2012-11-05 14 views
10

CameraPreviewクラスを使用しているアクティビティクラス(CameraActivity)が1つあります。 "OnResume"では、カメラとプレビューが開始されます。 "OnPause"では、カメラのリソースを解放しています。アプリケーションが開始されると、 "OnResume"の内部ですべて正常に動作しますが、別のアクティビティをインテント(ブラウザのオープンURL)で開始してからアクティビティに戻ると、CamerPreviewクラスの "OnResume"内で例外が発生します。コードの下に見つけてください:リリース後に呼び出されるメソッド例外Camera preview

// CameraActivityクラス

public void onResume(){ 
    super.onResume(); 
    Log.d("inside onResume, camera==="+mCamera, "inside onResume"); 
    try { 
     if(mCamera==null) 
     { 

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 


     autoFocusHandler = new Handler(); 
     mCamera = getCameraInstance(); 
     int rotation = this.getWindowManager().getDefaultDisplay().getRotation(); 


     scanner = new ImageScanner(); 
     scanner.setConfig(0, Config.X_DENSITY, 3); 
     scanner.setConfig(0, Config.Y_DENSITY, 3); 

     mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB); 

     FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview); 
     preview.addView(mPreview); 



    } 





} catch (Exception e) { 
    // TODO Auto-generated catch block 
    Log.e("onResume",Log.getStackTraceString(e)); 
} 



public void onPause{ 
    try { 
     super.onPause(); 
     if (mCamera != null) { 
      previewing = false; 
      mCamera.stopPreview(); 
       mCamera.setPreviewCallback(null); 
       mCamera.release(); 
       mCamera = null; 
       mPreview=null; 


    } 
} catch (Exception e) { 
    // TODO Auto-generated catch block 
    Log.e("releaseCamera",Log.getStackTraceString(e)); 
} 
} 



public static Camera getCameraInstance(){ 
     Camera c = null; 
     try { 
      c = Camera.open(); 
     } catch (Exception e){ 
      Log.e("getCameraInstance",Log.getStackTraceString(e)); 

    } 
    return c; 
} 

// CameraPreviewクラスを以下に示します。

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
    private SurfaceHolder mHolder; 
    Camera mCamera; 
    PreviewCallback previewCallback; 
    AutoFocusCallback autoFocusCallback; 
    private int rotation; 
    public int getRotation() { 
     return rotation; 
    } 

    public void setRotation(int rotation) { 
     this.rotation = rotation; 
    } 

    public CameraPreview(Context context, Camera camera, 
         PreviewCallback previewCb, 
         AutoFocusCallback autoFocusCb) { 
     super(context); 
     mCamera = camera; 
     previewCallback = previewCb; 
     autoFocusCallback = autoFocusCb; 

     /* 
     * Set camera to continuous focus if supported, otherwise use 
     * software auto-focus. Only works for API level >=9. 
     */ 
     /* 
     Camera.Parameters parameters = camera.getParameters(); 
     for (String f : parameters.getSupportedFocusModes()) { 
      if (f == Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) { 
       mCamera.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
       autoFocusCallback = null; 
       break; 
      } 
     } 
     */ 

     // Install a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and destroyed. 
     mHolder = getHolder(); 
     mHolder.addCallback(this); 

     // deprecated setting, but required on Android versions prior to 3.0 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 


    public void surfaceCreated(SurfaceHolder holder) { 
     // The Surface has been created, now tell the camera where to draw the preview. 
     try { 
      if(mCamera==null){ 
       mCamera=Camera.open(); 
      } 
      mCamera.setPreviewDisplay(holder); 
     } catch (IOException e) { 
      Log.d("DBG", "Error setting camera preview: " + e.getMessage()); 
     } 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 

     // Camera preview released in activity 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     /* 
     * If your preview can change or rotate, take care of those events here. 
     * Make sure to stop the preview before resizing or reformatting it. 
     */ 
     if (mHolder.getSurface() == null){ 
      // preview surface does not exist 
      return; 
     } 

     // stop preview before making changes 
     try { 
      mCamera.stopPreview(); 
     } catch (Exception e){ 
      // ignore: tried to stop a non-existent preview 
     } 

try{ 
      mCamera.setPreviewDisplay(mHolder); 
      mCamera.setPreviewCallback(previewCallback); 
      mCamera.startPreview(); 
      mCamera.autoFocus(autoFocusCallback); 
     } catch (Exception e){ 
      Log.d("DBG", "Error starting camera preview: " + e.getMessage()); 
     } 
    } 

} 

これはlogCatからである:

