Android的 - cam.set previewDisplay(架)运行到IO错误 [英] Android - cam.setPreviewDisplay(holder) running into IOError

查看:80
本文介绍了Android的 - cam.set previewDisplay(架)运行到IO错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用相机的图像,作为动态壁纸一部分。

在我宣布引擎,我有这个code:

 公共类类扩展WallpaperService
{
    摄像头凸轮;

    @覆盖
    公共无效的onCreate()
    {
        super.onCreate();
        凸轮= Camera.open();
    }

    // ...

    @覆盖
    公共引擎onCreateEngine()
    {
        返回新CubeEngine(CAM);
    }

    类CubeEngine扩展引擎
    {
        摄像头凸轮;

        CubeEngine(照相机CAM)
        {
            this.cam =凸轮;
        }

        // ...

        @覆盖
        公共无效的onDestroy()
        {
            如果(凸轮!= NULL)
            {
                cam.stop preVIEW();
                cam.set previewCallback(空);
                cam.release();
                凸轮= NULL;
            }
            super.onDestroy();
        }

        @覆盖
        公共无效onSurfaceChanged(SurfaceHolder持有人,INT格式,
                INT宽度,高度INT)
        {
            尝试
            {
                cam.set previewDisplay(保持器);
                cam.start preVIEW();
            }
            赶上(IOException异常E)
            {
                e.printStackTrace();
            }
            super.onSurfaceChanged(保持器,格式,宽度,高度);
        }

        @覆盖
        公共无效onSurfaceCreated(SurfaceHolder持有人)
        {
            super.onSurfaceCreated(保持器);
        }

        @覆盖
        公共无效onSurfaceDestroyed(SurfaceHolder持有人)
        {
            如果(凸轮!= NULL)
            {
                cam.stop preVIEW();
                cam.set previewCallback(空);
                cam.release();
                凸轮= NULL;
            }
            super.onSurfaceDestroyed(保持器);
        }

        // ...
    }
}
 

凸轮是被宣布为Camera.open()一个摄像头;

当我运行此我得到: java.io.IOException异常:一套previewDisplay失败

我现在收到此异常:

  07-26 00:12:18.399:WARN / CameraService(1357):覆盖创建失败 - 重试
07-26 00:12:18.419:WARN / CameraService(1357):覆盖创建失败 - 重试
07-26 00:12:18.439:WARN / CameraService(1357):覆盖创建失败 - 重试
07-26 00:12:18.459:WARN / CameraService(1357):覆盖创建失败 - 重试
07-26 00:12:18.479:WARN / CameraService(1357):覆盖创建失败 - 重试
07-26 00:12:18.509:WARN / CameraService(1357):覆盖创建失败 - 重试
07-26 00:12:18.529:WARN / CameraService(1357):覆盖创建失败 - 重试
07-26 00:12:18.549:WARN / CameraService(1357):覆盖创建失败 - 重试
07-26 00:12:18.569:ERROR / CameraService(1357):覆盖创建失败!


07-26 00:12:18.609:WARN / System.err的(4104):java.lang.RuntimeException的:启动preVIEW失败
07-26 00:12:18.609:WARN / System.err的(4104):在android.hardware.Camera.start preVIEW(本机方法)
07-26 00:12:18.609:WARN / System.err的(4104):在com.petrifiednightmares.transparentphone.main.GenericaCamera.surfaceChanged(GenericaCamera.java:29)
07-26 00:12:18.609:WARN / System.err的(4104):在android.service.wallpaper.WallpaperService $ Engine.updateSurface(WallpaperService.java:687)
07-26 00:12:18.609:WARN / System.err的(4104):在android.service.wallpaper.WallpaperService $ Engine.attach(WallpaperService.java:749)
07-26 00:12:18.619:WARN / System.err的(4104):在android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:984)
07-26 00:12:18.619:WARN / System.err的(4104):在com.android.internal.os.HandlerCaller $ MyHandler.handleMessage(HandlerCaller.java:61)
07-26 00:12:18.619:WARN / System.err的(4104):在android.os.Handler.dispatchMessage(Handler.java:99)
07-26 00:12:18.619:WARN / System.err的(4104):在android.os.Looper.loop(Looper.java:143)
07-26 00:12:18.619:WARN / System.err的(4104):在android.app.ActivityThread.main(ActivityThread.java:4293)
07-26 00:12:18.629:WARN / System.err的(4104):在java.lang.reflect.Method.invokeNative(本机方法)
07-26 00:12:18.629:WARN / System.err的(4104):在java.lang.reflect.Method.invoke(Method.java:507)
07-26 00:12:18.629:WARN / System.err的(4104):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:839)
07-26 00:12:18.629:WARN / System.err的(4104):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-26 00:12:18.629:WARN / System.err的(4104):在dalvik.system.NativeStart.main(本机方法)
 

解决方案

