2013-10-07 6 views
0

Я пытаюсь сделать приложение для камеры на Android, никаких ошибок в Log-cat, но приложение не закрывается, когда я нажимаю кнопку «Назад»; и если я хочу открыть другую камеру приложения после ее остановки; камера заблокирована! любой намек или идеи? Спасибо заранее.Предварительный просмотр камеры на Android

public class Capture extends Activity { 
    private Camera mCamera; 
    private ViewCamera mPreview; 
    public static final int MEDIA_TYPE_IMAGE = 1; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.camera); 
     releaseCamera(); 
     // Create an instance of Camera 
     mCamera = getCameraInstance(); 
     Log.d("EyeSeeJD", "getCameraInstance"); 

     // Create our Preview view and set it as the content of our activity. 
     mPreview = new ViewCamera(this, mCamera); 
     FrameLayout preview = (FrameLayout) findViewById(R.id.frame); 
     Log.d("EyeSeeJD", "addview "); 

     preview.addView(mPreview); 
    } 

    /** A safe way to get an instance of the Camera object. */ 
    public static Camera getCameraInstance() { 
     Camera c = null; 
     try { 
      c = Camera.open(); // attempt to get a Camera instance 
      // c.lock(); 
     } catch (Exception e) { 
      // Camera is not available (in use or does not exist) 
      Log.d("EyeSeeJD", "can't open camera "); 

     } 
     return c; // returns null if camera is unavailable 
    } 

    /** Create a File for saving an image or video */ 
    private static File getOutputMediaFile(int type) { 
     // To be safe, you should check that the SDCard is mounted 
     // using Environment.getExternalStorageState() before doing this. 

     File mediaStorageDir = new File(
       Environment 
         .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), 
       "MyCameraApp"); 
     // This location works best if you want the created images to be shared 
     // between applications and persist after your app has been uninstalled. 

     // Create the storage directory if it does not exist 
     if (!mediaStorageDir.exists()) { 
      if (!mediaStorageDir.mkdirs()) { 
       Log.d("MyCameraApp", "failed to create directory"); 
       return null; 
      } 
     } 
     // Create a media file name 
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss") 
       .format(new Date()); 
     File mediaFile; 
     if (type == MEDIA_TYPE_IMAGE) { 
      mediaFile = new File(mediaStorageDir.getPath() + File.separator 
        + "IMG_" + timeStamp + ".jpg"); 
     } else { 
      return null; 
     } 

     return mediaFile; 
    } 

    private PictureCallback mPicture = new PictureCallback() { 

     @Override 
     public void onPictureTaken(byte[] data, Camera camera) { 

      File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); 
      if (pictureFile == null) { 
       Log.d("EyeSeeJD", 
         "Error creating media file, check storage permissions "); 
       return; 
      } 

      try { 

       FileOutputStream fos = new FileOutputStream(pictureFile); 
       fos.write(data); 
       fos.close(); 
      } catch (FileNotFoundException e) { 
       Log.d("EyeSeeJD", "File not found: " + e.getMessage()); 
      } catch (IOException e) { 
       Log.d("EyeSeeJD", "Error accessing file: " + e.getMessage()); 
      } 
     } 

    }; 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     /* 
     * if (mCamera == null) { releaseCamera(); // release the camera 
     * immediately on pause event System.exit(0); } 
     */ 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     releaseCamera(); // release the camera immediately on pause event 
     // System.exit(0); 
    } 

    private void releaseCamera() { 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
      mCamera.setPreviewCallback(null); 
      mPreview.getHolder().removeCallback(mPreview); 
      // mCamera.unlock(); 
      mCamera.release(); // release the camera for other applications 
      mCamera = null; 

     } 
    } 

    @Override 
    public void onBackPressed() { // TODO Auto-generated methodstub 
     super.onBackPressed(); 
     //mCamera.setPreviewCallback(null); 
     //mPreview.getHolder().removeCallback(mPreview); 
     mCamera.stopPreview(); 
     mCamera.release(); // release the camera for other applications 
     mCamera = null; 
     finish(); 
     System.exit(0); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     // TODO Auto-generated method stub 
     //mCamera.setPreviewCallback(null); 
     mCamera.takePicture(null, null, mPicture); 
     //mCamera.release(); 
    // mCamera.startPreview(); 
     return super.onTouchEvent(event); 
    } 

    @Override 
    protected void onDestroy() { 
     // TODO Auto-generated method stub 
     super.onDestroy(); 
     mCamera.stopPreview(); 
     mCamera.setPreviewCallback(null); 
     mPreview.getHolder().removeCallback(mPreview); 
     mCamera.release(); // release the camera for other applications 
     mCamera = null; 
     finish(); 
     System.exit(0); 
    } 

} 

ViewCamera.java

public class ViewCamera extends SurfaceView implements SurfaceHolder.Callback { 
private SurfaceHolder mHolder = null; 
private Camera mCamera = null; 

public ViewCamera(Context context, Camera camera) { 
    super(context); 
    mCamera = camera; 
    // Install a SurfaceHolder.Callback so we get notified when the 
    // underlying surface is created and destroyed. 
    mHolder = getHolder(); 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    // TODO Auto-generated method stub 
    // The Surface has been created, now tell the camera where to draw the 
    // preview. 
    try { 

     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     Log.d("EyeSeeJD", "Error setting camera preview: " + e.getMessage()); 
    } 
} 

// check if device has camera 
private boolean checkCameraHardware(Context context) { 
    if (context.getPackageManager().hasSystemFeature(
      PackageManager.FEATURE_CAMERA)) { 
     // this device has a camera 
     Log.d("EyeSeeJd", "there is a camera "); 

     return true; 
    } else { 
     // no camera on this device 
     Log.d("EyeSeeJd", "there is no camera "); 

     return false; 
    } 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    // TODO Auto-generated method stub 
    // 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 
    } 

    // set preview size and make any resize, rotate or 
    // reformatting changes here 
    /*Camera.Parameters parameters = mCamera.getParameters(); 
    parameters.setPreviewSize(320, 480); 
    mCamera.setParameters(parameters);*/ 
    // start preview with new settings 
    try { 

     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 
     // mCamera.unlock(); 
    } catch (Exception e) { 
     Log.d("EyeSeeJd", 
       "Error starting camera preview: " + e.getMessage()); 
    } 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder arg0) { 
    // TODO Auto-generated method stub 
    // empty. Take care of releasing the Camera preview in your activity. 

    this.getHolder().removeCallback(this); 
    mCamera.stopPreview(); 
    mCamera.release(); 
    mCamera = null; 
} 

}

ответ

0

Трудно сказать, что на самом деле происходит без соблюдения кода в отладчике, но есть шанс, что вы называете Camera.release() слишком много раз. Там может быть NullPointerExeception где-то, что предотвращает нормальное выключение. В вашем приложении должен быть только один выпуск, а onPause() - идеальное место для звонка releaseCamera(). Я не понимаю, почему вам нужно переопределить onBackPressed() вообще, вызывать finish() от этого переопределения не рекомендуется, и еще более называть System.exit(). Кроме того, я переместил бы вызов на getCameraInstance() на onResume() или, возможно, на onStart().

0

Причина, по которой ваше приложение требует времени, чтобы закрыть, когда вы нажимаете назад, является то, что ваше приложение рушится, потому что в методе onBackPressed() вы устанавливаете mCamera в null и в onDestroy() вы используете его снова, чтобы остановить и освободить камеру ,

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