Camera对象始终返回null

时间:2016-07-29 00:41:24

标签: java android camera

我正在尝试按照官方开发者指南构建相机应用程序,但由于我的相机对象返回null,我收到此错误:

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)

这是班级:

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();
}

}

我搜索了同样的问题,但没有一个答案对我有帮助。

2 个答案:

答案 0 :(得分:1)

Mark Keen在这里得到了答案:

"我怀疑你在释放前一个第一个之前尝试获取相机对象的实例时会加倍。你在onCreate()中获得了一个Camera实例 - 你只需要一个实例 - 你的方法prepareVideoRecorder()试图获得另一个Camera Object并在它被释放之前将mCamera指向它#34;

所以mCamera = getCameraInstance();在prepareVideoRecorder导致了这个问题。

答案 1 :(得分:0)

尝试在使用Camera之前请求权限,在AndroidManifest.xml中添加以下代码:

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