android camera2 api - onImageAvailable在session.capture之后不会被调用
我想用摄像头api2来捕捉图像。该代码在MOTO g4上运行良好,但是当我在NEXUS 6上测试代码时,onImageAvailable在session.capture之后未被调用,并且没有保存图像。真的很沮丧,非常感谢,如果有人可以帮助!非常感谢。android camera2 api - onImageAvailable在session.capture之后不会被调用
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurfaces = new ArrayList<Surface>(2);
outputSurfaces.add(reader.getSurface());
outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// Orientation
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
sendUri = getImageUri();
final File file = new File(Environment.getExternalStorageDirectory()+"/" + sendUri +".jpg");
ImageReader.OnImageAvailableListener 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 {
OutputStream output = null;
try {
output = new FileOutputStream(file);
output.write(bytes);
} finally {
if (null != output) {
output.close();
}
}
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
//Toast.makeText(MainActivity.this, "Saved:" + file, Toast.LENGTH_SHORT).show();
toast1("Saved:"+file);
//createCameraPreview();
}
};
cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
下面是承上启下6输出的完整的logcat运行相机功能时,似乎没有什么用处...
03-07 13:04:34.526 1838-1838/examples.hello E/AndroidCameraApi: is camera open
03-07 13:04:34.527 1838-1838/examples.hello I/CameraManagerGlobal: Connecting to camera service
03-07 13:04:34.659 1838-1838/examples.hello E/AndroidCameraApi: openCamera X
03-07 13:04:34.694 1838-1838/examples.hello E/AndroidCameraApi: onOpened
03-07 13:04:34.722 1838-1883/examples.hello D/OpenGLRenderer: endAllActiveAnimators on 0x931bee80 (RippleDrawable) with handle 0x92c2cea0
03-07 13:04:43.952 1838-1838/examples.hello E/AndroidCameraApi: onPause
这将会是,如果你提供从发生故障的设备全输出logcat的有益,但我怀疑的问题是这样的:
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
你创建本地ImageReader对象,而不是将其保存为进一步使用。你从它得到一个Surface,但是Surface很像一个弱指针;如果没有引用它,它将不会使ImageReader获取GC'd(请参阅note in the developer references)
所以我怀疑如果您只是创建一个类成员mReader变量并将读取器存储在其中,那么一切都会正常工作。
由于GC算法的不同,它可能在Moto手机上工作;运行时尚未完全清除读者对象,因此有时间调用回调函数。
非常感谢!你能更具体地告诉我吗? – song
1)添加一个'私人ImageReader mReader'给你的班级。 2)将阅读器保存到mReader中 –
谢谢!我正在使用的nexus 6正在运行android版本7.0。我认为它应该能够支持camera2 api。 – song
我认为android.camera2 API会受到指责。复合这个问题的事实是这个API不支持低于21的任何API级别。许多摄像头应用程序仍然使用弃用的Camera API。 –