我正在使用表面视图和Camera 1 API创建自定义相机应用程序,生命周期中存在某种问题而我无法让它工作,但基本上我正在释放相机然后再次调用它:< / p>
调用Camera.release()后正在使用相机
理想情况下,当按下后退按钮时,应该返回上一个活动,按下主页按钮时应该重新打开,没有任何问题。
有人会指导我完成这些调用的实施,例如发布和打开相机:
自定义曲面视图类:
public class ImageSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private Camera camera;
private SurfaceHolder surfaceHolder;
public final String TAG = ImageSurfaceView.class.getSimpleName();
public ImageSurfaceView(Context context, Camera camera) {
super(context);
this.camera = camera;
this.surfaceHolder = getHolder();
this.surfaceHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
this.camera.setPreviewDisplay(holder);
this.camera.startPreview();
} catch (IOException ex){
Log.e(TAG, "surfaceCreated: "+ex.getMessage() );
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
this.camera.stopPreview();
this.camera.release();
this.camera = null;
}
}
和我的CameraAcitivty LifeCycle CallBacks:
@Override
protected void onRestart() {
super.onRestart();
camera = null;
requestCamera();
}
@Override
protected void onResume() {
super.onResume();
try {
requestCamera();
} catch (RuntimeException ex){
Log.e(TAG, "onResume: "+ex.getMessage() );
}
}
@Override
protected void onPause() {
super.onPause();
if (camera != null) {
camera.setPreviewCallback(null);
imageSurfaceView.getHolder().removeCallback(imageSurfaceView);
camera.release();
camera = null;
}
}
@Override
protected void onStop() {
super.onStop();
isSurfaceCreated = false;
}
@Override
protected void onDestroy() {
super.onDestroy();
releaseCameraAndPreview();
}
private void releaseCameraAndPreview(){
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
if(imageSurfaceView != null){
imageSurfaceView.destroyDrawingCache();
}
}
private void requestCamera(){
if (camera == null) {
if (checkPermission()) {
callCameraThread();
Toast.makeText(getApplicationContext(), "Permission already granted", Toast.LENGTH_LONG).show();
} else {
requestPermission();
}
}
}
public Camera checkDeviceCamera(){
Camera mCamera = null;
try {
mCamera = Camera.open(0);
} catch (Exception e) {
e.printStackTrace();
}
return mCamera;
}
private void callCameraThread(){
if(mThread == null){
mThread = new CameraHandlerThread();
}
synchronized (mThread){
mThread.openCamera();
}
}
public synchronized void loadSurface(){
while(camera == null){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(!isSurfaceCreated) {
imageSurfaceView = new ImageSurfaceView(CameraActivity.this, camera);
cameraPreviewLayout.addView(imageSurfaceView);
isSurfaceCreated = true;
imgGhost = new ImageView(this);
imgGhost.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
imgGhost.setBackground(ContextCompat.getDrawable(this, R.drawable.fantasma_doc_front));
cameraPreviewLayout.addView(imgGhost);
}
}
private CameraHandlerThread mThread = null;
private class CameraHandlerThread extends HandlerThread {
Handler mHandler = null;
CameraHandlerThread(){
super("CameraHandlerThread");
start();
mHandler = new Handler(getLooper());
}
synchronized void notifyCameraOpened(){
notifyAll();
}
void openCamera(){
mHandler.post(new Runnable() {
@Override
public void run() {
camera = checkDeviceCamera();
notifyCameraOpened();
}
});
try{
wait();
} catch (InterruptedException ex){
Log.e(TAG, "openCamera: "+"wait was interrupted" );
}
}
}
我不知道如何正确处理相机的发布和表面视图的创建,现在我做了一些更改后,我能够按下主页按钮并回来没有问题,但onBackPressed崩溃,之前是相反的,谢谢事先得到任何帮助
答案 0 :(得分:0)
所以,我试图尽量减少对相机的重复引用,这是onBackPressed的样子:
@Override
public void onBackPressed() {
if (isPreviewing) { //if previewing layout is on screen, then I want to return to the camera, without saving the picture
rlPicturePreview.setVisibility(View.GONE);
llCameraControl.setVisibility(View.VISIBLE);
isPreviewing = false;
isPictureProcessing = false;
camera.startPreview();
} else {
if(!isPictureProcessing) { //Otherwise if there is no process happening I want to go back to previous calling activity, therefore closing the camera
previousDataExists = false;
isSurfaceCreated = false;
DriverFragment.docPicturesArray.clear();
CameraDocActivity.this.finish();
}
}
}
这就是onResume()现在的样子,我添加了对在棒棒糖,Marshmallow和Nougat中测试的大多数现代API的支持
@Override
protected void onResume() {
super.onResume();
try {
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M){
callCameraThread();
loadSurface();
} else {
requestCamera();
}
} catch (RuntimeException ex){
Log.e(TAG, "onResume: "+ex.getMessage() );
}
}
onRestart中的只需删除requestCamera():
@Override
protected void onRestart() {
super.onRestart();
camera = null;
}
最后在onSurfaceDestroyed()中进行空验证:
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(this.camera != null) {
this.camera.stopPreview();
this.camera.release();
this.camera = null;
}
现在按下主页按钮时没有任何问题,或者按下后退按钮,我确保每次通过onRestart(),关闭后和onStop i时相机都设置为空确保标志isSurfaceCreated设置为false。