11-05 10:14:34.585: E/AndroidRuntime(7864): FATAL EXCEPTION: main 
11-05 10:14:34.585: E/AndroidRuntime(7864): java.lang.RuntimeException: Method called after release() 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.hardware.Camera.setPreviewDisplay(Native Method) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.hardware.Camera.setPreviewDisplay(Camera.java:393) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at com.intagleo.qraugmented.detection.camera.CameraPreview.surfaceCreated(CameraPreview.java:74) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.view.SurfaceView.updateWindow(SurfaceView.java:552) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:215) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.view.View.dispatchWindowVisibilityChanged(View.java:4027) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.view.ViewRoot.performTraversals(ViewRoot.java:790) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1867) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.os.Handler.dispatchMessage(Handler.java:99) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.os.Looper.loop(Looper.java:130) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at android.app.ActivityThread.main(ActivityThread.java:3687) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at java.lang.reflect.Method.invokeNative(Native Method) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at java.lang.reflect.Method.invoke(Method.java:507) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 
11-05 10:14:34.585: E/AndroidRuntime(7864):  at dalvik.system.NativeStart.main(Native Method) 

EDIT

私は "surfaceDestroyed" 更新と示唆されているように、ログを置くが、今私は "onPause" の例外を取得しています - > onSurfaceDestroyed。最初はonPauseが正常に実行されていました。

1カメラインスタンスは、アクティビティクラスの "onResume"メソッド "getCameraInstance"で作成され、mCameraインスタンスをCameraPreviewクラスに渡します。カメラのインスタンスがonSurfaceCreatedの片側だけに作成され、mCameraインスタンスがアクティビティクラスに割り当てられるように変更しようとしましたが、動作しませんでした。私はまた、 "CameraPreview"クラスのpreviewCallBackメンバが最初に有効ですが、 "CameraPreview"クラスの "previewCallBack"メンバがnullであることをデバッグを介して気付きました。

"onResume"が初めて呼び出されたときはすべて正常に動作しますが、onPause後に2回目に実行されると、onResumeのコードは同じですが、元々は例外が発生します。

11-06 01:25:28.375: I/onResume(4332): INITIATED 
// Workinf fine till now. Now opening another intent activity 
11-06 01:26:23.500: I/onPause(4332): INITIATED 
11-06 01:26:23.804: "OnSurfaceDestroyed": "Initiated" 
11-06 01:26:23.945: E/AndroidRuntime(4332): FATAL EXCEPTION: main 
11-06 01:26:23.945: E/AndroidRuntime(4332): java.lang.RuntimeException: Method called after release() 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.hardware.Camera.stopPreview(Native Method) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at com.intagleo.qraugmented.detection.camera.CameraPreview.surfaceDestroyed(CameraPreview.java:85) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:596) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.SurfaceView.updateWindow(SurfaceView.java:490) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:215) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.View.dispatchWindowVisibilityChanged(View.java:4027) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.ViewRoot.performTraversals(ViewRoot.java:790) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1867) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.os.Handler.dispatchMessage(Handler.java:99) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.os.Looper.loop(Looper.java:130) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at android.app.ActivityThread.main(ActivityThread.java:3687) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at java.lang.reflect.Method.invokeNative(Native Method) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at java.lang.reflect.Method.invoke(Method.java:507) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 
11-06 01:26:23.945: E/AndroidRuntime(4332):  at dalvik.system.NativeStart.main(Native Method) 
+0

あなたのカメラが適切にリリースされているように見えますが、再開すると開くことはありません。 'surfaceDestroyed'では' mCamera'を 'null'に設定して、' surfaceCreated'の 'if(mCamera == null){' statment' – jnthnjns

+0

を以下のようにマークしてください。 –

+0

@arunsooryaその答えは? –

答えて

39

新しいカメラを作成して開くと、FrameLayoutには以前のカメラが残っているため、新しいカメラに加えてsurfaceCreatedが呼び出されます。このような

何をすべき、あなたは(onPause()法上の)カメラを離すとFrameLayoutから以前のカメラを削除します

preview.removeView(mPreview); 

はそれがお役に立てば幸いです。

1

EDIT

これは私が今、あなたの例外を引き起こしているものを100%確認することができない、答えるために厳しいものです。私はとstopCamera()メソッドを使用して、とonResumeというコードを使用して、下にカメラコードを含めました。私はまた、唯一の私は私のcameraView == nullない限りonResumeで再インスタンス化していない、私のonCreateCameraPreviewクラスの新しいインスタンスを作成します。私たちがやり方を変えることがいくつかあります。

