所以我的Manifest.xml
是正确的:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus"/>
<application>
...
我还使用此功能在onPause
和onDestroy
功能中释放相机:
private void releaseCamera() {
// stop and release camera
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
//mPreview instance of CameraPreview (referenced below)
if (mPreview != null) {
mPreview.setCamera(null);
}
}
我在mCamera = Camera.open();
期间只拨打onResume
一次。
即使我完成了我在Stack Overflow和其他来源上找到的每个示例所指定的所有内容,Camera.open()
偶尔会失败。
一些用例:
//Bizarre
mCamera.takePicture()
时,活动崩溃并重新加载。 (相机工作)所以我完全被难过......任何想法都会非常感激:D
根据要求,找到以下相关代码:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
// create the surface and start camera preview
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
} catch (IOException e) {
Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void refreshCamera(Camera camera) {
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
setCamera(camera);
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
refreshCamera(mCamera);
}
public void setCamera(Camera camera) {
//method to set a camera instance
mCamera = camera;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
}
}
}
public class CameraActivity extends Activity {
private static final String TAG = "CameraActivity";
private Camera mCamera;
private CameraPreview mPreview;
private Camera.PictureCallback mPicture;
private ImageButton capture;
private Context myContext;
private LinearLayout cameraPreview;
// Required to remove the camera if onPause did not
@Override
public void onDestroy() {
releaseCamera();
super.onDestroy();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_test);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
myContext = this;
initialize();
}
//Code to find the id for the traditional back facing camera
private int findBackFacingCamera() {
int cameraId = -1;
//Search for the back facing camera
//get the number of cameras
int numberOfCameras = Camera.getNumberOfCameras();
//for every camera check
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) {
cameraId = i;
cameraFront = false;
break;
}
}
return cameraId;
}
@Override
public void onResume() {
super.onResume();
//If there is no camera on the device, inform the user.
if (!hasCamera(myContext)) {
Toast toast = Toast.makeText(myContext, "Sorry, your phone does not have a camera!", Toast.LENGTH_LONG);
toast.show();
}
//release the camera if it's in use.
releaseCamera();
if (mCamera == null) {
//if the back facing camera does not exist
if (findBackFacingCamera() < 0) {
Toast.makeText(this, "No back facing camera found.", Toast.LENGTH_LONG).show();
} else {
try {
//Open the back facing camera, note that Camera.open() gives the same error.
mCamera = Camera.open(findBackFacingCamera());
mCamera.setDisplayOrientation(90); //Show in Portrait
mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
} catch (RuntimeException e) {
e.printStackTrace();
Toast.makeText(this, "Could not connect to camera.", Toast.LENGTH_LONG).show();
}
}
}
}
public void initialize() {
cameraPreview = (LinearLayout) findViewById(R.id.camera_preview);
mPreview = new CameraPreview(myContext, mCamera);
cameraPreview.addView(mPreview);
capture = (ImageButton) findViewById(R.id.button_capture);
capture.setOnClickListener(captureListener);
}
@Override
protected void onPause() {
super.onPause();
//when on Pause, release camera in order to be used from other applications
releaseCamera();
}
private void captureComplete() {
//...
}
private Camera.PictureCallback getPictureCallback() {
Camera.PictureCallback picture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
//make a new picture file
mFile = ImageUtility.getOutputMediaFile(ImageUtility.MEDIA_TYPE_IMAGE);
Log.i(TAG, (mFile == null) + ": ");
if (mFile == null) {
return;
}
mPreview.refreshCamera(mCamera);
mBackgroundHandler.post(new ImageUtility.ImageSaver(getApplicationContext(), data, mFile, new Callable() {
@Override
public Object call() throws Exception {
captureComplete();
return null;
}
}));
}
};
return picture;
}
View.OnClickListener captureListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mCamera != null) {
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
mPicture = getPictureCallback();
mPreview.refreshCamera(camera);
camera.takePicture(null, null, mPicture);
}
});
} else {
throw new NullPointerException();
}
}
};
private void releaseCamera() {
// stop and release camera
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
if (mPreview != null) {
mPreview.setCamera(null);
}
}
}
答案 0 :(得分:0)
您可以做一些更改,因为我自3个月以来一直在Camera
api工作..
在CameraPreview
构造函数中,添加此行
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) // add this
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
在surfaceDestroyed()
中的CameraPreview
方法中,您应该在释放相机资源后立即删除回调:
this.getHolder().removeCallback(this);
除了改变上述内容之外,由于您使用了自动对焦和其他功能,我无法从您的CameraActivity
中获得更多信息....我使用FrameLayout作为运行预览的容器。