Autofoco que lanza la excepción

He intentado todo, pero todavía no puedo resolver este problema.

Estoy implementando una función de cámara en una aplicación y todo funciona bien, excepto el autofoco. Cuando llamo autoFocus (), lanza una excepción, y no puedo entender por qué. Estoy ejecutando el código en un Desire HD.

Código:

@Override protected void onStart() { super.onStart(); //grab seurface view and callback cameraView = (CameraSurfaceView) findViewById(R.id.cameraView); try{ camera = Camera.open(); cameraView.setCamera(camera); //release previous autofocus and assign new one camera.cancelAutoFocus(); camera.autoFocus(new Camera.AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { // TODO Auto-generated method stub }}); } catch (Exception e) { //had an issue accessing the camera prompt user //TODO create user prompt e.printStackTrace(); } } 

Rastro de la pila:

 01-11 16:09:38.456: W/System.err(26546): java.lang.RuntimeException: autoFocus failed 01-11 16:09:38.456: W/System.err(26546): at android.hardware.Camera.native_autoFocus(Native Method) 01-11 16:09:38.456: W/System.err(26546): at android.hardware.Camera.autoFocus(Camera.java:680) 01-11 16:09:38.456: W/System.err(26546): at com.myapp.MyActivity.onStart(BarcodeScannerActivity.java:57) 01-11 16:09:38.466: W/System.err(26546): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1201) 01-11 16:09:38.466: W/System.err(26546): at android.app.Activity.performStart(Activity.java:3955) 01-11 16:09:38.466: W/System.err(26546): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1845) 01-11 16:09:38.466: W/System.err(26546): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1893) 01-11 16:09:38.466: W/System.err(26546): at android.app.ActivityThread.access$1500(ActivityThread.java:135) 01-11 16:09:38.466: W/System.err(26546): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1054) 01-11 16:09:38.466: W/System.err(26546): at android.os.Handler.dispatchMessage(Handler.java:99) 01-11 16:09:38.466: W/System.err(26546): at android.os.Looper.loop(Looper.java:150) 01-11 16:09:38.476: W/System.err(26546): at android.app.ActivityThread.main(ActivityThread.java:4385) 01-11 16:09:38.476: W/System.err(26546): at java.lang.reflect.Method.invokeNative(Native Method) 01-11 16:09:38.476: W/System.err(26546): at java.lang.reflect.Method.invoke(Method.java:507) 01-11 16:09:38.476: W/System.err(26546): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849) 01-11 16:09:38.476: W/System.err(26546): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607) 01-11 16:09:38.476: W/System.err(26546): at dalvik.system.NativeStart.main(Native Method) 

Use SurfaceHolder.Callback -> surfaceCreated para saber cuándo puede iniciar el AutoFocus. Si el soporte de superficie no se crea (duró algún tiempo) el autofoco fallará.

