android java.lang.RuntimeException:Fail to connect to camera service using SurfaceView

394 views Asked by At

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" />
1

There are 1 answers

18
Sameer Jani On

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.