我正在尝试构建一个 android 应用程序来捕获图像并每隔 x 秒自动将它们保存在 SD 卡上。对于 PictureCallback,从 takePicture() 到 onPictureTaken() 的调用从未发生在我身上。
以下是创建对象的活动,它创建相机对象,并且按钮的 onclick 侦听器调用 takePicture()
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
prefs = getSharedPreferences(PREFS, 0);
long timeout = prefs.getLong("TIMEOUT", 5);
if(checkCameraHardware(this)){
mCamera = getCameraInstance();
}
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
// Add a listener to the Capture button
final Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
// get an image from the camera
takePictures.execute(null);
captureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// get an image from the camera
takePictures.cancelPicture();
captureButton.setOnClickListener(null);
}
});
}
});
takePictures = new Picturetask(timeout);
}
protected void resetPreview(){
System.out.println("hello reset");
mCamera.stopPreview();
mPreview = new CameraPreview(this, mCamera);
preview.addView(mPreview);
}
@Override
protected void onPause() {
System.out.println("hello pause");
super.onPause();
takePictures.cancelPicture();
takePictures.cancel(true);
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
@Override
public void onStart() {
System.out.println("hello start");
super.onStart();
registerReceiver(refreshPreview, new IntentFilter(BROADCAST_PREVIEW));
}
protected void releaseMediaRecorder(){
System.out.println("hello release");
if (mMediaRecorder != null) {
mMediaRecorder.reset(); // clear recorder configuration
mMediaRecorder.release(); // release the recorder object
mMediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}
protected void releaseCamera(){
System.out.println("hello camera release");
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
@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_main, menu);
return true;
}
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
System.out.println("hello instance");
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
这是保存捕获图像的逻辑
protected PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
try {
System.out.println("Code never gets called");
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
private class Picturetask extends AsyncTask<String, Void, Boolean> {
private long timeout;
private volatile boolean wait = true;
public Picturetask(long timeout){
System.out.println("hello");
this.timeout = 1000 * timeout;
}
@Override
protected Boolean doInBackground(String... arg0) {
takePicture();
return null;
}
private void takePicture(){
while(wait){
System.out.println("Take picture in loop");
CameraActivity.this.mCamera.takePicture(null, null, mPicture);
Intent i = new Intent(BROADCAST_PREVIEW);
sendBroadcast(i);
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
break;
}
}
}
private BroadcastReceiver refreshPreview = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mPreview.surfaceChanged(null, 0, 0, 0);
}
}
Flow 永远不会到达 onPictureTaken() 方法中的打印语句