Es posible que desee asegurarse de que el teléfono admita el enfoque automático. Es muy fácil comprobar esto:

 Camera.Parameters p = mCamera.getParameters(); List<String> focusModes = p.getSupportedFocusModes(); if(focusModes != null && focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { //Phone supports autofocus! } else { //Phone does not support autofocus! } 

He encontrado una buena solución
Así que vamos a capturar la excepción de esto simplemente, y vuelva a intentar llamar autofocus en algunos dispositivos (es decir, sony experia y algunos otros)
¿Cuál es el tiempo de retraso entre reintentos (1 segundo)
No amo ningún número "mágico" en el código, por lo que este puede ser demasiado grande o demasiado pequeño en algunos casos. Es suficiente para mi)

 public void requestAutoFocus(Handler handler, int message) { if(camera != null && previewing) { autoFocusCallback.setHandler(handler, message); scheduleAutoFocus(); } } public void safeAutoFocus() { try { camera.autoFocus(autoFocusCallback); } catch (RuntimeException e) { // Horrible hack to deal with autofocus errors on Sony devices // See https://github.com/dm77/barcodescanner/issues/7 for example scheduleAutoFocus(); // wait 1 sec and then do check again } } private void scheduleAutoFocus() { mAutoFocusHandler.postDelayed(doAutoFocus, 1000); } private Runnable doAutoFocus = new Runnable() { public void run() { if(camera != null && previewing) { safeAutoFocus(); } } }; 

Y aquí están los métodos de inicio y parada

 public void startPreview() { if (camera != null && !previewing) { camera.startPreview(); camera.autoFocus(autoFocusCallback); previewing = true; } } public void stopPreview() { if(camera != null && previewing) { try { camera.cancelAutoFocus(); if(!useOneShotPreviewCallback) { camera.setPreviewCallback(null); } camera.stopPreview(); previewCallback.setHandler(null, 0); autoFocusCallback.setHandler(null, 0); previewing = false; } catch(Exception e) { Log.e(TAG, e.toString(), e); } } } 

Referencia: https://github.com/dm77/barcodescanner/blob/master/core/src/main/java/me/dm7/barcodescanner/core/CameraPreview.java

Propongo dos soluciones que trabajaron para mí. 1) Detenga y vuelva a encender la cámara correctamente. Lo hago llamando a estos métodos on onPause y onResume, también en medio de la vista previa de cámara, donde escanear códigos QR en mi aplicación:

 public void stopCamera(){ mCamera.cancelAutoFocus(); mCamera.setPreviewCallback(null); mCamera.stopPreview(); mPreviewing = false; } public void rethrottleCamera(){ updateViews(); //Updates my Layouts mPreviewing = true; mCamera.startPreview(); mCamera.setPreviewCallback(previewCb); mCamera.autoFocus(autoFocusCB); } 

2) muy difícil pero funcionaba como magia! Asegúrese de llamar al autofoco después de que se haya creado la superficie de vista previa. Para hacer esto ejecute Autofocus con un retraso de 200ms, para ganar tiempo para que la superficie sea creada. Configure esto presionando ctrl + clic sobre una declaración de objeto "CameraPreview", como por ejemplo:

 CameraPreview my_camera; 

Busque el método "public void surfaceChanged" y realice los cambios siguientes:

 //Add a delay to AUTOFOCUS after mCamera.startpreview();!!: mCamera.startPreview(); final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { mCamera.autoFocus(autoFocusCallback); } }, 200); //<-200 millisecond delay //If you call autofocus right after startPreview, chances are, //that the previewSurface will have not been created yet, //and autofocus will fail: mCamera.startPreview(); //Bad idea! mCamera.autoFocus(autoFocusCallback); //Bad idea! 

Hay muchos otros arreglos, pero estos dos pueden salvar tu día.

Asegúrese de que está llamando a la función AutoFocus después de llamar a la vista previa de inicio. De acuerdo con la documentación de Android

Este método sólo es válido cuando la vista previa está activa (entre startPreview () y before stopPreview ()).

Si todavía enfrentas algún error, prueba la solución de Rasmus y zwebie en el mismo orden.

Hay muchas soluciones, pero esta es una opción fácil, muerta barata que trabajó para mí:

 try{ mCamera.autoFocus(autoFocusCB); //Or whatever part of code that crashes } catch(Exception e){ Log.v("joshtag","THIS PHONE DOES NOT SUPPORT AUTOFOCUS!!"); //a warning, popup, whatever } 

Voilà! Trampa desactivada.

  • Mantener la devolución de llamada de vista previa mientras graba vídeo?
  • ¿Cuál es la diferencia entre `opencv.android.JavaCameraView` y` opencv.android.NativeCameraView`
  • La importación de android.hardware.camera2 no se puede resolver
  • Android: NPE sucede al obtener la imagen de la cámara
  • Negación de permisos: no se permite enviar emisiones en android
  • Obtener orientación del teléfono cuando está bloqueado en una orientación
  • OpenCV Android: Obtener fotogramas de la cámara en segundo plano sin mostrar en la pantalla
  • Cámara incorporada, utilizando el MediaStore.EXTRA_OUTPUT extra almacena imágenes dos veces (en mi carpeta, y en el valor predeterminado)
  • Android: obtener tamaños de vídeo compatibles
  • ¿Debo usar Camera2 o Camera APIs para Android?
  • ¿Cómo usar la cámara de Android o la API de la cámara2 para admitir versiones antiguas y nuevas de la API sin notas de reprobación?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.