我希望摄像机在更改为录像机 Activity 时启动录像机,而不是在事件监听器上启动录像机。但是,当我尝试在oncreate上运行它时,它将崩溃一次,然后将按预期运行。
我在MediaRecorder.start()和myCamera.unlock上遇到错误。我该如何调试?

package com.abacus.surveillance;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import java.io.IOException;


import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;
import android.os.Handler;


public class RecordActivity extends AppCompatActivity {

    private static Camera myCamera;
    private  MyCameraSurfaceView myCameraSurfaceView;
    private  MediaRecorder mediaRecorder;

    Button myButton;
    Button restore;
    SurfaceHolder surfaceHolder;
    boolean recording;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        recording = false;

        setContentView(R.layout.activity_record);

        //Get Camera for preview
        myCamera = getCameraInstance();

        if(myCamera == null){
            Log.d("ON Create","Failed to get camera");
        } else {
            Log.d("ON Create","Got camera");
        }

        myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
        FrameLayout myCameraPreview = (FrameLayout)findViewById(R.id.videoview);
        myCameraPreview.addView(myCameraSurfaceView);

        myButton = (Button)findViewById(R.id.mybutton);
        restore = (Button)findViewById(R.id.restorebtn);
        myButton.setOnClickListener(myButtonOnClickListener);

        restore.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(RecordActivity.this, MainActivity.class));
            }
        });


         Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                startRecord();
            }
        }, 3000);
    }

    Button.OnClickListener myButtonOnClickListener
            = new Button.OnClickListener(){

        @Override
        public void onClick(View v) {

            startRecord();
            }

        };

    private void startRecord(){
        if(recording){

            try{
                mediaRecorder.stop();
                releaseMediaRecorder();
                //finish();
                myButton.setText("REC");
            }catch(Exception e){
                e.printStackTrace();
            }

        }else{

            releaseCamera();

            if(!prepareMediaRecorder()){
                Toast.makeText(RecordActivity.this,
                        "Fail in prepareMediaRecorder()!\n - Ended -",
                        Toast.LENGTH_LONG).show();
                finish();
            }

            mediaRecorder.start();
            Log.d("start", "started");
            recording = true;
            myButton.setText("STOP");
        }
    }

    private Camera getCameraInstance(){

        Camera c = null;
        try {
            c = Camera.open();
            Log.d("open", "open");
        }
        catch (Exception e){
            Log.d("notopen", "notopen");
           Log.e("camera", e.getMessage());
        }
        return c;
    }

    private boolean prepareMediaRecorder(){
        Log.d("prep", "prepcamera");
        myCamera = getCameraInstance();

        mediaRecorder = new MediaRecorder();

        myCamera.unlock();

        //myCamera.setDisplayOrientation(90);

        mediaRecorder.setCamera(myCamera);

        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));

        mediaRecorder.setOutputFile("/sdcard/myvideo.mp4");
        mediaRecorder.setMaxDuration(60000);

        mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface());

        try {
            mediaRecorder.prepare();
            Log.d("prepare", "prepared");
            //mediaRecorder.start();
        } catch (IllegalStateException e) {
            Log.d("fail", "failed");
            e.printStackTrace();
            releaseMediaRecorder();
            return false;
        } catch (IOException e) {
            Log.d("fail", "failed2");
            e.printStackTrace();
            releaseMediaRecorder();
            return false;
        }
        return true;
    }

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

    private void releaseMediaRecorder(){
        if (mediaRecorder != null) {
            mediaRecorder.reset();
            mediaRecorder.release();
            mediaRecorder = null;
            myCamera.lock();
        }
    }

    private void releaseCamera(){
        if (myCamera != null){
            myCamera.release();
            myCamera = null;
        }
    }

    public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{

        private SurfaceHolder mHolder;
        private Camera mCamera;

        public MyCameraSurfaceView(Context context, Camera camera) {
            super(context);
            mCamera = camera;
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

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


            if (mHolder.getSurface() == null){

                return;
            }
            // stop preview before making changes
            try {
                mCamera.stopPreview();
            } catch (Exception e){
                // ignore: tried to stop a non-existent preview
            }

            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (Exception e){
            }
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {

            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d("prevfail","fail");
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }
    }
}