这或多或少会跟随code有一些变化。

 进口java.io.IOException异常;
进口android.hardware.Camera;
进口android.view.SurfaceHolder;

公共类GenericaCamera实现SurfaceHolder.Callback {

    私人相机cameraDevice = NULL;
    私人SurfaceHolder cameraSurfaceHolder = NULL;

    //修改为从原请参见更新底部
    公共GenericaCamera(SurfaceHolder持有人)
    {
        cameraSurfaceHolder =持有人;
        cameraSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        cameraSurfaceHolder.addCallback(本);
    }

     //所需摄像机表面支架接口回调的
     公共无效surfaceChanged(SurfaceHolder持有人,INT格式,INT W,INT高)
     {
         Camera.Parameters PARAMS = cameraDevice.getParameters();
         Camera.Size大小= getBest previewSize(PARAMS,W,H);

         如果(大小!= NULL)
            params.set previewSize(size.width,size.height);
         cameraDevice.start preVIEW();
     }

     //当表面已经准备好,然后我们就可以建立摄像头,并附
     //相机preVIEW输出到UI保持器
     公共无效surfaceCreated(SurfaceHolder持有人)
     {
        尝试 {

            cameraDevice = Camera.open();
            cameraDevice.set previewDisplay(cameraSurfaceHolder);

        }赶上(IOException异常E){}

    }

    //停止摄像机preVIEW和处置相机对象
    公共无效surfaceDestroyed(SurfaceHolder持有人)
    {
        如果(空== cameraDevice)
            返回;
        cameraDevice.stop preVIEW();
        cameraDevice.release();
        cameraDevice = NULL;
    }

    公共Camera.Size getBest previewSize(Camera.Parameters参数,INT W,INT高)
    {
        Camera.Size结果= NULL;

        对于(Camera.Size大小:parameters.getSupported previewSizes())
        {
            如果(size.width&其中; = W&安培;&安培; size.height&其中; = H)
            {
                如果(空==结果)
                结果=大小;
            其他
            {
                INT resultDelta = W  -​​  result.width + H  -  result.height;
                INT newDelta = W  -​​  size.width + H  -  size.height;

                    如果(newDelta< resultDelta)
                结果=大小;
            }
            }
        }
        返回结果;
    }
 

}

更新

刚一进墙纸code和理解了它,还存在问题,但至少我得到了它的基本工作原理,顺序,因为推的时候是非常重要的缓冲设置

问题

  1. 不是在横向模式下,这会导致图像失真是previewed的摄像头,已知的问题,只是还没有想锁定的风景又

  2. 在preVIEW如果使用返回键一切都正确销毁(相机发布),但如果你设置的墙纸类不调用的onDestroy方法,所以这意味着你不能得到的相机,因为类的preVIEW情况还没有公布它

  3. 这也显示为锁屏图像,不知道如何重写,可能接收和经意图作出反应,并关闭它,当你在后卫/锁屏

  4. 有没有处理的可见性事件,所以其他的相机类是行不通的,潜在的不必要的电池消耗等。

反正所有这一切说,修改内容如下得到这至少是重新开始工作。

在引擎类从在OnCreate上面的类创建摄像头,任何后来又因为推缓冲区设置中出现的问题,尽管这是pcated稍后德$ P $ 2.3+它仍然需要中老年版本。说实在的,没有测试上面2.2呢。

  @覆盖
    公共无效的onCreate(SurfaceHolder持有者){
        Log.d(CameraWallpaper,的onCreate(SurfaceHolder保持器));
        如果(空== GC)
        GC =新GenericaCamera(保持器);
    super.onCreate(保持器);
}
 

然后在GenericCamera类变更下面的构造格局

 公共GenericaCamera(SurfaceHolder持有人)
{
     cameraSurfaceHolder =持有人;
     cameraSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
     cameraSurfaceHolder.addCallback(本);
}
 

这基本上吧,至少这应该让你开始,如果你发现任何解决方案,以1-4让社会知道!

更新2

看来,Android的3+突破这一点,不知道为什么,因为源为这些平台仍然关闭。

有高达2.3所以最终的答案是,上述工程,但3+不会。

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)

解决方案

It more or less follows your code with a few changes.

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; 
    }

}

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

  1. 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

  2. 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

  3. 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

  4. 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.

@Override
    public void onCreate(SurfaceHolder holder) {
        Log.d("CameraWallpaper","onCreate(SurfaceHolder holder)");
        if (null == GC)
        GC = new GenericaCamera(holder);
    super.onCreate(holder);
}

Then in the GenericCamera class change to the following constructor pattern

public GenericaCamera(SurfaceHolder holder)
{
     cameraSurfaceHolder = holder;
     cameraSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
     cameraSurfaceHolder.addCallback(this);
}

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.

这篇关于Android的 - cam.set previewDisplay(架)运行到IO错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