1

我正在尝试在 android 中创建背景录像机。为此,我创建了一个Service类来实现视频录制。当我按下按钮开始录制时,它开始成功,但是当我停止它时,出现以下异常:

06-27 17:32:20.974 20244-21916/com.svtech.thirdeye.thirdeye E/MediaRecorderJNI: Application lost the surface
06-27 17:32:24.513 20244-21848/com.svtech.thirdeye.thirdeye E/NativeCrypto: ssl=0x587e0d60 cert_verify_callback x509_store_ctx=0x54ab7a48 arg=0x0
06-27 17:32:24.513 20244-21848/com.svtech.thirdeye.thirdeye E/NativeCrypto: ssl=0x587e0d60 cert_verify_callback calling verifyCertificateChain authMethod=ECDHE_ECDSA
06-27 17:32:25.009 20244-20244/com.svtech.thirdeye.thirdeye E/MediaRecorder: stop called in an invalid state: 4
06-27 17:32:25.033 20244-20244/com.svtech.thirdeye.thirdeye E/AndroidRuntime: 

FATAL EXCEPTION: main

java.lang.RuntimeException: Unable to stop service com.svtech.thirdeye.thirdeye.Services.VideoRecordingOldApiService@424cfbb8: java.lang.IllegalStateException
    at android.app.ActivityThread.handleStopService(ActivityThread.java:2894)
    at android.app.ActivityThread.access$2000(ActivityThread.java:162)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1466)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:194)
    at android.app.ActivityThread.main(ActivityThread.java:5371)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.IllegalStateException
    at android.media.MediaRecorder.stop(Native Method)
    at com.svtech.thirdeye.thirdeye.Services.VideoRecordingOldApiService.onDestroy(VideoRecordingOldApiService.java:129)
    at android.app.ActivityThread.handleStopService(ActivityThread.java:2877)
    at android.app.ActivityThread.access$2000(ActivityThread.java:162) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1466) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:194) 
    at android.app.ActivityThread.main(ActivityThread.java:5371) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:525) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 
    at dalvik.system.NativeStart.main(Native Method) 

这是我的VideoRecordingOldApiService

public class VideoRecordingOldApiService extends Service {


    private Handler handler;
    protected String fileName;
    private Camera mCamera;
    private CameraPreview cameraPreview;
    private MediaRecorder videoRecorder;
    private CameraCheck cameraCheck;
    private Thread recorderThread;

