Android 相机 takePicture() 失败
Android Camera takePicture() failed
我一直在尝试使用 Android 中的表面预览使用相机拍照。表面预览跨越布局中的整个屏幕。
每当我调用 takePicture 时,它都会失败并提示我没有启用预览。
下面是activity变量、图片方法、相机拍照代码(在onResume()中):
public class FawkesRCActivity extends Activity implements SurfaceHolder.Callback {
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
public Camera mCamera;
...
Camera.PictureCallback camHolla = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
String photoFile = "F_Auton.jpg";
File sdDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String filename =sdDir + File.separator + photoFile;
File pictureFile = new File(filename);
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (Exception e) {
Log.d("Errored:", e.getMessage());
}
}
};
public void setCamera(Camera camera) {
if (mCamera == camera) { return; }
stopPreviewAndFreeCamera();
mCamera = camera;
if (mCamera != null) {
List<Camera.Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
// Important: Call startPreview() to start updating the preview
// surface. Preview must be started before you can take a picture.
mCamera.startPreview();
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
mCamera.startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
// Call stopPreview() to stop updating the preview surface.
mCamera.stopPreview();
}
}
/**
* When this function returns, mCamera will be null.
*/
private void stopPreviewAndFreeCamera() {
if (mCamera != null) {
// Call stopPreview() to stop updating the preview surface.
mCamera.stopPreview();
// Important: Call release() to release the camera for use by other
// applications. Applications should release the camera immediately
// during onPause() and re-open() it during onResume()).
mCamera.release();
mCamera = null;
}
}
@Override
protected void onResume() {
FawkesRCActivity.this.runOnUiThread(new Runnable() {
public void run() {
mSurfaceView = (SurfaceView) findViewById(R.id.cameraPreview);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(FawkesRCActivity.this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
int camId=0;
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
camId=i;
}
}
if (safeCameraOpen(camId))Log.e("Camera","All Good"); else Log.e("Camera","Errored");
try{
SurfaceTexture surfaceTexture = new SurfaceTexture(0);
mCamera.setPreviewTexture(surfaceTexture);
// mCamera.startPreview();
}
catch(Exception e){
e.printStackTrace();
}
try {
mCamera.takePicture(null, null, null, camHolla);
}
catch(Exception e){
e.printStackTrace();
}
}
});
super.onResume();
}
private boolean safeCameraOpen(int id) {
boolean qOpened = false;
try {
releaseCameraAndPreview();
mCamera = Camera.open(id);
qOpened = (mCamera != null);
} catch (Exception e) {
Log.e(getString(R.string.app_name), "failed to open Camera");
e.printStackTrace();
}
return qOpened;
}
private void releaseCameraAndPreview() {
setCamera(null);
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
这是错误:
12-31 20:00:15.407 3244-5501/? E/Camera2Client﹕ takePicture: Camera 0: Cannot take picture without preview enabled
12-31 20:00:15.408 6988-6988/? W/System.err﹕ java.lang.RuntimeException: takePicture failed
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.hardware.Camera.native_takePicture(Native Method)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.hardware.Camera.takePicture(Camera.java:1434)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at org.fawkes.fawkesrc.FawkesRCActivity.run(FawkesRCActivity.java:327)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.Activity.runOnUiThread(Activity.java:5524)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at org.fawkes.fawkesrc.FawkesRCActivity.onResume(FawkesRCActivity.java:298)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.Activity.performResume(Activity.java:6327)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.ActivityThread.-wrap11(ActivityThread.java)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at android.os.Looper.loop(Looper.java:148)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5417)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
在论坛上搜索了几个小时后,我完全迷路了,如有任何帮助,我们将不胜感激。
我不是专家,但我认为你在拍照之前没有打电话给 mCamera.startPreview()
。您可以尝试在此之前调用它。
你可以看看这个CameraFragment Sample作为启动相机预览等的参考。
相机操作不是即时的,而且通常不是同步的。某些设备需要在 startPreview() 和 takePicture() 之间有明显的延迟,例如在 OnePlus One 上你至少需要 100ms。
对您的代码的最小修复可能是
try{
SurfaceTexture surfaceTexture = new SurfaceTexture(0);
mCamera.setPreviewTexture(surfaceTexture);
// mCamera.startPreview();
}
catch(Exception e){
e.printStackTrace();
}
mSurfaceView.postDelayed(new Runnable() {
@Override
public void run() {
try {
mCamera.takePicture(null, null, null, camHolla);
}
catch(Exception e){
e.printStackTrace();
}
}, 100);
super.onResume();
我一直在尝试使用 Android 中的表面预览使用相机拍照。表面预览跨越布局中的整个屏幕。
每当我调用 takePicture 时,它都会失败并提示我没有启用预览。
下面是activity变量、图片方法、相机拍照代码(在onResume()中):
public class FawkesRCActivity extends Activity implements SurfaceHolder.Callback {
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
public Camera mCamera;
...
Camera.PictureCallback camHolla = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
String photoFile = "F_Auton.jpg";
File sdDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String filename =sdDir + File.separator + photoFile;
File pictureFile = new File(filename);
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (Exception e) {
Log.d("Errored:", e.getMessage());
}
}
};
public void setCamera(Camera camera) {
if (mCamera == camera) { return; }
stopPreviewAndFreeCamera();
mCamera = camera;
if (mCamera != null) {
List<Camera.Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
// Important: Call startPreview() to start updating the preview
// surface. Preview must be started before you can take a picture.
mCamera.startPreview();
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
mCamera.startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
// Call stopPreview() to stop updating the preview surface.
mCamera.stopPreview();
}
}
/**
* When this function returns, mCamera will be null.
*/
private void stopPreviewAndFreeCamera() {
if (mCamera != null) {
// Call stopPreview() to stop updating the preview surface.
mCamera.stopPreview();
// Important: Call release() to release the camera for use by other
// applications. Applications should release the camera immediately
// during onPause() and re-open() it during onResume()).
mCamera.release();
mCamera = null;
}
}
@Override
protected void onResume() {
FawkesRCActivity.this.runOnUiThread(new Runnable() {
public void run() {
mSurfaceView = (SurfaceView) findViewById(R.id.cameraPreview);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(FawkesRCActivity.this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
int camId=0;
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
camId=i;
}
}
if (safeCameraOpen(camId))Log.e("Camera","All Good"); else Log.e("Camera","Errored");
try{
SurfaceTexture surfaceTexture = new SurfaceTexture(0);
mCamera.setPreviewTexture(surfaceTexture);
// mCamera.startPreview();
}
catch(Exception e){
e.printStackTrace();
}
try {
mCamera.takePicture(null, null, null, camHolla);
}
catch(Exception e){
e.printStackTrace();
}
}
});
super.onResume();
}
private boolean safeCameraOpen(int id) {
boolean qOpened = false;
try {
releaseCameraAndPreview();
mCamera = Camera.open(id);
qOpened = (mCamera != null);
} catch (Exception e) {
Log.e(getString(R.string.app_name), "failed to open Camera");
e.printStackTrace();
}
return qOpened;
}
private void releaseCameraAndPreview() {
setCamera(null);
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
这是错误:
12-31 20:00:15.407 3244-5501/? E/Camera2Client﹕ takePicture: Camera 0: Cannot take picture without preview enabled
12-31 20:00:15.408 6988-6988/? W/System.err﹕ java.lang.RuntimeException: takePicture failed
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.hardware.Camera.native_takePicture(Native Method)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.hardware.Camera.takePicture(Camera.java:1434)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at org.fawkes.fawkesrc.FawkesRCActivity.run(FawkesRCActivity.java:327)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.Activity.runOnUiThread(Activity.java:5524)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at org.fawkes.fawkesrc.FawkesRCActivity.onResume(FawkesRCActivity.java:298)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.Activity.performResume(Activity.java:6327)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.ActivityThread.-wrap11(ActivityThread.java)
12-31 20:00:15.408 6988-6988/? W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at android.os.Looper.loop(Looper.java:148)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5417)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
12-31 20:00:15.409 6988-6988/? W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
在论坛上搜索了几个小时后,我完全迷路了,如有任何帮助,我们将不胜感激。
我不是专家,但我认为你在拍照之前没有打电话给 mCamera.startPreview()
。您可以尝试在此之前调用它。
你可以看看这个CameraFragment Sample作为启动相机预览等的参考。
相机操作不是即时的,而且通常不是同步的。某些设备需要在 startPreview() 和 takePicture() 之间有明显的延迟,例如在 OnePlus One 上你至少需要 100ms。
对您的代码的最小修复可能是
try{
SurfaceTexture surfaceTexture = new SurfaceTexture(0);
mCamera.setPreviewTexture(surfaceTexture);
// mCamera.startPreview();
}
catch(Exception e){
e.printStackTrace();
}
mSurfaceView.postDelayed(new Runnable() {
@Override
public void run() {
try {
mCamera.takePicture(null, null, null, camHolla);
}
catch(Exception e){
e.printStackTrace();
}
}, 100);
super.onResume();