Камера используется после вызова camera.release()

Я создал класс Camera Activity и класс вида с камеры, который расширяет вид поверхности. Я также создаю кнопку, которая отвечает за обработку запуска и остановки видеокамеры. Когда я нажимаю кнопку запуска, камера начинает запись, но когда я нажимаю кнопку остановки, это показывает фатальную ошибку

public class CameraActivity extends Activity {
    private Camera mCamera;
    private CameraView cameraView;
    private boolean isRecording = false;
    private MediaRecorder mediaRecorder;
    private Button mStart;
    FrameLayout frameLayout;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camera);
    mStart = findViewById(R.id.start);

    mStart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(isRecording){
                mediaRecorder.stop();
                releaseMediaRecorder();
                mCamera.lock();
                mStart.setText("start");
                isRecording = false;
            }
            if(prepare()){
                mediaRecorder.start();
                mStart.setText("stop");
                isRecording = true;
            }
        }
    });

}
@Override
public void onResume(){
    super.onResume();

        mCamera = getCameraInstance();
        cameraView = new CameraView(this, mCamera);
        frameLayout = findViewById(R.id.frame);
        frameLayout.addView(cameraView);

}

private boolean prepare(){

    try {
        mCamera.setPreviewDisplay(cameraView.getHolder());
        mCamera.startPreview();
    } catch (IOException e) {
        e.printStackTrace();
    }

    mCamera.unlock();

    mediaRecorder = new MediaRecorder();

    mediaRecorder.setCamera(mCamera);

    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);

    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    mediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    mediaRecorder.setPreviewDisplay(cameraView.getHolder().getSurface());

    try {
        mediaRecorder.prepare();
    } catch (IOException e) {
        e.printStackTrace();
        releaseMediaRecorder();
        return false;
    }
    return true;
}

private void releaseMediaRecorder() {
    if(mediaRecorder != null){
        mediaRecorder.reset();
        mediaRecorder.release();
        mediaRecorder = null;
        mCamera.release();
    }
}

private static Camera getCameraInstance() {
    Camera c = null;
    try {
        c = Camera.open();
    }catch (Exception e){

    }
    return c;
}
private static final int MEDIA_TYPE_VIDEO = 2;

private static Uri getOutputMediaFileUri(int type){
    return Uri.fromFile(getOutputMediaFile(type));
}
private static File getOutputMediaFile(int type){
    File store = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES), "folder");
    if(!store.exists()){
        store.mkdirs();
    }
    String timeStame = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File media;
    if(type == MEDIA_TYPE_VIDEO){
        media = new File(store.getPath()+File.separator+"vid"+timeStame+".mp4");
    }else {
        return null;
    }
    return media;
     }
}

мой класс держателя поверхности

public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
Context ctx;

public CameraView(Context context, Camera camera) {
    super(context);

    ctx = context;
    mCamera = camera;
    mHolder = getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();
        mCamera.setDisplayOrientation(90);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int w, int h) {
    if(mHolder.getSurface() == null){
        return;
    }
    try{
        mCamera.stopPreview();
    }catch (Exception e){
        e.printStackTrace();
    }
    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
    }catch (Exception e){
        e.printStackTrace();
    }
}

 @Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        mCamera.lock();
        mCamera.stopPreview();
        mCamera.release();
    }
}

при остановке записи видео я получил эту фатальную ошибку

10-31 06:22:06.277 5744-5744/com.android.appD/AndroidRuntime: Shutting down VM
10-31 06:22:06.287 5744-5744/com.android.appE/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.app, PID: 5744
java.lang.RuntimeException: Camera is being used after Camera.release() was called
at android.hardware.Camera.lock(Native Method)
at com.android.app.CameraActivity$1.onClick(CameraActivity.java:47)
at android.view.View.performClick(View.java:5716)
at android.widget.TextView.performClick(TextView.java:10932)
at android.view.View$PerformClick.run(View.java:22596)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

0 ответов

Другие вопросы по тегам