    public VideoRecordingOldApiService() {
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        recorderThread = new Thread(new Runnable() {
            @Override
            public void run() {

            Looper.prepare();

                mCamera = cameraCheck.getDesiredCamera(getApplicationContext(),
                        Camera.CameraInfo.CAMERA_FACING_BACK, handler);

                cameraPreview = new CameraPreview(getApplicationContext(), mCamera);

                handler.post(new Runnable() {
                    @Override
                    public void run() {

                        Toast.makeText(getApplicationContext(), R.string.video_recorder_started, Toast.LENGTH_SHORT).show();
                    }
                });


                mCamera.unlock();
                videoRecorder.setCamera(mCamera);
                videoRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
                videoRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
                videoRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
                videoRecorder.setOutputFile(fileName);
                videoRecorder.setPreviewDisplay(cameraPreview.getHolder().getSurface());

                try {
                    videoRecorder.prepare();
                    videoRecorder.start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        recorderThread.start();

        return START_REDELIVER_INTENT;
    }

    @Override
    public void onCreate() {

        getFileName();
        handler = new Handler();
        videoRecorder = new MediaRecorder();
        cameraCheck = new CameraCheck();


        //Setup Notification
        final Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
        notificationIntent.addCategory("android.intent.category.LAUNCHER");

        final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

        Notification notification;

        notification = new Notification.Builder(getApplicationContext())
                .setSmallIcon(R.drawable.videorecordicon)
                .setOngoing(true)
                .setPriority(Notification.PRIORITY_DEFAULT)
                .setContentTitle(getResources().getString(R.string.video_recorder_notification))
                .setContentText(getResources().getString(R.string.notification_video_text) + "...")
                .setContentIntent(pendingIntent).build();

        startForeground(1, notification);
    }




    @Override
    public void onDestroy() {

        if (videoRecorder != null){

            videoRecorder.stop();
            videoRecorder.release();
            videoRecorder = null;

            Toast.makeText(getApplicationContext(), R.string.recording_done, Toast.LENGTH_SHORT).show();
            recorderThread.interrupt();

            mCamera.lock();

            if (mCamera != null){

                mCamera.stopPreview();
                mCamera.release();
                mCamera = null;
            }
        }

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    public String getFileName (){

        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            fileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
                    + "/" + "video_record" + System.currentTimeMillis() + ".mp4";
        } else {

            Toast.makeText(getApplicationContext(), "No External Storage Found", Toast.LENGTH_LONG).show();
        }

        return fileName;
    }

}

编辑:

这是我修改后的VideoRecordingOldApiService课程:

public class VideoRecordingOldApiService extends Service implements MediaRecorder.OnInfoListener, MediaRecorder.OnErrorListener {


    private Camera mCamera;
    private String outputFile;
    private FrameLayout frameLayout;
    private MediaRecorder mMediaRecorder;
    private CameraCheck cameraCheck;
    private final static String TAG = "VideoRecorderService";
    private CameraPreview cameraPreview;


    public VideoRecordingOldApiService() {
    }


    @Override
    public void onCreate() {

        cameraCheck = new CameraCheck();
        frameLayout = MainActivity.PlaceholderFragment.previewFrameLayout;

        //Setup Notification
        final Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
        notificationIntent.addCategory("android.intent.category.LAUNCHER");

        final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

        Notification notification;

        notification = new Notification.Builder(getApplicationContext())
                .setSmallIcon(R.drawable.videorecordicon)
                .setOngoing(true)
                .setPriority(Notification.PRIORITY_DEFAULT)
                .setContentTitle(getResources().getString(R.string.video_recorder_notification))
                .setContentText(getResources().getString(R.string.notification_video_text) + "...")
                .setContentIntent(pendingIntent).build();

        startForeground(1, notification);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Toast.makeText(getApplicationContext(), R.string.video_recorder_started, Toast.LENGTH_LONG).show();

        if (initCamera()) {

            initRecorder();

        } else {

            Toast.makeText(getApplicationContext(), "Camera not found", Toast.LENGTH_SHORT).show();
        }

        return START_REDELIVER_INTENT;
    }

    @Override
    public void onDestroy() {

        stopRecording();
    }


    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }


    public String getFileName() {

        String fileName = null;

        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            fileName = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
                    + "/" + "video_record" + System.currentTimeMillis() + ".mp4";

            Log.i("Camera Recorder", fileName);
        } else {

            Toast.makeText(getApplicationContext(), "No External Storage Found", Toast.LENGTH_LONG).show();
        }

        return fileName;
    }


    private boolean initCamera() {

        try {

            mCamera = cameraCheck.getDesiredCamera(this, Camera.CameraInfo.CAMERA_FACING_FRONT);
            cameraPreview = new CameraPreview(getApplicationContext(), mCamera);
            frameLayout.addView(cameraPreview);
        } catch (Exception e) {

            Log.v(TAG, "Could not initialise the camera");
            e.printStackTrace();
            return false;

        }

        return true;
    }

    private void initRecorder() {

        if (mMediaRecorder == null) {
            mMediaRecorder = new MediaRecorder();
            outputFile = getFileName();

            try {

                // mCamera.unlock();
                mMediaRecorder.setCamera(mCamera);

                mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
                mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
                mMediaRecorder.setOutputFile(outputFile);
                mMediaRecorder.setPreviewDisplay(cameraPreview.getHolder().getSurface());


                mMediaRecorder.prepare();
                mMediaRecorder.start();
            } catch (Exception e) {
                Log.v(TAG, "MediaRecorder failed to initialize");
                e.printStackTrace();
            }

            mMediaRecorder.setOnInfoListener(this);
            mMediaRecorder.setOnErrorListener(this);
        }
    }



        @Override
        public void onInfo (MediaRecorder mr,int what, int extra){

        }

        @Override
        public void onError (MediaRecorder mr,int what, int extra){

        }


    private void stopRecording() {

            try {
                mMediaRecorder.stop();
            } catch (Exception e) {

                //This can happen if recorder has already stopped.
                Log.e(TAG, "Got IllegalStateException in stopRecording " + e.getMessage());
            }

            releaseRecorder();
            Toast.makeText(getApplicationContext(), R.string.recording_done, Toast.LENGTH_SHORT).show();
            releaseCamera();

    }

    private void releaseRecorder() {

        if (mMediaRecorder != null) {

            mMediaRecorder.reset();
            mMediaRecorder.release();
            mMediaRecorder = null;
        }
    }

    private void releaseCamera() {

        if (mCamera != null) {

            //mCamera.lock();

            mCamera.release();
            mCamera = null;
        }

    }
}

我现在正在获取相机预览。MediaRecorder 正在目录中创建文件,但不知何故我仍在IllegalStateException继续onStop()。有人可以帮忙吗????

4

0 回答 0