0

Im getting the exception java.lang.RuntimeException:Fail to connect to camera service when reopening the same activity. For the first time the code works fine without capturing video file(only camera preview).But after finishing MainActivity.If I again calls Mainactivity then for mCamera = Camera.open(0); it throws Exception I checked questions on stackoverflow but non of the solution worked for it.

Code

public class MainActivity extends AppCompatActivity  implements SurfaceHolder.Callback, View.OnClickListener {
    private VideoView videoView = null;
    private MediaController mc = null;
    private SurfaceHolder surfaceHolder;
    private SurfaceView surfaceView;
    public MediaRecorder mediaRecorder = new MediaRecorder();
    private Camera mCamera;
    private Button btnStart;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        surfaceView = (SurfaceView) findViewById(R.id.surface_camera);

        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        btnStart = (Button) findViewById(R.id.btnStart);
        btnStart.setOnClickListener(this);
        if (mCamera == null) {
            mCamera = Camera.open(0);
            Camera.Parameters params = mCamera.getParameters();
            mCamera.setParameters(params);
            mCamera.setDisplayOrientation(90);

        }

    }

    @SuppressLint("NewApi")
    protected void startRecording() throws IOException {


        File sdCard = Environment.getExternalStorageDirectory();
        File dir = new File(sdCard.getAbsolutePath() + "/myVideos");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        Date date = new Date();
        String fileName =  "/rec" + date.toString().replace(" ", "_").replace(":", "_") + ".mp4";
        File file = new File(dir, fileName);

        mediaRecorder = new MediaRecorder();
        mCamera.lock();
        mCamera.unlock();

        mediaRecorder.setCamera(mCamera);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
        mediaRecorder.setOutputFile(dir + fileName);
        mediaRecorder.setOrientationHint(90);
        mediaRecorder.prepare();
        mediaRecorder.start();
        refreshGallery(file);
    }

    private void refreshGallery(File file) {
        Intent mediaScanIntent = new Intent(
                Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        mediaScanIntent.setData(Uri.fromFile(file));
        sendBroadcast(mediaScanIntent);
    }



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

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (mCamera != null) {

            try {
                if (mCamera != null) {
                    mCamera.setPreviewDisplay(surfaceHolder);
                    mCamera.startPreview();
                    mCamera.unlock();


                }
            }
            catch(Exception ex)
            {

                ex.printStackTrace();
            }
        } else {
            Toast.makeText(getApplicationContext(), "Camera not available!",
                    Toast.LENGTH_LONG).show();
            finish();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mCamera.stopPreview();
        mCamera.setPreviewCallback(null);
        mCamera.release();
        mCamera = null;

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnStart:
                if (btnStart.getText().toString().equalsIgnoreCase("Start")) {
                    btnStart.setText("Stop");
                    try {
                        startRecording();
                    } catch (IOException e) {
                        String message = e.getMessage();
                        Log.i(null, "Problem " + message);
                        mediaRecorder.release();
                        e.printStackTrace();
                    }
                } else {
                    btnStart.setText("Start");
                    mediaRecorder.stop();
                    mediaRecorder.release();
                    mediaRecorder = null;
                }
                break;

            default:
                break;
        }
    }
   @Override
public void onDestroy()
{
    super.onDestroy();

    if(mCamera!=null) {
        mCamera.stopPreview();
        mCamera.setPreviewCallback(null);
        mCamera.release();
        mCamera = null;
   }

}

    @Override
    public void onBackPressed()
    {

        Intent intent=new Intent(MainActivity.this,FirstActivityActivity.class);
        startActivity(intent);
        super.onBackPressed();


    }
}

can anyone tell me,whats wrong with the code?

here is the logcat

FATAL EXCEPTION: main
    Process: com.example.surfaceviewrecord, PID: 11717
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.surfaceviewrecord/com.example.surfaceviewrecord.MainActivity}: 
    java.lang.RuntimeException: Fail to connect to camera service
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5776)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
     Caused by: java.lang.RuntimeException: Fail to connect to camera service
        at android.hardware.Camera.<init>(Camera.java:647)
        at android.hardware.Camera.open(Camera.java:489)
        at com.example.surfaceviewrecord.MainActivity.onCreate(MainActivity.java:47)
        at android.app.Activity.performCreate(Activity.java:6582)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667) 
        at android.app.ActivityThread.-wrap11(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494) 
        at android.os.Handler.dispatchMessage(Handler.java:111) 
        at android.os.Looper.loop(Looper.java:207) 
        at android.app.ActivityThread.main(ActivityThread.java:5776) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

