2012-01-11 248 views
20

我已經嘗試了一切,但我仍然無法解決此問題。autoFocus拋出異常

我在應用程序中實現了一個攝像頭功能,除了自動對焦外,一切正常。當我調用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) 

回答

7

您可能要確保手機支持自動對焦。這是很容易檢查:

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

謝謝,我結束了使用什麼,我需要的是有一個第三方的開源庫自動對焦沒有問題。 – MikeIsrael 2012-02-06 11:20:49

+0

@MikeIsrael我面臨同樣的問題,對於autoFocus失敗的異常。你能告訴我你使用了什麼解決方案嗎?當我在我的應用程序中啓動相機並不是所有的時候,我都會遇到此異常。謝謝 – Vikram 2012-04-09 10:27:28

+0

@Vikram我需要條形碼掃描的東西,所以最終我最終使用了zxing。我從來沒有找到拋出異常的原因,我記得嘗試不同的權限和一切。 zxing是開源的,所以你可能只想看看他們的一些代碼,看看它是否可以幫助你,確保注意他們的授權。 – MikeIsrael 2012-04-09 10:35:56

13

使用SurfaceHolder.Callback - > surfaceCreated知道什麼時候可以啓動自動對焦。如果沒有創建水邊(持續一段時間),自動對焦將失敗。

+0

請參閱下面的答案,它有關於如何執行此操作的代碼。 – Josh 2017-11-06 09:40:14

1

確保您在調用開始預覽後調用autoFocus函數。 按照android documentation

此方法纔有效時預覽是活動的( startPreview(之間)和前stopPreview())。

如果您仍然面臨任何錯誤,請按照相同的順序嘗試Rasmus'szwebie's解決方案。

3

我提出了兩個解決方案,爲我工作。 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)非常棘手,但像變魔術一樣!確保在預覽表面創建完成後調用自動對焦。要做到這一點,運行自動對焦延遲200毫秒,以購買創建表面的時間。按CTRL + CLIC在「CameraPreview」對象的聲明,比如設置這樣的:

CameraPreview my_camera; 

尋找「公共無效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! 

還有許多其他的修復,但這兩個可能會節省你的一天。

0

解決方法有很多,但是這是爲我工作的方便,便宜死選項:

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 
    } 

瞧!陷阱停用。

+0

這不會有什麼幫助,因爲無論支持與否,autoFocus方法都可以被調用。文檔說:如果相機不支持自動對焦,它將是一個無操作並立即調用onAutoFocus(布爾,相機)回調。 – slott 2015-09-03 11:07:03

3

我已經找到了一個很好的解決方案
所以,讓我們捕獲異常這一簡單,並嘗試再次呼籲某些設備(即索尼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