2013-02-02 125 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); 
相关问题