2013-02-02 41 views
0

我對Android中的相機功能沒有多少經驗。我需要通過我計劃發送回服務器的代碼拍照。我基於我的邏輯關閉this後,它運作良好,只要我不添加mCamera.takePicture(null, null, mPictureCallback);到surfaceChange方法的末尾(這是我想要的)。當我添加該行時,它有時會起作用,但大多數情況下,我只是回到黑屏。這是主要問題。我不認爲與設備存在兼容性問題,因爲我的功能提前至少提供了3-4倍的功能。Android:以編程方式拍照不起作用

我的設備,我測試的是Galaxy Nexus的

public class CameraView extends Activity implements SurfaceHolder.Callback, OnClickListener 
{ 
    private static final String TAG = "CameraTest"; 
    Camera mCamera; 
    boolean mPreviewRunning = false; 

    public void onCreate(Bundle icicle) 
    { 
     super.onCreate(icicle); 
     Log.e(TAG, "onCreate"); 

     getWindow().setFormat(PixelFormat.TRANSLUCENT); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     setContentView(R.layout.activity_camera_view); 
     mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera); 
     mSurfaceView.setOnClickListener(this); 
     mSurfaceHolder = mSurfaceView.getHolder(); 
     mSurfaceHolder.addCallback(this); 
     mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    @Override 
    protected void onRestoreInstanceState(Bundle savedInstanceState) 
    { 
     super.onRestoreInstanceState(savedInstanceState); 
    } 


    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { 

     @Override 
     public void onPictureTaken(byte[] data, Camera camera) { 
      // TODO Auto-generated method stub 
      if (data != null) 
      { 
       //Intent mIntent = new Intent(); 
       //mIntent.putExtra("image",imageData); 

       mCamera.stopPreview(); 
       mPreviewRunning = false; 
       mCamera.release(); 


       try 
        { 
        BitmapFactory.Options opts = new BitmapFactory.Options(); 
        Bitmap bitmap= BitmapFactory.decodeByteArray(data, 0, data.length,opts); 
        bitmap = Bitmap.createScaledBitmap(bitmap, 480, 480, false); 
        CameraProjectActivity.image.setImageBitmap(bitmap); 
        } 
        catch(Exception e) 
        { 
         e.printStackTrace(); 
        } 
       //StoreByteImage(mContext, imageData, 50,"ImageName"); 
       //setResult(FOTO_MODE, mIntent); 
       setResult(585); 
       finish(); 
      }  
     } 
    }; 




    protected void onResume() 
    { 
     Log.e(TAG, "onResume"); 
     super.onResume(); 
    } 

    protected void onSaveInstanceState(Bundle outState) 
    { 
     super.onSaveInstanceState(outState); 
    } 

    protected void onStop() 
    { 
     Log.e(TAG, "onStop"); 
     super.onStop(); 
    } 

    public void surfaceCreated(SurfaceHolder holder) 
    { 
     Log.e(TAG, "surfaceCreated"); 
     mCamera = Camera.open(); 
     mCamera.setDisplayOrientation(90); 

    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     Log.e(TAG, "surfaceChanged"); 

     // XXX stopPreview() will crash if preview is not running 
     if (mPreviewRunning) 
     { 
      mCamera.stopPreview(); 
     } 

     Camera.Parameters p = mCamera.getParameters(); 

     List<Camera.Size> previewSizes = p.getSupportedPreviewSizes(); 

     Camera.Size previewSize = previewSizes.get(3); 
     p.setPreviewSize(previewSize.width, previewSize.height); 


     mCamera.setParameters(p); 
     try 
     { 
      mCamera.setPreviewDisplay(holder); 
     } 
     catch (Exception e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     mCamera.startPreview(); 
     mPreviewRunning = true; 

    // THIS IS THE CODE THAT BREAKS IT. IS THERE ANY OTHER WAY TO DO THIS??? ******** 
    // mCamera.takePicture(null, null, mPictureCallback); 


    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     Log.e(TAG, "surfaceDestroyed"); 
//  mCamera.stopPreview(); 
//  mPreviewRunning = false; 
//  mCamera.release(); 
    } 

    private SurfaceView mSurfaceView; 
    private SurfaceHolder mSurfaceHolder; 

    @Override 
    public void onClick(View v) { 
     // TODO Auto-generated method stub 
     mCamera.takePicture(null, mPictureCallback, mPictureCallback); 
    } 
} 

任何幫助,將不勝感激。 謝謝!

回答

2

我不確定這是否是一個好的解決方案,但我只是通過使surfaceChanged()方法同步並使線程在我調用takePicture之前等待一秒來修復它。

try { 
    this.wait(1000); 
    mCamera.takePicture(null, null, mPictureCallback); 
} catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
0

我相信,建議setPreviewDisplay()之前調用startPreview(),但這不應該作出重大的區別。

您所看到的是相機初始化需要時間,並且在準備就緒之前它無法拍攝照片。最好使用攝像頭的回調來決定是否準備好,而不是等待任意1000毫秒。

您可以使用的回調是Camera.PreviewCallback。您可以在您的CameraView類中實現它。要觸發回調,只需添加setOneShotPreviewCallback(this)CameraView.surfaceChanged()

mCamera.startPreview(); 
mCamera.setPreviewDisplay(holder); 
mCamera.setOneShotPreviewCallback(this); 
相關問題