2012-01-11 10 views
20

Próbowałem wszystkiego, ale nadal nie mogę rozwiązać tego problemu.AutoFocus throwing exception

Wprowadzam funkcję kamery w aplikacji i wszystko działa poprawnie, z wyjątkiem autofokusa. Kiedy wywołuję funkcję autoFocus(), generuje wyjątek i nie mogę zrozumieć, dlaczego. Używam kodu na Desire HD.

Kod: ślad

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

Stos:

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) 

Odpowiedz

7

Może chcesz się upewnić, że telefon obsługuje autofokusa. Jest to dość łatwe do sprawdzenia to:

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

Dzięki, skończyło się za pomocą 3rd party biblioteki open source, co potrzebne, który miał nie ma problemu z autofokusem. – MikeIsrael

+0

@MikeIsrael Mam do czynienia z tym samym problemem dla wyjątku AutoFocus Failed. czy możesz mi powiedzieć, jakiego rozwiązania użyłeś. Dostaję ten wyjątek czasami, gdy uruchamiam kamerę w mojej aplikacji nie cały czas. Dziękuję – Vikram

+0

@Vikram Potrzebowałem czegoś do skanowania kodów kreskowych, więc w końcu w końcu użyłem zxing. Nigdy nie udało mi się znaleźć przyczyny wyjątku, pamiętam, próbując różnych uprawnień i wszystkiego. Zxing jest opensource, więc możesz po prostu chcieć sprawdzić niektóre z ich kodów i sprawdzić, czy może ci pomóc, pamiętaj jednak o ich licencjonowaniu. – MikeIsrael

13

Zastosowanie SurfaceHolder.Callback -> surfaceCreated wiedzieć, kiedy można rozpocząć autofokusa. Jeśli powierzchnia nie została utworzona (trwała jakiś czas), autofokus zakończy się niepowodzeniem.

+0

Zobacz moją odpowiedź poniżej, ma kod, jak to zrobić. – Josh

1

Upewnij się, że wywołujesz funkcję automatycznego ustawiania ostrości po wywołaniu podglądu początkowego. Według android documentation

Metoda ta jest ważny tylko wtedy, gdy aktywny jest podgląd (między startPreview() i przed stopPreview()).

Jeśli nadal stoi jakiś błąd spróbuj Rasmus's i zwebie's rozwiązanie w tej samej kolejności.

3

Proponuję dwa rozwiązania, które sprawdziły się u mnie. 1) Zatrzymaj i wznów aparat poprawnie. Robię to poprzez wywołanie tych metod na OnPause i onResume, także w środku kamery podglądu, gdzie skanowanie kodów QR w mojej aplikacji:

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) Bardzo trudne, ale pracował jak magia! Upewnij się, że wywołujesz autofokus PO utworzeniu powierzchni podglądu. Aby to zrobić, należy uruchomić Autofocus z opóźnieniem 200ms, aby kupić czas na powierzchnię, która ma zostać utworzona. Ustaw to wciskając ctrl + zapadkę nad „CameraPreview” deklaracją obiektów, takich jak:

CameraPreview my_camera; 

Spójrz na „pustkę publicznej surfaceChanged” metody i zrobić to zmienia:

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

Istnieje wiele innych poprawki, ale te dwie mogą uratować twój dzień.

0

Istnieje wiele rozwiązań, ale jest to łatwe, martwe tani opcja, że ​​pracował dla mnie:

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 
    } 

voila! Pułapka wyłączona.

+0

To niewiele pomoże, ponieważ można wywołać metodę autoFocus, niezależnie od tego, czy jest obsługiwana, czy nie. Dokumenty mówią: jeśli aparat nie obsługuje funkcji autofokusa, nie działa, a wywołanie zwrotne onAutoFocus (boolean, Camera) zostanie natychmiast wywołane. – slott

3

znalazłem piękny rozwiązanie
Więc pozwala wyjątek catch to po prostu, a następnie spróbuj ponownie zadzwonić autofokusa na niektórych urządzeniach (tj Experia Sony i kilku innych)
Co jest na około czasu opóźnienia pomiędzy próbami (1 sekunda)
Nie lubię żadnych "magicznych" cyfr w kodzie, więc w niektórych przypadkach może to być zbyt duże lub zbyt małe.Jego wystarczająco dla mnie)

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

i tu jest start i stop metody

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

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