我正在使用新的相机api开发Android应用程序我试图按顺序捕获多个图像我想要做的是在一秒钟内捕获多个图像但它只输出两个图像并停止 这是我的代码:
import android.app.Activity;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.ExifInterface;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class CameraActivity extends Activity {
private final static String TAG = "CameraStress";
private android.util.Size mPreviewSize;
private TextureView mTextureView;
private CameraDevice mCameraDevice;
private CaptureRequest.Builder mPreviewBuilder;
private CameraCaptureSession mPreviewSession;
private Button ButtonCap;
Timer mTimer = null;
// Handler handler;
static int count = 0;
Handler handler = new Handler();
/**
* Conversion from screen rotation to JPEG orientation.
*/
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.fragment_camera2_basic);
Log.e(TAG, "In OnCreate");
mTextureView = (TextureView) findViewById(R.id.texture);
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
ButtonCap = (Button) findViewById(R.id.picture);
ButtonCap.setOnClickListener(onClickPicture); {
Log.e(TAG, "Button Clicked");
takePicture();
}
}
protected void takePicture() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Log.e(TAG, "takePicture");
}
});
if (null == mCameraDevice) {
Log.e(TAG, "mCameraDevice is null, return");
return;
}
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
List<Surface> outputSurfaces;
outputSurfaces = null;
try {
String CameraID = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(CameraID);
StreamConfigurationMap configs = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
android.util.Size[] sizes;
// JPEG format support
sizes = configs.getOutputSizes(ImageFormat.JPEG);
int picWidth = 2592;
int picHeight = 1944;
// We use an ImageReader to get a JPEG from CameraDevice.
// Here, we create a new ImageReader and prepare its Surface as an output from camera.
ImageReader imageReader = ImageReader.newInstance(picWidth, picHeight, ImageFormat.JPEG, 1);
outputSurfaces = new ArrayList<Surface>(2);
outputSurfaces.add(imageReader.getSurface());
outputSurfaces.add(new Surface(mTextureView.getSurfaceTexture()));
Handler backgroundHandler = null;
ImageReader.OnImageAvailableListener readerListener = null;
imageReader.setOnImageAvailableListener(readerListener, backgroundHandler);
// This is the CaptureRequest.Builder that we use to take a picture,CreateCapture request.
final CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
// mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, backgroundHandler);
builder.addTarget(imageReader.getSurface());
// Use the same AE and AF modes as the preview.
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
// Orientation
int rotation = getWindowManager().getDefaultDisplay().getRotation();
builder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
readerListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (image != null) {
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
final File file = new File(getApplicationContext().getExternalFilesDir(null), "count"+n+".jpg");
OutputStream output = null;
try {
output = new FileOutputStream(file);
output.write(bytes);
} finally {
if (null != output) {
output.close();
}
}
try {
ExifInterface exif = new ExifInterface(file.getAbsolutePath());
exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, "10");
exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, "10");
exif.saveAttributes();
} catch (IOException e) {
e.printStackTrace();
}
}
};
// We create a Handler since we want to handle the result JPEG in a background thread
HandlerThread thread = new HandlerThread("Camera Picture");
thread.start();
backgroundHandler = new Handler(thread.getLooper());
imageReader.setOnImageAvailableListener(readerListener, backgroundHandler);
final CameraCaptureSession.CaptureCallback CaptureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
Log.v(TAG, "JPEG Saved");
super.onCaptureCompleted(session, request, result);
Log.v(TAG, "Image Captured Successfully");
// We restart the preview when the capture is completed
startPreview();
}
};
//mCaptureSession.stopRepeating();
//mCaptureSession.capture();
final Handler finalBackgroundHandler = backgroundHandler;
mCameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
mPreviewSession = session;
try {
// session.capture(builder.build(), CaptureCallback, finalBackgroundHandler);
// This is for capturing an image
session.setRepeatingRequest(builder.build(),CaptureCallback,finalBackgroundHandler);
} catch (CameraAccessException e1) {
e1.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume");
}
private void openCamera() {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
Log.e(TAG, "openCamera E");
try {
String cameraId = manager.getCameraIdList()[0];
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];
manager.openCamera(cameraId, mStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
Log.e(TAG, "openCamera X");
}
private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.e(TAG, "onSurfaceTextureAvailable, width=" + width + ",height=" + height);
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface,
int width, int height) {
Log.e(TAG, "onSurfaceTextureSizeChanged");
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
//Log.e(TAG, "onSurfaceTextureUpdated");
}
};
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
Log.e(TAG, "onOpened");
mCameraDevice = camera;
startPreview();
}
@Override
public void onDisconnected(CameraDevice camera) {
Log.e(TAG, "onDisconnected");
}
@Override
public void onError(CameraDevice camera, int error) {
Log.e(TAG, "onError");
}
};
@Override
protected void onPause() {
Log.e(TAG, "onPause");
super.onPause();
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
}
protected void startPreview() {
SurfaceTexture texture = mTextureView.getSurfaceTexture();
if (texture == null) {
Log.e(TAG, "texture is null");
return;
}
// We configure the size of default buffer to be the size of camera preview we want.
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
// This is the output Surface we need to start preview.
Surface surface = new Surface(texture);
Log.e(TAG, "In Start Preview");
try {
// We set up a CaptureRequest.Builder with the output Surface.
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
} catch (CameraAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mPreviewBuilder.addTarget(surface);
// Here, we create a CameraCaptureSession for camera preview.
try {
mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
// TODO Auto-generated method stub
mPreviewSession = session;
updatePreview();
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
// TODO Auto-generated method stub
Toast.makeText(CameraActivity.this, "onConfigureFailed", Toast.LENGTH_LONG).show();
}
}, null);
} catch (CameraAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void updatePreview() {
// TODO Auto-generated method stub
if (null == mCameraDevice) {
Log.e(TAG, "updatePreview error, return");
}
Log.e(TAG, "In Update Preview");
mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
HandlerThread thread = new HandlerThread("Camera Preview");
thread.start();
Handler backgroundHandler = new Handler(thread.getLooper());
// Auto focus should be continuous for camera preview.
// Finally, we start displaying the camera preview.
try {
mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
public View.OnClickListener onClickPicture = new View.OnClickListener() {
public void onClick(View v) {
Log.v(TAG,"In ON click");
takePicture();
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
Thread thread = new Thread() {
@Override
public void run() {
Looper.prepare();
Looper.loop();
takePicture();
}
};
thread.start();
}
},5,2000);
}
};
}