2011-10-28 9 views
8

onPause()onResume()カメラのライブサイクルで問題が発生しました: カメラのプレビューと写真の撮影はまったく問題ありません。 1つの例外を除いて:android:camera onPause/onResume issue

私は、アプリケーションを起動し、ホームボタンをクリックし、アプリに戻って別のショットを撮る。

結果:shuttercallbackはまだ実行されていますが(コードを参照)、jpegコールバックはもうありません。その後、私の銀河Sは振動し、画面は黒くなります。なぜなら、startPreview()はjpegCallbackの後で再トリガーされないからです。スタックトレースは私にとっては役に立たないものです。 これは私のギャラクシーSでのみ起こり、エミュレータでは起こらないということです。私は実際にどのように移動するのか手がかりを持っていません:/ 誰もが何が役に立つか考えていますか?ここで

 
10-28 18:59:40.649: ERROR/SecCamera(4291): SetRotate(angle(0)) 
10-28 18:59:40.649: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null) 
10-28 18:59:40.649: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480)) 
10-28 18:59:40.673: ERROR/SecCamera(4291): SetRotate(angle(0)) 
10-28 18:59:40.673: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null) 
10-28 18:59:40.673: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480)) 
10-28 18:59:40.692: ERROR/SecCamera(4291): SetRotate(angle(0)) 
10-28 18:59:40.692: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null) 
10-28 18:59:40.692: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480)) 
10-28 18:59:40.712: ERROR/SecCamera(4291): SetRotate(angle(0)) 
10-28 18:59:40.712: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null) 
10-28 18:59:40.712: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480)) 
10-28 18:59:40.751: ERROR/CameraHardwareSec(4291): stopPreview() 
10-28 18:59:40.751: ERROR/SecCamera(4291): cancelAutofocus() 
10-28 18:59:40.751: ERROR/SecCamera(4291): cancelAutofocus() end, 0, 4 
10-28 18:59:40.768: ERROR/SecCamera(4291): stopPreview() 
10-28 18:59:40.768: ERROR/SecCamera(4291): fimc_v4l2_streamoff() 
10-28 18:59:40.797: ERROR/CameraHardwareSec(4291): stopPreview() end 
10-28 18:59:41.622: ERROR/SecCamera(4291): fimc_v4l2_streamoff() 
10-28 18:59:46.536: ERROR/dalvikvm(2993): Failed to write stack traces to /data/anr/traces.txt (2775 of 2970): Unknown error: 0 
10-28 18:59:46.540: ERROR/dalvikvm(2919): Failed to write stack traces to /data/anr/traces.txt (-1 of 3414): Math result not representable 
10-28 18:59:46.610: ERROR/dalvikvm(3044): Failed to write stack traces to /data/anr/traces.txt (3354 of 7154): Math result not representable 
... 

が私の(短縮)コードです:

 
public class CameraActivity extends Activity implements MenuViewCallback, CutoutPathManagerCallback { 
    public static final String TAG = "CutoutCamera"; 
    Preview preview; 
    OverlayView overlay; 
    static MenuView menuView; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Hide the window title. 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     ... 

     preview = (Preview) this.findViewById(R.id.preview); 
     ... 
    } 

    ... 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     this.log("onResume()"); 
     preview.openCamera(); 
    } 


    @Override 
    protected void onPause() { 
     super.onPause(); 
     this.log("onPause()"); 
     if (preview.camera != null) { 
      preview.camera.release(); 
      preview.camera = null; 
     } 
    } 

    // Called when shutter is opened 
    ShutterCallback shutterCallback = new ShutterCallback() { // 
     public void onShutter() { 
      Log.d(TAG, "onShutter'd"); 
     } 
    }; 

    // Handles data for raw picture 
    PictureCallback rawCallback = new PictureCallback() { // 
     public void onPictureTaken(byte[] data, Camera camera) { 
      Log.d(TAG, "onPictureTaken - raw"); 
     } 
    }; 

    // Handles data for jpeg picture 
    PictureCallback jpegCallback = new PictureCallback() { // 
     public void onPictureTaken(byte[] data, Camera camera) { 
      Log.d(TAG, "onPictureTaken - jpeg"); 
      ... 
     } 
    }; 

    @Override 
    public void shootButtonClicked() { 
     preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback); 
    } 

    @Override 
    public void focusButtonClicked() { 
     preview.camera.autoFocus(new Camera.AutoFocusCallback() { 
      public void onAutoFocus(boolean success, Camera camera) { 

      } 
     }); 
    } 
} 
 
/** 
* order of execution: 
* openCamera() 
* onMeasure() 
* onLayout() 
* onMeasure() 
* onLayout() 
* surfaceCreated() 
* surfaceChanged() 
* onMeasure() 
* onLayout() 
* onMeasure() 
* @author stephan 
* 
*/ 
class Preview extends ViewGroup implements SurfaceHolder.Callback { // 
    private static final String TAG = "Preview"; 

    SurfaceHolder mHolder; // 
    public Camera camera; // 
    private List supportedPreviewSizes; 
    private Size previewSize; 
    SurfaceView mSurfaceView; 
    CameraActivity cameraActivity; 
    int l2 = 0, t2 = 0, r2 = 0, b2 = 0; 
    int padding = 20; 
    Size optimalPreviewSize, optimalPictureSize; 
    // the size of this view. gets set in onMeasure() 
    int fullWidth, fullHeight; 



    public Preview(Context context) { 
     super(context); 
     init(context); 
    } 

    public Preview(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(context); 
    } 

    public Preview(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(context); 
    } 

