2012-12-13 125 views
2

我想手動捕捉照片,而不是使用現有的相機應用程序。所以我做了這個活動安卓相機預覽空白屏幕

public class CameraActivity extends Activity { 

    private Camera mCamera; 
    private Preview mPreview; 

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


     // Create an instance of Camera 
     mCamera = Camera.open(0); if(mCamera !=null) Log.i("CameraActivity.onCreate()", "mCamera initialized"); 

     // Create our Preview view and set it as the content of our activity. 
     mPreview = new Preview(this); if(mPreview !=null) Log.i("CameraActivity.onCreate()", "mPreview initialized"); 

     FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 

     preview.addView(mPreview); Log.i("CameraActivity.onCreate()", "mPreview added to FrameLayout"); 

     mPreview.setCamera(mCamera); Log.i("CameraActivity.onCreate()", "mPreview.setCamera(mCamera)"); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.activity_camera, menu); 
     return true; 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     mPreview.stopPreviewAndFreeCamera(); 
    } 

} 

這就是我想用CameraPreview:

public class Preview extends ViewGroup implements SurfaceHolder.Callback { 

    SurfaceView mSurfaceView; 
    SurfaceHolder mHolder; 

    private Camera mCamera; 
    List<Size> mSupportedPreviewSizes; 

    /** 
    * @param context 
    */ 
    public Preview(Context context) { 
     super(context); 

     mSurfaceView = new SurfaceView(context); Log.i("CameraPreview.constructor(...)", "mSurfaceView initialized"); 
     if(mSurfaceView==null) {Log.i("CameraPreview.constructor(...)", "mSurfaceView is null");} 
     addView(mSurfaceView); 

     // Install a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and destroyed. 
     mHolder = mSurfaceView.getHolder(); Log.i("CameraPreview.constructor(...)", "mHolder setup"); 
     if(mHolder==null) {Log.e("PreviewCamera", "mHolder is null");} 

     mHolder.addCallback(this); 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    /** 
    * @param context 
    * @param attrs 
    */ 
    public Preview(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     // TODO Auto-generated constructor stub 
    } 

    /** 
    * @param context 
    * @param attrs 
    * @param defStyle 
    */ 
    public Preview(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     // TODO Auto-generated constructor stub 
    } 

    /* (non-Javadoc) 
    * @see android.view.ViewGroup#onLayout(boolean, int, int, int, int) 
    */ 
    @Override 
    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 
     // Now that the size is known, set up the camera parameters and begin 
     // the preview. 
     Camera.Parameters parameters = mCamera.getParameters(); 
     parameters.setPreviewSize(width, height); 
     requestLayout(); 
     mCamera.setParameters(parameters); 

     /* 
      Important: Call startPreview() to start updating the preview surface. Preview must be 
      started before you can take a picture. 
     */ 
     mCamera.startPreview(); Log.i("CameraPreview.surfaceChanged(...)", "mCamera.startPreview()"); 

    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     // Surface will be destroyed when we return, so stop the preview. 
     if (mCamera != null) { 
      /* 
       Call stopPreview() to stop updating the preview surface. 
      */ 
      mCamera.stopPreview(); Log.i("CameraPreview.surfaceDestroyed(...)", "mCamera.stopPreview()"); 
     } 

    } 



    /** 
     * When this function returns, mCamera will be null. 
     */ 
    public void stopPreviewAndFreeCamera() { 

     if (mCamera != null) { 
      /* 
       Call stopPreview() to stop updating the preview surface. 
      */ 
      mCamera.stopPreview(); Log.i("CameraPreview.stopPreviewAndFreeCamera()", "mCamera.stopPreview()"); 

      /* 
       Important: Call release() to release the camera for use by other applications. 
       Applications should release the camera immediately in onPause() (and re-open() it in 
       onResume()). 
      */ 
      mCamera.release(); Log.i("CameraPreview.stopPreviewAndFreeCamera()", "mCamera.release()"); 

      mCamera = null; 
     } 
    } 


