Функции камеры Android не работают на нескольких телефонах - PullRequest
7 голосов
/ 15 декабря 2011

Я только что понял, что моя камера в поверхностном держателе не работает на некоторых устройствах. Некоторые DROID фирменные и скины телефонов. На данный момент он работает на всех телефонах Google со стандартной реализацией Android.

У меня был короткий момент для отладки устройства на 2.2 (не знаю точно, какая это модель телефона, но он был скинов), и я увидел, что отладчик сказал (ICamera не удалось) (Ошибка камеры 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();
    }*/

Ответы [ 3 ]

4 голосов
/ 06 января 2012

Во-первых, вопрос о том, где находится ваш метод 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 для экземпляра камеры, который выбудет получено уведомление об этом событии, и вы можете начать с новой версии, т. е. заново инициализировать экземпляр камеры.

надеюсь, что это поможет!

4 голосов
/ 15 декабря 2011

Я бы удалил логику onResume(), так как она дублирует то, что есть у вас в surfaceChanged(), и может быть небезопасно выполнять эту работу к тому времени, когда вызывается onResume(), поскольку поверхность еще может не быть готовый.

Кроме того, вы вслепую запрашиваете FLASH_MODE_AUTO, не видя, поддерживается ли это устройством.

Это будет два места для начала.

2 голосов
/ 06 января 2012

Взгляните на пример Android здесь

или импортируйте примеры Android в вашу IDE.

Надеюсь, это поможет

...