P.S:すべてが私の作品:うまくいけば、以下のコードは、多分あなたは、あなたが働いて得るためにそれを再生することができ、役立ちます。すなわちなど他の活動、に行く私がテストしていないのライフサイクルの一部のみがonDestroyですが、私のアプリケーションは、このサイクルの初めに開始するように設計されているので、それはです。

MainActivity:

boolean cameraReleased = false; 

@Override 
protected void onPause() { 
    Log.i("onPause", "CALLED:: cameraReleased = " + cameraReleased); 
    Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString()); 
    if (cameraReleased == false) { 
     image = null; 
     imageResult.setImageBitmap(null); 
     imageResult.setImageResource(0); 
     cameraView.stopCamera(); 
     cameraReleased = true; 
    } 

    if (cameraView == null) { 
     Log.i("onPause", "cameraView == null"); 
     cameraView = new JJCameraSurfaceView(getApplicationContext()); 
     imageResult = new ImageView(getApplicationContext()); 
    } 
    super.onPause(); 
} 

@Override 
protected void onDestroy() { 
    Log.e("onDestroy", "INITIATED"); 
    super.onDestroy(); 
} 

@Override 
protected void onResume() { 
    Log.i("onResume", "CALLED:: cameraReleased = " + cameraReleased); 
    Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString()); 
    if (cameraReleased == true) { 
     image = null; 
     imageResult.setImageBitmap(null); 
     imageResult.setImageResource(0); 
     cameraView.startCamera(); 
    } 

    if (cameraView == null) { 
     Log.i("onResume", "cameraView == null"); 
     cameraView = new JJCameraPreview(getApplicationContext()); 
     imageResult = new ImageView(getApplicationContext()); 
    } 

    super.onResume(); 
} 

@Override 
public void onBackPressed() { 
    // If Statement used to get out of my camera view and back to my MainActivity - Same Class 
    if (“Camera Preview or Image Result is displayed”) { 
     cameraView.stopCamera(); 
     image = null; 
     imageResult.setImageBitmap(null); 
     imageResult.setImageResource(0); 
     cameraView.startCamera(); 
     return; 
    } 

    Log.i("onBackPressed", "WAS PRESSED"); 
    super.onBackPressed(); 
} 

CameraPreview:

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    Log.w("surfaceChanged", "STARTED"); 
    if (camera != null) { 
     Log.w("surfaceChanged", "camera = NOT NULL"); 
     Camera.Parameters cParams = camera.getParameters(); 
     cParams.setPreviewSize(width, height); 
     cParams.setSceneMode(Parameters.SCENE_MODE_NIGHT); 
     camera.setParameters(cParams); 
     camera.startPreview(); 
    } 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    Log.w("surfaceCreated", "STARTED"); 
    if (camera == null) { 
     camera = Camera.open(); 
    } 
    try { 
     camera.setPreviewDisplay(mHolder); 
    } catch (Exception e) { 
     Log.e("setPreviewDisplay", "FAILED: " + e.getMessage()); 
    } 
} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    Log.w("CameraSurfaceDestroyed", "INITIATED"); 
    camera.stopPreview(); 
    camera.release(); 
    camera = null; 
} 

public void startCamera() { 
    Log.w("startCamera", "CALLED"); 
    mHolder = getHolder(); 
    surfaceCreated(mHolder); 
    camera.startPreview(); 
    mHolder.addCallback(this); 
} 

public void stopCamera() { 
    mHolder = getHolder(); 
    mHolder.removeCallback(this); 
    camera.stopPreview(); 
} 
+0

CameraPreviewは新しく作成されたインスタンスであるため、mCameraはnullにする必要があります(onPausedでヌルになっているため) – njzk2

+0

カメラが正しく再オープンされていません。私は最近この問題を抱えていて、アクティビティライフサイクルのすべてをオーバーライドして、コールされたものを見つけ出し、リリースして適切に再開していることを確認しなければなりませんでした。あなたのカメラで 'onPause'と' onResume'が正しく動作するならば、 'onPause'はインテントを通して他のアクティビティを開始したときに呼び出されていないのでしょうか? – jnthnjns

+0

onPauseが呼び出されなかった場合、リリースは呼び出されません。 – njzk2

1

私はMethod called after release()エラーで閉鎖力だった私のコードと同様の問題がありました。

私はヌルcameraオブジェクトをチェックしてからcamera.Open()と呼ばOnResume()SetupCamera()メソッドを呼び出していました。私の問題を修正し何

Camera Docsを読んだ後、ヌルチェックとそれがnullだったかどうかcamera.Open()を呼び出して(私はにcamera = nullをすでに設定していた)を取り除くことでした。