Logcat
04-04 17:07:42.237 22448-22448/com.abacus.surveillance D/open: open
04-04 17:07:42.237 22448-22448/com.abacus.surveillance D/ON Create: Got camera
04-04 17:07:42.257 22448-22448/com.abacus.surveillance I/Choreographer: Skipped 42 frames!  The application may be doing too much work on its main thread.
04-04 17:07:43.118 22448-22448/com.abacus.surveillance D/open: open
04-04 17:07:43.118 22448-22448/com.abacus.surveillance D/ON Create: Got camera
04-04 17:07:43.929 22448-22448/com.abacus.surveillance D/open: open
04-04 17:07:43.929 22448-22448/com.abacus.surveillance D/ON Create: Got camera
04-04 17:07:44.029 22448-22448/com.abacus.surveillance I/Choreographer: Skipped 96 frames!  The application may be doing too much work on its main thread.
04-04 17:07:44.169 22448-22448/com.abacus.surveillance D/AndroidRuntime: Shutting down VM
04-04 17:07:44.169 22448-22448/com.abacus.surveillance W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x418ccda0)
04-04 17:07:44.199 22448-22448/com.abacus.surveillance E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.abacus.surveillance, PID: 22448
    java.lang.RuntimeException: Method called after release()
    at android.hardware.Camera.setPreviewDisplay(Native Method)
    at android.hardware.Camera.setPreviewDisplay(Camera.java:530)
    at com.abacus.surveillance.RecordActivity$MyCameraSurfaceView.surfaceCreated(RecordActivity.java:263)
    at android.view.SurfaceView.updateWindow(SurfaceView.java:602)
    at android.view.SurfaceView.access$000(SurfaceView.java:94)
    at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:183)
    at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:891)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2193)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1251)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6540)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:813)
    at android.view.Choreographer.doCallbacks(Choreographer.java:613)
    at android.view.Choreographer.doFrame(Choreographer.java:583)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:799)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:146)
    at android.app.ActivityThread.main(ActivityThread.java:5593)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
    at dalvik.system.NativeStart.main(Native Method)

Logcat 2
04-04 17:19:30.573 2479-2479/com.abacus.surveillance E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.abacus.surveillance, PID: 2479
    java.lang.NullPointerException
    at com.abacus.surveillance.RecordActivity.startRecord(RecordActivity.java:136)
    at com.abacus.surveillance.RecordActivity.access$000(RecordActivity.java:40)
    at com.abacus.surveillance.RecordActivity$2.run(RecordActivity.java:90)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:146)
    at android.app.ActivityThread.main(ActivityThread.java:5593)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
    at dalvik.system.NativeStart.main(Native Method)

最佳答案

对于第一个例外,请尝试像这样更改surfaceCreated():

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if( mCamera != null ){
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d("prevfail","fail");
            }
        }
    }

对于第二个例外,请尝试如下操作:
private void startRecord(){
    if(recording){
        try{
            if( mediaRecorder != null )
                mediaRecorder.stop();

            releaseMediaRecorder();
            //finish();
            myButton.setText("REC");
        }catch(Exception e){
            e.printStackTrace();
        }

    }else{

        releaseCamera();

        if(!prepareMediaRecorder()){
            Toast.makeText(RecordActivity.this,
                    "Fail in prepareMediaRecorder()!\n - Ended -",
                    Toast.LENGTH_LONG).show();
            finish();
        }
        else{
            mediaRecorder.start();
            Log.d("start", "started");
            recording = true;
            myButton.setText("STOP");
        }
    }
}

10-08 13:25