Permissions in manifest file

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
Bhagyashri
  • 182
  • 1
  • 15

1 Answers1

0

You need to apply Runtime Camera Permission from marshmallow and above. So here you haven't camera permission that's why this error occurred.

Please check this Link

@Override
protected void onDestroy() {
    super.onDestroy();
    releaseMediaRecorder();
    if (camera != null) {
        camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
        camera = null;
    }
}

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

Please check above code and put in at onDestroy() method.

Sameer Jani
  • 1,192
  • 9
  • 16
  • I have already added the runtime permissions.and checked in settings also. – Bhagyashri Jun 18 '18 at 09:36
  • Ohk, Have you release camera at onDestroy() ? – Sameer Jani Jun 18 '18 at 09:41
  • Please write log at surfaceDestroyed() method and check what actually happening. I think so something went wrong here. – Sameer Jani Jun 18 '18 at 09:49
  • surfaceDestroyed() is working fine I debug the code and it sets camera to null.No issues in that code – Bhagyashri Jun 18 '18 at 09:53
  • Oh,...please check in this step, 1) Open your app camera(MainActivity, As you said first time it's opening without fail) 2) Then close main activity then try to open your mobile device camera (Might be it would not open properly and throwing same error as I expect). Please check this things and update me about it. So I can help you with properly here. – Sameer Jani Jun 18 '18 at 09:57
  • @ Sameer Jani you are correct.My mobile device camera also shows error can't connect to camera. – Bhagyashri Jun 18 '18 at 10:01
  • Because of you are not properly releasing camera, Resource must be release carefully after use. No issue please do as above code which I kept in my answer at onDestroy method then update me what happen?So I can help you further issue if any. – Sameer Jani Jun 18 '18 at 10:02
  • I have copied above code and placed it onDestroy() but still it throws Exception.but first it calls surfaceDestroyed() and then it calls onDestroy() so camera is already released in surfaceDestroyed() as I mentioned in code – Bhagyashri Jun 18 '18 at 10:05
  • Okay, Is it throwing error at first time when you open mainactivity camera and during close that activity that time throwing error or second time when you open at that time it occurs? – Sameer Jani Jun 18 '18 at 10:09
  • @ Sameer Jani for the first time its working fine.for the second time when opening activity it throws Exception – Bhagyashri Jun 18 '18 at 10:17
  • Still it throws the Exception.Here it throws Exception for preview only without recording.and again opening the activity. – Bhagyashri Jun 18 '18 at 10:24
  • When you are opening camera that time you are pressing record button? There is lock and unlock which you call both simultaneously it's not proper. lock() method call when you are acquiring resource and here when you going to start recording before it you need to release camera so media resource can acquire camera lock. It's simple thread fundamentals. By this way one process handoff to another.might be this issue may rise this error. – Sameer Jani Jun 18 '18 at 10:31
  • I think please apply this code for your camera task https://github.com/gmerwan/cameraview This is more easy and very very good and properly managed code. This will surely 100% help you without issue. – Sameer Jani Jun 18 '18 at 10:36
  • But without clicking start button im just showing the preview and just pressing back and again opening the activity. – Bhagyashri Jun 18 '18 at 10:39
  • Hmm...Okay, I recommend you to use above google camera which I above provided It will surely help you and It's not taking much time and it will reduce your code too much. Just check it and if you are getting any trouble during implementation tell me I will help you. :) – Sameer Jani Jun 18 '18 at 10:42
  • @ Sameer Jani unable to compile the project it gives error `error: package com.google.android.cameraview does not exist import com.google.android.cameraview.Camera2;` – Bhagyashri Jun 18 '18 at 11:17
  • Can you show me your gradle dependancies? and camera module which you added, it's dependancies? Update it in your question. then ping me. – Sameer Jani Jun 18 '18 at 11:19
  • @ Sameer Jani But the code is for capture image i want for capture video – Bhagyashri Jun 18 '18 at 12:12