    private void init(Context context) { 
     setKeepScreenOn(true); 
     cameraActivity = (CameraActivity) context; 
     mSurfaceView = new SurfaceView(context); 
     addView(mSurfaceView); 

     mHolder = mSurfaceView.getHolder(); // 
     mHolder.addCallback(this); // 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 
    } 
    ... 

    public void openCamera() { 
     cameraActivity.log("openCamera()"); 
     if (this.camera == null) { 
      cameraActivity.log("Camera.open()"); 
      this.camera = Camera.open(); 

      //supportedPreviewSizes = camera.getParameters().getSupportedPreviewSizes(); 
      requestLayout(); // -> onMeassure() -> onLayout() 
     } 
    } 


    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     cameraActivity.log("onMeasure()"); 

     // We purposely disregard child measurements because act as a 
     // wrapper to a SurfaceView that centers the camera preview instead 
     // of stretching it. 
     fullWidth = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
     fullHeight = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 
     setMeasuredDimension(fullWidth, fullHeight); 

     if(this.camera != null){ 
      cameraActivity.log("fullSize:"+fullWidth+"x"+fullHeight); 
      this.setCameraPreviewSize(); 
      this.setCameraPictureSize(); 
     } 
    } 

    private void calcScaledPreviewSize(){ 
     ... 
    } 

    ... 

    private void setCameraPreviewSize() { 
     Camera.Parameters parameters = camera.getParameters(); 
     if(parameters.getPreviewSize() != this.getOptimalPreviewSize()){ 
      parameters.setPreviewSize(this.getOptimalPreviewSize().width, this.getOptimalPreviewSize().height); 
      this.camera.setParameters(parameters); 
     } 
    } 

    private void setCameraPictureSize() { 
     Camera.Parameters parameters = this.camera.getParameters(); 
     if(parameters.getPictureSize() != this.getOptimalCameraPictureSize()){ 
      parameters.setPictureSize(getOptimalCameraPictureSize().width, getOptimalCameraPictureSize().height); 
      this.camera.setParameters(parameters); 
     } 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
     cameraActivity.log("onLayout()"); 
     if (changed && getChildCount() > 0 && this.camera != null) { 
      final View child = getChildAt(0); 
      cameraActivity.log("r:"+this.getPreviewRight()+" l:"+this.getPreviewLeft()+" b:"+this.getPreviewBottom()+" t:"+this.getPreviewTop()); 
      child.layout(this.getPreviewLeft(), this.getPreviewTop(), this.getPreviewRight(), this.getPreviewBottom()); 
      cameraActivity.initOverlay(this.getPreviewLeft(),this.getPreviewTop(),this.getPreviewRight(),this.getPreviewBottom()); 
     } 
    } 
    private Size getOptimalPreviewSize() { 

     if(optimalPreviewSize == null){ 
      //calculate optimal preview size 
     } 
     return optimalPreviewSize; 
    } 

    private Size getOptimalCameraPictureSize() { 

     if(optimalPictureSize == null){ 
      //calculate optimal image size 
     } 
     return optimalPictureSize; 
    } 


    // Called once the holder is ready 
    public void surfaceCreated(SurfaceHolder holder) { // 
     // The Surface has been created, acquire the camera and tell it where 
     // to draw. 
     cameraActivity.log("surfaceCreated()"); 
     try { 
      if (this.camera != null) { 
       this.camera.setPreviewDisplay(holder); 
      } 
     } catch (IOException exception) { 
      Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); 

     } 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     cameraActivity.log("surfaceChanged()"); 
     if (camera != null) { 

      Camera.Parameters parameters = camera.getParameters(); 
      parameters.setPreviewSize(getOptimalPreviewSize().width, getOptimalPreviewSize().height); 
      requestLayout(); 

      camera.setParameters(parameters); 
      camera.startPreview(); 
     } 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { // 
     cameraActivity.log("surfaceDestroyed()"); 
     if(this.camera != null){ 
      camera.stopPreview(); 
     } 
    } 

    public void releaseCamera(){ 
     cameraActivity.log("releaseCamera()"); 
     if (camera != null) { 
      camera.stopPreview(); 
      camera.setPreviewCallback(null); 
      camera.release(); 
      camera = null; 
     } 
    } 
} 

答えて

4

これは私が最終的に(私はギャラクシーSを含め、それを試してみましたすべてのデバイスに取り組んで)、それを100%に固定する方法です。

私はcamereプレビューオブジェクトonResumeを破壊し、起動時のようにすべてを一緒に再インスタンス化しました。ここでは詳細:

android: I get no stacktrace, phone just hangs

2

私の推測では、カメラがあるので、あなたがしなければならないすべては、(プレビューでローカルカメラオブジェクトはonPause(後に無効となる)カメラをリセットするためのプレビューでsetterメソッドを作成することであるということですリリースされましたが、残りのプレビュー状態はまだ維持されています)。

3

この投稿には少し遅れていますが、同様の問題がありました。まず、あなたが顧客ROMを使用している場合、それはカメラドライバ(私の1 X8 runniing 4.0.4)の問題かもしれません。この問題は、電源ボタンを押して電話機をスタンバイモードにして、短時間で戻す(ホーム画面ロックの有無にかかわらず)場合にも発生します。試してみた後、私はそれがsuper.onPauseが最高です前にカメラをシャットダウンした後に短い遅延を置くことがわかった。私のコードは以下の通りです。

@Override 
    public void onPause() { 
     // Log.d(TAG,"ccp_onPause"); 
     closeCamera(); 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     super.onPause(); 
    } 

とcloseCamera();

public void closeCamera() { 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
      mCamera.setPreviewCallback(null); 
      mCamera.lock(); 
      mCamera.release(); 
      mCamera=null; 
      requestLayout(); 
     } 
    } 
+0

なぜonPauseに遅延を追加したのがこの問題を修正したのですか? –