Android - cam.setPreviewDisplay(holder) 遇到 IOError
我正在尝试使用相机的图像作为动态壁纸的一部分。
在我声明的引擎中,我有以下代码:
public class Class extends WallpaperService
{
Camera cam;
@Override
public void onCreate()
{
super.onCreate();
cam = Camera.open();
}
//...
@Override
public Engine onCreateEngine()
{
return new CubeEngine(cam);
}
class CubeEngine extends Engine
{
Camera cam;
CubeEngine(Camera cam)
{
this.cam=cam;
}
//...
@Override
public void onDestroy()
{
if (cam != null)
{
cam.stopPreview();
cam.setPreviewCallback(null);
cam.release();
cam = null;
}
super.onDestroy();
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height)
{
try
{
cam.setPreviewDisplay(holder);
cam.startPreview();
}
catch (IOException e)
{
e.printStackTrace();
}
super.onSurfaceChanged(holder, format, width, height);
}
@Override
public void onSurfaceCreated(SurfaceHolder holder)
{
super.onSurfaceCreated(holder);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder)
{
if (cam != null)
{
cam.stopPreview();
cam.setPreviewCallback(null);
cam.release();
cam = null;
}
super.onSurfaceDestroyed(holder);
}
//...
}
}
cam 是一个声明为 Camera.open() 的相机;
当我运行此命令时,我得到: java.io.IOException: setPreviewDisplay failed
我现在收到此异常:
07-26 00:12:18.399: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.419: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.439: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.459: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.479: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.509: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.529: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.549: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.569: ERROR/CameraService(1357): Overlay Creation Failed!
07-26 00:12:18.609: WARN/System.err(4104): java.lang.RuntimeException: startPreview failed
07-26 00:12:18.609: WARN/System.err(4104): at android.hardware.Camera.startPreview(Native Method)
07-26 00:12:18.609: WARN/System.err(4104): at com.petrifiednightmares.transparentphone.main.GenericaCamera.surfaceChanged(GenericaCamera.java:29)
07-26 00:12:18.609: WARN/System.err(4104): at android.service.wallpaper.WallpaperService$Engine.updateSurface(WallpaperService.java:687)
07-26 00:12:18.609: WARN/System.err(4104): at android.service.wallpaper.WallpaperService$Engine.attach(WallpaperService.java:749)
07-26 00:12:18.619: WARN/System.err(4104): at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:984)
07-26 00:12:18.619: WARN/System.err(4104): at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:61)
07-26 00:12:18.619: WARN/System.err(4104): at android.os.Handler.dispatchMessage(Handler.java:99)
07-26 00:12:18.619: WARN/System.err(4104): at android.os.Looper.loop(Looper.java:143)
07-26 00:12:18.619: WARN/System.err(4104): at android.app.ActivityThread.main(ActivityThread.java:4293)
07-26 00:12:18.629: WARN/System.err(4104): at java.lang.reflect.Method.invokeNative(Native Method)
07-26 00:12:18.629: WARN/System.err(4104): at java.lang.reflect.Method.invoke(Method.java:507)
07-26 00:12:18.629: WARN/System.err(4104): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-26 00:12:18.629: WARN/System.err(4104): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-26 00:12:18.629: WARN/System.err(4104): at dalvik.system.NativeStart.main(Native Method)
I am trying to use the camera's image as part of live wallpaper.
In the Engine that I declared, I have this code:
public class Class extends WallpaperService
{
Camera cam;
@Override
public void onCreate()
{
super.onCreate();
cam = Camera.open();
}
//...
@Override
public Engine onCreateEngine()
{
return new CubeEngine(cam);
}
class CubeEngine extends Engine
{
Camera cam;
CubeEngine(Camera cam)
{
this.cam=cam;
}
//...
@Override
public void onDestroy()
{
if (cam != null)
{
cam.stopPreview();
cam.setPreviewCallback(null);
cam.release();
cam = null;
}
super.onDestroy();
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height)
{
try
{
cam.setPreviewDisplay(holder);
cam.startPreview();
}
catch (IOException e)
{
e.printStackTrace();
}
super.onSurfaceChanged(holder, format, width, height);
}
@Override
public void onSurfaceCreated(SurfaceHolder holder)
{
super.onSurfaceCreated(holder);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder)
{
if (cam != null)
{
cam.stopPreview();
cam.setPreviewCallback(null);
cam.release();
cam = null;
}
super.onSurfaceDestroyed(holder);
}
//...
}
}
cam is a Camera that was declared as Camera.open();
When I run this I get: java.io.IOException: setPreviewDisplay failed
I am now getting this exception:
07-26 00:12:18.399: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.419: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.439: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.459: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.479: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.509: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.529: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.549: WARN/CameraService(1357): Overlay create failed - retrying
07-26 00:12:18.569: ERROR/CameraService(1357): Overlay Creation Failed!
07-26 00:12:18.609: WARN/System.err(4104): java.lang.RuntimeException: startPreview failed
07-26 00:12:18.609: WARN/System.err(4104): at android.hardware.Camera.startPreview(Native Method)
07-26 00:12:18.609: WARN/System.err(4104): at com.petrifiednightmares.transparentphone.main.GenericaCamera.surfaceChanged(GenericaCamera.java:29)
07-26 00:12:18.609: WARN/System.err(4104): at android.service.wallpaper.WallpaperService$Engine.updateSurface(WallpaperService.java:687)
07-26 00:12:18.609: WARN/System.err(4104): at android.service.wallpaper.WallpaperService$Engine.attach(WallpaperService.java:749)
07-26 00:12:18.619: WARN/System.err(4104): at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:984)
07-26 00:12:18.619: WARN/System.err(4104): at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:61)
07-26 00:12:18.619: WARN/System.err(4104): at android.os.Handler.dispatchMessage(Handler.java:99)
07-26 00:12:18.619: WARN/System.err(4104): at android.os.Looper.loop(Looper.java:143)
07-26 00:12:18.619: WARN/System.err(4104): at android.app.ActivityThread.main(ActivityThread.java:4293)
07-26 00:12:18.629: WARN/System.err(4104): at java.lang.reflect.Method.invokeNative(Native Method)
07-26 00:12:18.629: WARN/System.err(4104): at java.lang.reflect.Method.invoke(Method.java:507)
07-26 00:12:18.629: WARN/System.err(4104): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-26 00:12:18.629: WARN/System.err(4104): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-26 00:12:18.629: WARN/System.err(4104): at dalvik.system.NativeStart.main(Native Method)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它或多或少遵循您的代码,但做了一些更改。
更新
,时间顺序很重要
进入壁纸代码并解决了它,仍然存在问题,但至少我让它基本上工作,由于推送缓冲区设置问题
不在横向模式下,这会导致预览的图像失真,相机的已知问题尚未尝试锁定横向模式
在预览中,如果您使用后退键,所有内容都会被正确销毁(释放相机),但如果您设置壁纸,该类不会调用 onDestroy 方法,因此这意味着您无法获取相机,因为该类的预览实例尚未释放它
它也显示为锁定屏幕图像,不知道如何覆盖它,可能通过意图接收和响应,并在您处于防护/锁定屏幕时将其关闭
尚未处理可见性事件,因此其他相机类将无法工作,可能会产生不必要的电池排水等。
无论如何,修改如下,以使其至少开始工作
在引擎类中,在 onCreate 中从上述类创建相机,任何以后都会出现问题由于推送缓冲区设置而发生,尽管这在 2.3+ 版本中已弃用,但在旧版本中仍然需要。事实上2.2以上还没有测试过。
然后在 GenericCamera 类中更改为以下构造函数模式
基本上就是这样,至少这应该让您开始,如果您找到 1-4 的任何解决方案,请让社区知道!
更新 2
似乎 Android 3+ 打破了这一点,不知道为什么,因为这些平台的源代码仍然关闭。
所以对于 2.3 以上的最终答案是上面的方法有效,但在 3+ 上则不行。
It more or less follows your code with a few changes.
}
Update
Went into the wallpaper code and figured it out, still problems but at least I got it to basically work, order of when is important because of the push buffers setup
Problems
Not in landscape mode, this causes a distorted image to be previewed, known issue of the camera just havent tried to lock into landscape yet
In preview if you use back key everything is destroyed properly (camera released) but if you set the wallpaper the class does not call the onDestroy method so this means that you can't get the camera because the preview instance of the class has not released it
It also shows up as the lock screen image, not sure how to override that, probably receive and respond via intents and turn it off when you are in the guard/lock screen
Have not handled visibility event, so other camera classes won't work, potential unnecessary battery drain etc.
Anyway with all of that said the modifications are as follows to get this to at least start working
In the engine class create the camera from the above class in the onCreate, any later and problems occur because of the push buffers setup, and even though this is deprecated in later 2.3+ it is still required in older versions. Matter of fact have not tested this above 2.2 yet.
Then in the GenericCamera class change to the following constructor pattern
That's basically it, at least this should get you started, and if you find any solutions to 1-4 let the community know!
Update 2
It seems that Android 3+ breaks this, not sure why since the source for those platforms is still closed.
So final answer for upto 2.3 is that above works, but on 3+ it will not.
我看到以下问题给了我
java.io.IOException: setPreviewDisplay failed
:如果您同时执行视频和照片操作,则有两个函数,camera.unlock() 和camera.reconnect()。您必须在录制视频之前camera.unlock(),在拍照之前camera.reconnect()。
I have seen the following gotcha giving me
java.io.IOException: setPreviewDisplay failed
:If you do both video and photo, there are two functions, camera.unlock() and camera.reconnect(). You must camera.unlock() before recording a video and camera.reconnect() before taking a photo.