私はこれが私の問題を突き止めるのに決定的ではないことを知っていますが、それは絶対に私のために働いていました!

FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview); 
preview.addView(mPreview); 

surfaceCreatedメソッドが呼び出されますので、mCamera.setPreviewDisplay(holder);が呼び出されます:あなたはこのように、でframeLayoutにカメラを追加してきたように

4

Danが正しいです。またhereを参照してください。

コードサンプル:

public class MainActivity extends Activity { 
    private FrameLayout mFlCameraPreview; 
    private Camera mCamera; 
    private CameraPreview mCameraPreview; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mFlCameraPreview = (FrameLayout) findViewById(R.id.main_fl_camera_preview); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     if (mCamera == null) { 
      mCamera = getCameraInstance(); 
     } 

     if (mCameraPreview == null) { 
      mCameraPreview = new CameraPreview(this, mCamera); 
      mFlCameraPreview.addView(mCameraPreview); 
     } 

    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
      mCamera.release(); 
      mCamera = null; 
     } 

     if (mCameraPreview != null) { 
      mFlCameraPreview.removeView(mCameraPreview); 
      mCameraPreview = null; 
     } 
    } 

    public static Camera getCameraInstance() { 
     Camera camera = null; 
     try { 
      camera = Camera.open(); 
     } catch (Exception e) { 

     } 
     return camera; 
    } 
} 
+0

ニース、コードありがとう –

1

私の作業溶液: まず:配列としてCameraActivityクラス宣言mCameraで :

Camera mCamera[] = new Camera[1]; 

第二:コンストラクタCameraPreviewの宣言は次のようになります。

public CameraPreview(Context context, Camera[] camera, 
        PreviewCallback previewCb, 
        AutoFocusCallback autoFocusCb) { 
     mCamera = camera; 
     ... 
} 
次のように CameraPreviewクラスの

しかしmCameraを宣言する必要があります。

Camera[] mCamera; // without instantiating of the array! 

そして最後に:すべてのメソッド内部の両方のクラスでは、すべての参照を置き換える必要がありmCameramCamera[0]

によって

P.S:ごめんなさい、英語は

0

onPause()とonResume()をオーバーライドする代わりに、onStop()とonRestart()をオーバーライドしてください。アクティビティライフサイクルでは、アクティビティがVisibleでなく、次のライフサイクルメソッドコールがonRestart()にあるときにonStop()が呼び出されます。以下のコードを見てください。

@Override 
    protected void onStop() { 
     super.onStop(); 
     try { 
      m_camera.stopPreview(); 
      m_camera.release(); 
      preview.removeView(m_CameraPreview); 
/* 
m_CameraPreview is the object of the class that looks like this :        public class CameraSurfaceView extends SurfaceView implements Callback 
*/ 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
    @Override 
    protected void onRestart() { 
     super.onRestart(); 
     m_camera=getCameraInstance();//Initialize the camera in your own way 
     m_CameraPreview = new CameraSurfaceView(this, m_camera); 
     preview = (FrameLayout)findViewById(R.id.camera_preview); 
     preview.addView(this.m_CameraPreview); 
/* 
*camera_preview is the id of the framelayout defined in xml file and preview is *the instance of FrameLayout. 
*/ 
    } 

ダンが言ったように、フレームのレイアウトは、前のカメラのインスタンスへのホールドを持っていますし、そのsurfaceviewコールバックは、競合状態を作成する新しいオブジェクトに加えて作成されます。したがって、それをonStop()で解放し、onRestart()で再初期化する必要があります。 これが役立つことを願っています。

0

同じエラーが発生しました。以下の手順は私の問題を解決します。

コールgetHolder().removeCallback(this);

surfaceDestroyed()のCall

private void releaseCameraAndPreview() { 

     if (mCamera != null) { 
      mCamera.stopPreview(); 
      mCamera.setPreviewCallback(null); 
      mCamera.release(); 
      mCamera = null; 
     } 

     if(mPreview != null){ 
      mPreview.destroyDrawingCache(); 
      mPreview.mCamera = null; 
     } 

    } 

のCall onCreateView()

private boolean safeCameraOpenInView(View view) { 
     boolean qOpened = false; 
     releaseCameraAndPreview(); 
     mCamera = getCameraInstance(); 
     mCameraView = view; 
     qOpened = (mCamera != null); 

     if(qOpened == true){ 
      mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera,view); 
      preview = (FrameLayout) view.findViewById(R.id.camera_preview); 
      preview.addView(mPreview); 
      mPreview.startCameraPreview(); 
     } 
     return qOpened; 
    } 

関連する問題