Android FragmentStatePagerAdapter с двумя фрагментами, имеющими SurfaceViews с camerview, не удается подключиться к сервису камеры - PullRequest
0 голосов
/ 20 октября 2019

Android с FragmentStatePagerAdapter и имеет в общей сложности 3 фрагмента. -> первый фрагмент имеет диктофон -> второй фрагмент имеет SurfaceView, содержащий объект Camera. -> Третий фрагмент имеет функцию распознавания лица google vision с камерой, удерживающей вид на поверхности. Проблема: когда viewpageradapter переключился на второй экран, приложение завершало работу с ошибкой в ​​третьем фрагменте (из-за того, что объект камеры не был освобожден во втором фрагменте)

Сообщение об ошибке: java.lang.RuntimeException: не удается подключиться к службе камеры. MainRenderer.onSurfaceCreated (MainRenderer.java:171)

-> как разблокировать камеру, когда 2-й и 3-й фрагменты пересекаются между собой?

Код: фрагмент 2:

открытый класс VideoMsgFragment расширяет Fragment реализует SurfaceHolder.Callback {

private FragmentVideoRecordBinding binding;
private SurfaceHolder surfaceHolder;
public MediaRecorder mrec = new MediaRecorder();

File video;
static public Camera mCamera;
private boolean isRecording;
private boolean isVideoPlaying;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {


    mrec = new MediaRecorder();  // Works well
    mrec.setOrientationHint(180);
    binding = DataBindingUtil.inflate(inflater, R.layout.fragment_video_record, container,
            false);

    mCamera = Camera.open();

    initRecorder();

    surfaceHolder = binding.surfaceCamera.getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    binding.btnRecordOrStop.setOnClickListener(v -> {
        try {
            if (isRecording) {
                stopRecording();
                isRecording = false;
                binding.btnRecordOrStop.setImageDrawable(getResources().getDrawable(R.drawable.ic_fiber_manual_record_green_24dp));

                releaseMediaRecorder();
                releaseCamera();
            } else {
                isRecording = true;
                startRecording();
                binding.btnRecordOrStop.setImageDrawable(getResources().getDrawable(R.drawable.ic_stop));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    });


    binding.videoview.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
            binding.btnPlay.setImageDrawable(getResources().getDrawable(R.drawable.ic_play_arrow_black_24dp));
        }
    });

    binding.btnPlay.setOnClickListener(v -> {
        if (!isVideoPlaying) {
            isVideoPlaying = true;
            binding.videoview.setVisibility(View.VISIBLE);
            binding.surfaceCamera.setVisibility(View.GONE);
            binding.videoview.setVideoPath("/sdcard/videocapture_example.mp4");
            binding.videoview.start();
            binding.btnPlay.setImageDrawable(getResources().getDrawable(R.drawable.ic_stop));
        } else {
            isVideoPlaying = false;
            binding.videoview.pause();
            binding.btnPlay.setImageDrawable(getResources().getDrawable(R.drawable.ic_play_arrow_black_24dp));
        }
    });

    return binding.getRoot();
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public void onPrepareOptionsMenu(Menu menu) {
}


protected void startRecording() throws IOException {
    mCamera = Camera.open();
    mCamera.unlock();


    mrec.setPreviewDisplay(surfaceHolder.getSurface());
        mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mrec.setAudioSource(MediaRecorder.AudioSource.MIC);

    mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
           mrec.setOutputFile("/sdcard/videocapture_example.mp4");

    mrec.prepare();
    mrec.start();
}


protected void stopRecording() {
    if (mrec != null)
        mrec.stop();
    mrec.release();
    mCamera.release();
}

private void releaseMediaRecorder() {
    if (mrec != null) {
        mrec.release(); // release the recorder object

    }
}

private void releaseCamera() {
    if (mCamera != null) {
        mCamera.release();        // release the camera for other applications
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
                           int height) {
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    if (mCamera != null) {
        Camera.Parameters params = mCamera.getParameters();
        mCamera.setParameters(params);
    } else {
        Toast.makeText(getContext(), "Camera not available!", Toast.LENGTH_LONG).show();
    }
}

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

@Override
public void onDestroyView() {

    super.onDestroyView();

    if (mCamera!=null)
        mCamera.release();
}}
...