user6650650
user6650650

Reputation:

Camera object always returning null

I'm trying to build a camera app by following official developer guide but due to my camera object returning null , I get this error:

D/cam: java.lang.RuntimeException: Fail to connect to camera service

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapplication, PID: 1116
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.unlock()' on a null object reference
        at com.myapplication.CamPreview.prepareVideoRecorder(CamPreview.java:100)
        at com.myapplication.CamPreview.access$500(CamPreview.java:20)
        at com.myapplication.CamPreview$1.onClick(CamPreview.java:60)
        at android.view.View.performClick(View.java:4756)
        at android.view.View$PerformClick.run(View.java:19761)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5264)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:695)

here is the class:

public class CamPreview extends AppCompatActivity {

private Camera mCamera;
private MySurfaceHolder mPreview;
private MediaRecorder mMediaRecorder;
private File vidFile;
private String currentTime;
private boolean isRecording = false;
private Button captureButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_cam_preview);
    // Create an instance of Camera
    mCamera = getCameraInstance();

    // Create our Preview view and set it as the content of our activity.
    mPreview = new MySurfaceHolder(this, mCamera);
    FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
    preview.addView(mPreview);


    // Add a listener to the Capture button
    captureButton = (Button) findViewById(R.id.button_capture);
    captureButton.setOnClickListener(
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (isRecording) {
                        // stop recording and release camera
                        mMediaRecorder.stop();  // stop the recording
                        releaseMediaRecorder(); // release the MediaRecorder object
                        mCamera.lock();         // take camera access back from MediaRecorder

                        // inform the user that recording has stopped
                        setCaptureButtonText("Capture");
                        isRecording = false;
                    } else {
                        // initialize video camera
                        if (prepareVideoRecorder()) {
                            // Camera is available and unlocked, MediaRecorder is prepared,
                            // now you can start recording
                            mMediaRecorder.start();

                            // inform the user that recording has started
                            setCaptureButtonText("Stop");
                            isRecording = true;
                        } else {
                            // prepare didn't work, release the camera
                            releaseMediaRecorder();
                            // inform user
                        }
                    }
                }
            }
    );

}
private void setCaptureButtonText(String txt){
    captureButton.setText(txt);
}

public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        Log.d("cam", e.toString());
    }
    return c; // returns null if camera is unavailable
}

private boolean prepareVideoRecorder(){

    mCamera = getCameraInstance();
    mMediaRecorder = new MediaRecorder();

    // Step 1: Unlock and set camera to MediaRecorder
    mCamera.unlock();
    mMediaRecorder.setCamera(mCamera);

    // Step 2: Set sources
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
    mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    // Step 4: Set output file
    mMediaRecorder.setOutputFile(getVidFile().getAbsolutePath());

    // Step 5: Set the preview output
    mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

    // Step 6: Prepare configured MediaRecorder
    try {
        mMediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d("TAG", "IllegalStateException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        Log.d("TAG", "IOException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    }
    return true;
}

private File getVidFile(){
    currentTime=new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
    vidFile=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath()+"/"+currentTime+".mp4");
    return vidFile;
}

@Override
protected void onPause() {
    super.onPause();
    releaseMediaRecorder();       // if you are using MediaRecorder, release it first
    releaseCamera();              // release the camera immediately on pause event
}

private void releaseMediaRecorder(){
    if (mMediaRecorder != null) {
        mMediaRecorder.reset();   // clear recorder configuration
        mMediaRecorder.release(); // release the recorder object
        mMediaRecorder = null;
        mCamera.lock();           // lock camera for later use
    }
}

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

@Override
protected void onDestroy() {
    releaseCamera();
    super.onDestroy();
}

}

I searched same questions but none of the answers help me.

Upvotes: 4

Views: 1136

Answers (2)

user6650650
user6650650

Reputation:

We got the answer here , by Mark Keen :

" I suspect you are doubling up when trying to get an Instance of the Camera Object before releasing a previous first. You gain a Camera instance in onCreate() - you only need one instance - your method prepareVideoRecorder() attempts to gain another Camera Object and point mCamera to it before it has been released "

So mCamera = getCameraInstance(); in prepareVideoRecorder was causing the problem.

Upvotes: 1

Devin Zhu
Devin Zhu

Reputation: 1

Try to request permissions before use Camera, add following code in your AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA"/>

Upvotes: 0

Related Questions