我正在尝试将相机的图像用作动态壁纸的一部分。
在我宣布的引擎中,我有这段代码:
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)
答案 0 :(得分:5)
或多或少地跟随您的代码进行一些更改。
import java.io.IOException;
import android.hardware.Camera;
import android.view.SurfaceHolder;
public class GenericaCamera implements SurfaceHolder.Callback {
private Camera cameraDevice = null;
private SurfaceHolder cameraSurfaceHolder = null;
// MODIFIED FROM ORIGINAL SEE UPDATE AT BOTTOM
public GenericaCamera(SurfaceHolder holder)
{
cameraSurfaceHolder = holder;
cameraSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraSurfaceHolder.addCallback(this);
}
// Required camera surface holder interface Callback's
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
Camera.Parameters params = cameraDevice.getParameters();
Camera.Size size = getBestPreviewSize(params,w,h);
if (size != null)
params.setPreviewSize(size.width, size.height);
cameraDevice.startPreview();
}
// When the surface is ready then we can build the camera and attach
// the camera preview output to the UI holder
public void surfaceCreated(SurfaceHolder holder)
{
try {
cameraDevice = Camera.open();
cameraDevice.setPreviewDisplay(cameraSurfaceHolder);
} catch (IOException e) { }
}
// Stop the camera preview and dispose of the camera object
public void surfaceDestroyed(SurfaceHolder holder)
{
if (null == cameraDevice)
return;
cameraDevice.stopPreview();
cameraDevice.release();
cameraDevice = null;
}
public Camera.Size getBestPreviewSize(Camera.Parameters parameters, int w, int h)
{
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes())
{
if (size.width <= w && size.height <= h)
{
if (null == result)
result = size;
else
{
int resultDelta = w - result.width + h - result.height;
int newDelta = w - size.width + h - size.height;
if (newDelta < resultDelta)
result = size;
}
}
}
return result;
}
}
<强>更新强>
进入壁纸代码并想出来,仍然存在问题,但至少我得到它基本上工作,因为推送缓冲区设置的时间顺序很重要
问题
不在横向模式下,这会导致预览失真的图像,相机的已知问题还没有尝试锁定到风景中
在预览中如果你使用后退键,一切都被正确销毁(相机被释放)但是如果你设置壁纸,那么类不会调用onDestroy方法,这意味着你无法获得相机,因为预览实例该课程尚未发布
它也显示为锁定屏幕图像,不知道如何覆盖它,可能通过意图接收和响应并在你进入警卫/锁定屏幕时将其关闭
没有处理可见性事件,因此其他摄像机类不起作用,潜在的不必要的电池消耗等。
无论如何,所有这些都表示修改如下,以便至少开始工作
在引擎类中,在onCreate中从上面的类创建摄像头,之后由于推送缓冲区设置而出现问题,即使在以后的2.3+中不推荐使用它,在旧版本中仍然需要它。事实上还没有测试过2.2以上。
@Override
public void onCreate(SurfaceHolder holder) {
Log.d("CameraWallpaper","onCreate(SurfaceHolder holder)");
if (null == GC)
GC = new GenericaCamera(holder);
super.onCreate(holder);
}
然后在GenericCamera类中更改为以下构造函数模式
public GenericaCamera(SurfaceHolder holder)
{
cameraSurfaceHolder = holder;
cameraSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraSurfaceHolder.addCallback(this);
}
基本上就是这样,至少这应该让你开始,如果你找到1-4的任何解决方案让社区知道!
更新2
似乎Android 3+打破了这一点,不确定为什么因为这些平台的源仍然关闭。
所以2.3的最终答案是上面的工作,但是在3+上它不会。
答案 1 :(得分:0)
我看到以下问题给了我java.io.IOException: setPreviewDisplay failed
:
如果同时执行视频和照片,则有两个功能, camera.unlock()和 camera.reconnect()。在录制视频之前,您必须 camera.unlock(),然后在拍照前使用 camera.reconnect()。