2012-01-11 11 views
20

Tôi đã thử mọi thứ nhưng tôi vẫn không thể giải quyết vấn đề này.autoFocus ném ngoại lệ

Tôi đang triển khai tính năng máy ảnh trong ứng dụng và mọi thứ hoạt động tốt ngoại trừ tự động lấy nét. Khi tôi gọi autoFocus(), nó ném một ngoại lệ, và tôi không thể hiểu tại sao. Tôi đang chạy mã trên Desire HD.

Code:

@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 trace:

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) 

Trả lời

7

Bạn có thể muốn chắc chắn rằng điện thoại hỗ trợ tự động lấy nét. Thật dễ dàng để kiểm tra điều này:

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

Cảm ơn, tôi đã kết thúc bằng một thư viện mã nguồn mở bên thứ 3 cho những gì tôi cần là có không có vấn đề với tự động lấy nét. – MikeIsrael

+0

@MikeIsrael Tôi đang đối mặt với cùng một vấn đề với ngoại lệ autoFocus Failed. bạn có thể cho tôi biết bạn đã sử dụng giải pháp nào không. Tôi nhận được ngoại lệ này đôi khi khi tôi bắt đầu máy ảnh trong ứng dụng của tôi không phải lúc nào. Cảm ơn bạn – Vikram

+0

@Vikram Tôi cần một cái gì đó để quét mã vạch để cuối cùng tôi cuối cùng chỉ sử dụng zxing. Tôi đã không bao giờ có thể tìm thấy một lý do cho các ngoại lệ được ném ra, tôi nhớ cố gắng cấp phép khác nhau và tất cả mọi thứ. zxing là mã nguồn mở vì vậy bạn có thể chỉ muốn kiểm tra một số mã của họ và xem nó có thể giúp bạn không, hãy nhớ chú ý đến cấp phép của họ. – MikeIsrael

13

Sử dụng SurfaceHolder.Callback -> surfaceTạo để biết khi nào bạn có thể bắt đầu lấy nét tự động. Nếu bề mặt không được tạo ra (kéo dài một thời gian) tự động lấy nét sẽ thất bại.

+0

Xem câu trả lời của tôi bên dưới, nó có mã về cách thực hiện việc này. – Josh

1

Đảm bảo bạn đang gọi chức năng tự động lấy nét sau khi gọi bản xem trước bắt đầu. Theo android documentation

Phương pháp này chỉ có giá trị khi xem trước đang hoạt động (giữa startPreview() và trước stopPreview()).

Nếu bạn vẫn gặp phải bất kỳ lỗi nào, hãy thử Rasmus'szwebie's giải pháp theo cùng thứ tự.

3

Tôi đề xuất hai giải pháp phù hợp với tôi. 1) Dừng và Tiếp tục lại máy ảnh chính xác. Tôi làm điều đó bằng cách gọi các phương pháp trên onPause và onResume, cũng ở giữa camera trước, nơi tôi quét mã QR trong ứng dụng của tôi:

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) Rất khó khăn nhưng làm việc như kỳ diệu! Đảm bảo rằng bạn gọi tự động lấy nét SAU KHI bề mặt xem trước đã được tạo. Để thực hiện điều này, hãy chạy Tự động lấy nét với độ trễ 200ms, để mua thời gian cho bề mặt được tạo. Thiết lập này bằng cách nhấn Ctrl + Click chuột qua một tuyên bố đối tượng "CameraPreview", chẳng hạn như:

CameraPreview my_camera; 

Look cho "public void surfaceChanged" phương pháp và thực hiện điều này thay đổi:

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

Có rất nhiều khác các bản sửa lỗi, nhưng hai cách này có thể tiết kiệm trong ngày của bạn.

0

Có rất nhiều giải pháp, nhưng điều này là một, chết tùy chọn rẻ tiền dễ dàng mà làm việc cho tôi:

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! Đã hủy kích hoạt bẫy.

+0

Điều này sẽ không giúp ích nhiều khi phương pháp autoFocus có thể được gọi bất kể nó được hỗ trợ hay không. Tài liệu cho biết: Nếu máy ảnh không hỗ trợ lấy nét tự động, đó là cuộc gọi lại không-op và onAutoFocus (boolean, Camera) sẽ được gọi ngay lập tức. – slott

3

tôi đã tìm được một giải pháp tốt đẹp
Vì vậy, cho phép bắt ngoại lệ này chỉ đơn giản, và cố gắng một lần nữa để gọi tự động lấy nét trên một số thiết bị (ví dụ Experia sony và một số người khác)
là gì trong khoảng thời gian trì hoãn giữa retries (1 giây)
tôi không yêu bất kỳ số "ma thuật" nào trong mã, do đó, số này có thể quá lớn hoặc quá nhỏ trong một số trường hợp.đủ cho tôi)

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

và đây được bắt đầu và ngừng của nó phương pháp

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

tham khảo: https://github.com/dm77/barcodescanner/blob/master/core/src/main/java/me/dm7/barcodescanner/core/CameraPreview.java