2012-01-11 16 views
20

Ho provato tutto ma non riesco ancora a risolvere questo problema.autoFocus throwing exception

Sto implementando una funzione di fotocamera in un'app e tutto funziona bene tranne l'autofocus. Quando chiamo autoFocus(), genera un'eccezione e non riesco a capire perché. Sto eseguendo il codice su un desiderio HD.

Codice: trace

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

Stack:

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) 

risposta

7

Si potrebbe desiderare di fare in modo che il telefono supporta messa a fuoco automatica. E 'abbastanza facile da controllare questo:

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

Grazie, ho finito per usare una libreria open source 3a parte per quello che ho bisogno che ha avuto nessun problema con l'autofocus. – MikeIsrael

+0

@MikeIsrael Sto affrontando lo stesso problema per l'eccezione AutoFocus non riuscita. puoi dirmi quale soluzione hai usato. Ottengo questa eccezione a volte quando avvio la fotocamera nella mia app non sempre. Grazie – Vikram

+0

@Vikram Avevo bisogno di qualcosa per la scansione dei codici a barre, quindi alla fine ho usato zxing. Non sono mai stato in grado di trovare una ragione per l'eccezione generata, ricordo di aver provato permessi diversi e tutto il resto. zxing è opensource quindi potresti semplicemente voler controllare alcuni dei loro codici e vedere se può aiutarti, assicurati di prestare attenzione alle loro licenze. – MikeIsrael

13

Usa SurfaceHolder.Callback -> surfaceCreated a sapere quando è possibile avviare l'autofocus. Se il supporto della superficie non viene creato (dura un po 'di tempo) la messa a fuoco automatica fallirà.

+0

Vedere la mia risposta qui sotto, ha il codice su come farlo. – Josh

1

Assicurati di aver chiamato la funzione autoFocus dopo aver chiamato l'anteprima di avvio. Secondo la android documentation

Questo metodo è valido solo quando è attivo anteprima (tra startPreview() e prima stopPreview()).

Se siete ancora di fronte a qualsiasi errore di cercare Rasmus's e zwebie's soluzione nello stesso ordine.

3

Propongo due soluzioni che hanno funzionato per me. 1) Arresta e riattiva la fotocamera correttamente. Io lo faccio chiamando questi metodi su onPause e onResume, anche nel bel mezzo della fotocamera Anteprima, dove la scansione codici QR nella mia app:

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) Molto difficile, ma ha funzionato come per magia! Assicurati di chiamare l'autofocus DOPO che la superficie di anteprima è stata creata. Per fare ciò, eseguire la messa a fuoco automatica con un ritardo di 200 ms, per guadagnare tempo per la superficie da creare. Impostare questo premendo Ctrl + clic su una dichiarazione oggetto "CameraPreview", come ad esempio:

CameraPreview my_camera; 

cercare il "public void surfaceChanged" metodo e rendere questo cambia:

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

Ci sono molti altri risolve, ma questi due potrebbero salvare la tua giornata.

0

ci sono molte soluzioni, ma questo è un facile, un'opzione a basso costo morta che ha funzionato per me:

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à! Trap disattivata.

+0

Questo non aiuta molto come il metodo autoFocus può essere chiamato indipendentemente se supportato o meno. I documenti dicono: Se la fotocamera non supporta la messa a fuoco automatica, si tratta di una chiamata non operatoria e la chiamata suAutoFocus (boolean, Camera) verrà richiamata immediatamente. – slott

3

ho trovato una bella soluzione
Quindi, consente di eccezione cattura questo semplicemente, e riprovare a chiamare messa a fuoco automatica su alcuni dispositivi (ad esempio Experia Sony e alcuni altri)
ciò che è per il momento di ritardo tra i tentativi (1 secondo)
Non amo alcun numero "magico" nel codice, quindi in alcuni casi questo potrebbe essere troppo grande o troppo piccolo.La sua abbastanza per me)

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

e qui è avviare e arrestare i metodi

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

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