java - 相机对象总是返回 null

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

我搜索了相同的问题,但没有任何答案对我有帮助。

最佳答案

马克·基恩 (Mark Keen) 在这里找到了答案:

“我怀疑您在尝试获取相机对象的实例时加倍,然后再释放前一个。您在 onCreate() 中获得了一个相机实例 - 您只需要一个实例 - 您的方法 prepareVideoRecorder() 尝试获得另一个相机对象并在它被释放之前将 mCamera 指向它“

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

关于java - 相机对象总是返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38648830/

相关文章:

java - Java EE7 和 CDI 2.0 的 Maven 依赖项是什么?

使用变量的 Java Derby SQL 查询语句

java - 无模式 JSON 到 Apache Beam "Row"类型?

android - Creative sdk 编辑屏幕在手机中停留在纵向模式

android - 将实时视频从安卓摄像头流式传输到服务器

java - 正则表达式捕获具有特定容器的一系列数字

android - whatsapp 如何在更新后立即同步联系人

android - 如何在 android 中创建一个浏览按钮以从 sdcard 或内部卡加载任何目录?

iphone - 如何将图像保存到相机胶卷?

ios - 在 IOS 应用程序中构建相机时出错