Исключение автофокусировки

Я пробовал все, но я все еще не могу решить эту проблему.

Я использую функцию камеры в приложении, и все работает отлично, за исключением автофокуса. Когда я вызываю autoFocus (), он выдает исключение, и я не могу понять, почему. Я запускаю код на Desire HD.

Код:

@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(); } } 

Трассировки стека:

 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) 

Используйте SurfaceHolder.Callback -> surfaceCreated, чтобы знать, когда вы можете запустить AutoFocus. Если поверхностный держатель не создан (длился некоторое время), автофокусировка завершится неудачно.

Возможно, вы захотите убедиться, что телефон поддерживает автофокусировку. Это довольно легко проверить:

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

Я нашел хорошее решение
Так что давайте просто поймаем исключение и попробуем снова вызвать автофокус на некоторых устройствах (например, sony experia и некоторые другие)
Что касается времени задержки между попытками (1 секунда)
Я не люблю никаких «магических» чисел в коде, поэтому в некоторых случаях это может быть слишком большим или слишком маленьким. Его достаточно для меня)

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

И здесь используются методы начала и остановки

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

Ссылка: https://github.com/dm77/barcodescanner/blob/master/core/src/main/java/me/dm7/barcodescanner/core/CameraPreview.java

Я предлагаю два решения, которые сработали для меня. 1) Остановите и возобновите работу камеры. Я делаю это, вызывая эти методы onPause и onResume, также в середине предварительного просмотра камеры, где я просматриваю QR-коды в своем приложении:

 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) Очень сложно, но работал как магия! Убедитесь, что вы вызываете автофокус ПОСЛЕ получения поверхности предварительного просмотра. Для этого запустите Autofocus с задержкой в ​​200 мс, чтобы выиграть время для создания поверхности. Установите это, нажав ctrl + clic над объявлением объекта CameraPreview, например:

 CameraPreview my_camera; 

Найдите метод «public void surfaceChanged» и внесите следующие изменения:

 //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! 

Есть много других исправлений, но эти двое могут сэкономить ваш день.

Убедитесь, что вы вызываете функцию автофокуса после вызова предварительного просмотра. Согласно документации по Android

Этот метод действителен только при активном предварительном просмотре (между startPreview () и перед stopPreview ()).

Если вы все еще сталкиваетесь с какой-либо ошибкой, попробуйте решение Rasmus и zwebie в том же порядке.

Есть много решений, но это простой, умеренный дешевый вариант, который работал на меня:

 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 } 

Вуаля! Ловушка деактивирована.