安卓相机功能在一些手机上无法使用。

7
我刚意识到我的相机活动在一些设备上的surfaceholder不起作用。一些DROID品牌和有皮肤的手机。迄今为止,在所有标准安卓实现的谷歌手机上都可以正常工作。
我有一个短暂的时间来调试一个2.2版本的设备(不知道确切的手机型号,但它是有皮肤的),我看到调试器说(ICamera failed) (Camera Error 100)
但我没有机会弄清楚到底哪里出了问题,但我确实看到其他人也遇到了这个问题(关于在开始预览之前获取预览大小的问题?),但没有明显的响应或任何直觉的东西,这是我的相机代码,如何使其更普遍适用?
   //this is in OnCreate
   preview = (SurfaceView) findViewById(R.id.cameraplacer);
    previewHolder = preview.getHolder();

    previewHolder.addCallback(surfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

//这段代码在生命周期方法之外

 SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
    public void surfaceCreated(SurfaceHolder holder) {
        if (camera == null) {
            camera = Camera.open();
            try {
                Camera.Parameters camParams = camera.getParameters();
                camParams.setFlashMode(Parameters.FLASH_MODE_AUTO);

                setDisplayOrientation(camera, 90);
                camera.setPreviewDisplay(previewHolder);
                camera.setParameters(camParams);

            } catch (IOException e) {
                camera.release();
                camera = null;
            }
        }


    }//end surfaceCreated

    public void surfaceChanged(SurfaceHolder holder,
            int format, int width,
            int height) {
        Camera.Parameters parameters=camera.getParameters();
        Camera.Size size=getBestPreviewSize(width, height,
                parameters);

        if (size!=null) {
            parameters.setPreviewSize(size.width, size.height);
            camera.setParameters(parameters);
            camera.startPreview();
            inPreview=true;
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (camera != null) {
            camera.stopPreview();
            camera.setPreviewCallback(null);
            camera.release();
            camera = null;
        }
    }
};//end CallBack

private Camera.Size getBestPreviewSize(int width, int height,
        Camera.Parameters parameters) {
    Camera.Size result=null;

    for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
        if (size.width<=width && size.height<=height) {
            if (result==null) {
                result=size;
            }
            else {
                int resultArea=result.width*result.height;
                int newArea=size.width*size.height;

                if (newArea>resultArea) {
                    result=size;
                }
            }
        }
    }

    return(result);
}//end getBestPreviewSize

//这是在OnResume方法中

     try {
        //Method rotateMethod = android.hardware.Camera.class.getMethod("setDisplayOrientation", int.class);
        //rotateMethod.invoke(camera, 90);
        //Camera.Parameters camParams = camera.getParameters();
        //camParams.setPreviewSize(480, 320);// here w h are reversed
        //camera.setParameters(camParams);*/
        //setCameraDisplayOrientation(MainPhoto.this, 0, camera);
        if(camera!=null)
        {
            Camera.Parameters camParams = camera.getParameters();
            camParams.setFlashMode(Parameters.FLASH_MODE_AUTO);
            camera.setParameters(camParams);
            setDisplayOrientation(camera, 90);
            camera.setPreviewDisplay(previewHolder);
            camera.startPreview();
        }


    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }/* catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }*/ catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }/* catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }*/

没有日志和控制台消息,我认为很少有人能够帮助你解决这个问题。 - Tae-Sung Shin
3个回答

4
我会删除 onResume() 中的逻辑,因为它与 surfaceChanged() 中的逻辑重复,并且在调用 onResume() 时进行这项工作可能不安全,因为表面可能还没有准备好。
另外,您正在盲目地请求 FLASH_MODE_AUTO,而没有查看设备是否支持。
这将是开始的两个位置。

我该如何检查闪光模式是否为自动?我以为该调用会自行检查,因为它是硬编码变量。 - CQM
@CQM:调用getSupportedFlashModes()并查看是否在列表中。如果请求一个不支持的模式,我不知道会发生什么。 - CommonsWare
谢谢!我从中得到了一个条件语句。onResume已经消失,闪光模式被有条件地检查。这仍然没有在2.2设备上显示任何来自相机的内容。我现在只是将最低SDK版本提高到10,这样至少所有可以安装它的用户都能获得正确的体验。 - CQM
将其降回到2.2……仍然没有解决方案。并非所有2.2设备都有问题。 - CQM

4

首先,我有一个问题,你的onPause方法在哪里?我假设你正在释放与相机相关的所有资源,因为你不能一直持有它直到应用程序暂停。

其次,在变量中跟踪表面状态,无论其是否已销毁,基于此您必须决定在onResume中要执行什么操作。 类似于以下内容:

if (hasSurface) {
            // The activity was paused but not stopped, so the surface still
            // exists. Therefore
            // surfaceCreated() won't be called, so init the camera here.
            initCamera(surfaceHolder);
        } else {
            surfaceHolder.addCallback(this);
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        }

还有一件事,您收到的100错误实际上是相机指示本机相机应用程序已崩溃,如果您已将errorCallback设置为相机实例,则会收到有关此事件的通知,根据错误文档,您可以执行的操作是重新初始化相机实例。

希望它能在某种程度上有所帮助!


2
请看这个Android示例 链接,或在你的IDE中导入Android示例。希望这能帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接