    /*** 
    * 
    * @param camera 
    */ 
    public void setCamera(Camera camera) { 
     if (mCamera == camera) { Log.i("CameraPreview.setCamera()", "mCamera equals the Camera you want to set"); return; } 

     stopPreviewAndFreeCamera(); Log.i("CameraPreview.setCamera()", "stopPreviewAndFreeCamera()"); 

     mCamera = camera; Log.i("CameraPreview.setCamera()", "setup new Camera"); 

     if (mCamera != null) { 
      List<Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
      mSupportedPreviewSizes = localSizes; 
      requestLayout(); 

      try { 
       mCamera.setPreviewDisplay(mHolder); 
       Log.i("CameraPreview.setCamera()", "mCamera.setPreviewDisplay(mHolder)"); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

      /* 
       Important: Call startPreview() to start updating the preview surface. Preview must 
       be started before you can take a picture. 
       */ 
      mCamera.startPreview(); Log.i("CameraPreview.setCamera()", "mCamera.startPreview()"); 
     } 
    } 


    /*** 
    * 
    * @param id 
    * @return 
    */ 
    public boolean safeCameraOpen(int id) { 
     boolean qOpened = false; 

     try { 
      releaseCameraAndPreview(); 
      mCamera = Camera.open(id); 

      qOpened = (mCamera != null); 
     } catch (Exception e) { 
      // Log.e(R.string.app_name, "failed to open Camera"); 
      e.printStackTrace(); 
     } 

     return qOpened;  
    } 

    /** 
    * 
    */ 
    Camera.PictureCallback mPicCallback = new Camera.PictureCallback() { 

     @Override 
     public void onPictureTaken(byte[] data, Camera camera) { 
      // TODO Auto-generated method stub 
      Log.d("lala", "pic is taken"); 
     } 
    }; 

    /** 
    * 
    */ 
    public void takePic() { 

    // mCamera.takePicture(null, mPicCallback, mPicCallback); 

    } 
    /** 
    * 
    */ 
    private void releaseCameraAndPreview() { 
     this.setCamera(null); 
     if (mCamera != null) { 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 

} 

這是CameraActivity的佈局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context=".CameraActivity" > 


    <FrameLayout 
    android:id="@+id/camera_preview" 
    android:layout_width="0dip" 
    android:layout_height="fill_parent" 
    android:layout_weight="1" 
    /> 

    <Button 
    android:id="@+id/button_capture" 
    android:text="Capture" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    /> 


</LinearLayout> 

但我當啓動CameraActivity,我只看到一個空白的白色背景和Capture-Button?爲什麼我看不到相機屏幕?

編輯:logcat的:

12-16 13:09:39.941: I/CameraActivity.onCreate()(439): mCamera initialized 
12-16 13:09:39.941: I/CameraPreview.constructor(...)(439): mSurfaceView initialized 
12-16 13:09:39.941: I/CameraPreview.constructor(...)(439): mHolder setup 
12-16 13:09:39.941: I/CameraActivity.onCreate()(439): mPreview initialized 
12-16 13:09:39.952: I/CameraActivity.onCreate()(439): mPreview added to FrameLayout 
12-16 13:09:39.952: I/CameraPreview.setCamera()(439): stopPreviewAndFreeCamera() 
12-16 13:09:39.952: I/CameraPreview.setCamera()(439): setup new Camera 
12-16 13:09:39.961: D/Camera(439): app passed NULL surface 
12-16 13:09:39.961: I/CameraPreview.setCamera()(439): mCamera.setPreviewDisplay(mHolder) 
12-16 13:09:39.971: I/CameraPreview.setCamera()(439): mCamera.startPreview() 
12-16 13:09:39.971: I/CameraActivity.onCreate()(439): mPreview.setCamera(mCamera) 
12-16 13:09:40.622: I/ActivityManager(60): Displayed com.example.popup/.CameraActivity: +810ms 

回答

0

你是不是調用帶有攝像頭(只空)setCamera,所以你永遠不會設置預覽顯示。

+0

是的,但我使用的方法safeCameraOpen()。然而,我編輯我的活動在顯着 – user1104836

+0

啊,但safeCameraOpen不會調用mCamera.setPreviewDisplay(mHolder),並且您已經設置mCamera setCamera()將不做任何事情返回。確保你打電話給mCamera.setPreviewDisplay(mHolder); android.util.Log是你的朋友 –

+0

好吧你是對的。當我打電話preview.setCamera(凸輪)得到的消息:應用程序傳遞NULL表面。但我之前設置了表面和持有人,所以我不知道爲什麼 – user1104836

2

我想你應該在addView()之後撥打open()方法。
相機預覽尺寸由addView()設置。

+0

U意思是camera.open()?我已經在方法中使用safeCameraOpen() – user1104836

+0

現在我編輯我的CameraActivity通過使用方法setCamera() – user1104836

0

我有同樣的問題。然後我將它擴展到SurfaceView而不是ViewGroup。並在一個神奇的時刻...

0

您可以檢查預覽的layout_width和layout_height屬性是否設置爲match_parent。