2016-12-02 7 views
0

У меня есть приложение, которое снимает с таймера. Обычно он работает нормально, за исключением случаев, когда экран вращается во время сна. Может ли кто-нибудь сказать мне, почему он не может сделать снимок после вращения во сне?Камера используется после того, как Camera.release() вызывается после поворота экрана

Обычно, когда камера переходит в спящий режим и просыпается он выполняет ...

@Override 
protected void onPause() { 
    super.onPause(); 
    camera.stopPreview(); 
    camera.release(); 
    //camera = null; //this give me a null object message 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    camera = Camera.open(cameraId); 
    setCameraDisplayOrientation(); 
    startCameraPreview(surfaceHolder, surfaceView.getWidth(), surfaceView.getHeight()); 
} 

Однако, когда он просыпается после того, как камера была повернута во сне, он сначала выполняет onResume(), surfaceChanged(), OnPause(), OnStop (пусто), OnDestroy (пусто), то следующее:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    surfaceView = (SurfaceView) findViewById(R.id.surface); 
    surfaceHolder = surfaceView.getHolder(); 
    surfaceHolder.addCallback(this); 
} 

@Override 
protected void onStart() { 
    super.onStart(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    camera = Camera.open(cameraId); 
    setCameraDisplayOrientation(); 
    startCameraPreview(surfaceHolder, surfaceView.getWidth(), surfaceView.getHeight()); 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    camera.stopPreview(); 
    setCameraDisplayOrientation(); 
    startCameraPreview(holder, w, h); 
} 

public void setCameraDisplayOrientation() { 
    deviceRotation = getWindowManager().getDefaultDisplay().getRotation(); 
    int degrees = 0; 
    switch(deviceRotation) { 
     case Surface.ROTATION_0: degrees=0; break;//vertical 
     case Surface.ROTATION_90: degrees=-90; break; //left side 
     case Surface.ROTATION_180: degrees=180; break; //upside-down 
     case Surface.ROTATION_270: degrees=90; break; //right side 
    } 
    Camera.CameraInfo info = new Camera.CameraInfo(); 
    Camera.getCameraInfo(cameraId, info); 
    displayRotation = info.orientation + degrees; 
    camera.setDisplayOrientation(displayRotation); //changes orientation of camera's display 
} 

public void startCameraPreview(SurfaceHolder holder, int w, int h) { 
    double targetRatio = 0; 
    switch(deviceRotation) { 
     case Surface.ROTATION_0: targetRatio = (double)w/(double)h; break; //vertical 
     case Surface.ROTATION_90: targetRatio = (double)h/(double)w; break; //left side 
     case Surface.ROTATION_180: targetRatio = (double)w/(double)h; break; //upside-down 
     case Surface.ROTATION_270: targetRatio = (double)h/(double)w; break; //right side 
    } 
    Camera.Parameters p = camera.getParameters(); 
    List<Camera.Size> previewSizes = p.getSupportedPreviewSizes(); 
    int optimal_h = 2; //always refers to short length in PreviewSizes 
    int optimal_w = 1; //always refers to long length in PreviewSizes 
    for(Camera.Size previewSize : previewSizes) { 
     if (Math.abs((double)previewSize.height/(double)previewSize.width - targetRatio) < 
       Math.abs((double)optimal_h/(double)optimal_w - targetRatio)) { 
      optimal_h = previewSize.height; 
      optimal_w = previewSize.width; 
     } 
    } 
    p.setPreviewSize(optimal_w, optimal_h); //defines ratio of image preview - sizes can be larger than actual display 
    p.set("rotation", displayRotation); //required to orient final jpeg file correctly 
    camera.setParameters(p); 
    ViewGroup.LayoutParams surfaceParams = surfaceView.getLayoutParams(); 
    switch(deviceRotation) { //aligns ratio of surface view to ratio of image preview 
     case Surface.ROTATION_0: 
      surfaceParams.width=ViewGroup.LayoutParams.MATCH_PARENT; 
      surfaceParams.height=(int)(w*(double)optimal_w/(double)optimal_h); 
      break; //vertical 
     case Surface.ROTATION_90: 
      surfaceParams.width=(int)(h*(double)optimal_w/(double)optimal_h); 
      surfaceParams.height=ViewGroup.LayoutParams.MATCH_PARENT; 
      break; //left side 
     case Surface.ROTATION_180: 
      surfaceParams.width=ViewGroup.LayoutParams.MATCH_PARENT; 
      surfaceParams.height=(int)(w*(double)optimal_w/(double)optimal_h); 
      break; //upside-down 
     case Surface.ROTATION_270: 
      surfaceParams.width=(int)(h*(double)optimal_w/(double)optimal_h); 
      surfaceParams.height=ViewGroup.LayoutParams.MATCH_PARENT; 
      break; //right side 
    } 
    surfaceView.setLayoutParams(surfaceParams); 
    camera.setPreviewDisplay(holder); //required to startPreview 
    camera.startPreview(); 
} 

Это не полный код. Этот код создает несколько незначительных ошибок форматирования изображений, но он все еще демонстрирует проблему. Я упростил некоторые вещи для простоты. Основная проблема заключается в том, что когда он пытается сделать снимок после поворота во сне, он возвращает ошибку «Камера используется после того, как Camera.release() был вызван». Почему это?

ответ

0

Это действительно просрочено, но, как только мне удалось решить подобную проблему мин минуту назад, я думал, что внес свой вклад в пользу себя и всех, кто может отчаянно искать Стек.

Поэтому, когда вы вращаете устройство, вы вызываете onPause и onDestroy, где вы отпускаете свою камеру. Я заметил, что у вас есть camera.open() в вашем onResume, без взгляда на ваш код, связанный с поверхностью, я не могу прокомментировать. Это то, что сработало для меня.

Во-первых, cameraPreview

`

public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { 
    try { 
     this.mCamera.setPreviewDisplay(surfaceHolder); 
     this.mCamera.startPreview(); 
    } catch (Exception e) { 
    } 
} 


public void surfaceCreated(SurfaceHolder surfaceHolder) { 
    try { 
     //TODO we need this here too because on SurfaceCreated we always need to open the camera, in case its released 

     this.mCamera.setPreviewDisplay(surfaceHolder); 
     this.mCamera.setDisplayOrientation(90); 
     //this.mCamera.startPreview(); 
    } catch (IOException e) { 
    } 
} 

Далее Жизненный код в CameraActivity в

@Override 
public void onResume() { 
    super.onResume(); 
    try{ 
     mCamera = openFrontFacingCameraGingerbread(); 
     // Add to Framelayout 
     this.mCameraPreview = new CameraPreview(this, this.mCamera); 
     mImage.removeAllViews(); 
     this.mImage.addView(this.mCameraPreview); 

    }catch (RuntimeException ex){ 

    } 



} 


@Override 
public void onPause() { 
    super.onPause(); 
    captureButton.setText("Begin Capture"); 
    if(CameraActivity.this.timer !=null) { 
     CameraActivity.this.timer.cancel(); 
     CameraActivity.this.timer.purge(); 
     CameraActivity.this.timer = null; 
    } 
    if (mCamera != null) { 
     mCamera.setPreviewCallback(null); 
     mCameraPreview.getHolder().removeCallback(mCameraPreview); 
     mCamera.release(); 
     mCamera = null; 
    } 


} 


@Override 
protected void onDestroy(){ 
    super.onDestroy(); 
    releaseCameraAndPreview(); 
} 

private void releaseCameraAndPreview() { 

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

 Смежные вопросы

  • Нет связанных вопросов^_^