Подтвердить что ты не робот

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

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

Я использую функцию камеры в приложении, и все работает отлично, за исключением автофокуса. Когда я вызываю 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)
4b9b3361

Ответ 1

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

Ответ 2

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

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

Ответ 3

Я предлагаю два решения, которые сработали для меня. 1) Остановите и возобновите работу камеры. Я делаю это, вызывая эти методы onPause и onResume, также в середине камеры Preview, где я сканирую 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!

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

Ответ 4

Я нашел хорошее решение
Поэтому позволяет просто исключить исключение и повторить попытку вызвать автофокусировку на некоторых устройствах (т.е. 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

Ответ 5

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

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

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

Ответ 6

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

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
   }

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