在android中使用surfaceview在app中使用相机

我正在创建一个应用程序,我可以在其中使用相机,而无需使用手机的默认应用程序。所以我使用了表面视图并尝试将其保存到手机上,但onPictureTaken永远不会被调用。完整的代码是如下所示:

 package com.example.surfaceviewcamera; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.hardware.Camera; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.content.ContextWrapper; import android.view.Menu; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity implements SurfaceHolder.Callback { SurfaceView mSurfaceView; SurfaceHolder mSurfaceHolder; Camera mCamera; boolean mPreviewRunning; Button btncapture; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btncapture=(Button) findViewById(R.id.btncapture); mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(this); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); btncapture.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { public void onPictureTaken(byte[] imageData, Camera c) { Bitmap bitmap = BitmapFactory.decodeByteArray(imageData , 0, imageData .length); String file_path=saveToInternalSorage(bitmap); Toast.makeText(getApplicationContext(),"Image stored succesfully at "+file_path,Toast.LENGTH_LONG).show(); } }; } }); } private String saveToInternalSorage(Bitmap bitmapImage){ ContextWrapper cw = new ContextWrapper(getApplicationContext()); // path to /data/data/yourapp/app_data/imageDir File directory = cw.getDir("imageDir", Context.MODE_PRIVATE); // Create imageDir File mypath=new File(directory,"marina1.jpg"); FileOutputStream fos = null; try { fos = new FileOutputStream(mypath); // Use the compress method on the BitMap object to write image to the OutputStream bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos); fos.close(); } catch (Exception e) { e.printStackTrace(); } return directory.getAbsolutePath(); } @Override public void surfaceCreated(SurfaceHolder holder) { mCamera=Camera.open(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { if (mPreviewRunning) { mCamera.stopPreview(); } Camera.Parameters p = mCamera.getParameters(); p.setPreviewSize(w, h); mCamera.setParameters(p); try { mCamera.setPreviewDisplay(holder); } catch (IOException e) { e.printStackTrace(); } mCamera.startPreview(); mPreviewRunning = true; } @Override public void surfaceDestroyed(SurfaceHolder holder) { mCamera.stopPreview(); mPreviewRunning = false; mCamera.release(); } } 

我的XML文件:

    

call camera.takePicture(null, null, callback); 来自onClick()并定义onCreate()之外的回调

供参考,请看这个链接

 public class MainActivity extends Activity implements SurfaceHolder.Callback { SurfaceView mSurfaceView; SurfaceHolder mSurfaceHolder; Camera mCamera; boolean mPreviewRunning; Button btncapture; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btncapture=(Button) findViewById(R.id.btncapture); mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(this); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); btncapture.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //take picture here mCamera.takePicture(null, null, mPictureCallback); } }); } Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { public void onPictureTaken(byte[] imageData, Camera c) { Bitmap bitmap = BitmapFactory.decodeByteArray(imageData , 0, imageData .length); String file_path=saveToInternalSorage(bitmap); Toast.makeText(getApplicationContext(),"Image stored succesfully at "+file_path,Toast.LENGTH_LONG).show(); } }; private String saveToInternalSorage(Bitmap bitmapImage){ ContextWrapper cw = new ContextWrapper(getApplicationContext()); // path to /data/data/yourapp/app_data/imageDir File directory = cw.getDir("imageDir", Context.MODE_PRIVATE); // Create imageDir File mypath=new File(directory,"marina1.jpg"); FileOutputStream fos = null; try { fos = new FileOutputStream(mypath); // Use the compress method on the BitMap object to write image to the OutputStream bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos); fos.close(); } catch (Exception e) { e.printStackTrace(); } return directory.getAbsolutePath(); } @Override public void surfaceCreated(SurfaceHolder holder) { mCamera=Camera.open(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { if (mPreviewRunning) { mCamera.stopPreview(); } Camera.Parameters p = mCamera.getParameters(); p.setPreviewSize(w, h); mCamera.setParameters(p); try { mCamera.setPreviewDisplay(holder); } catch (IOException e) { e.printStackTrace(); } mCamera.startPreview(); mPreviewRunning = true; } @Override public void surfaceDestroyed(SurfaceHolder holder) { mCamera.stopPreview(); mPreviewRunning = false; mCamera.release(); } }