【问题标题】:android java.lang.RuntimeException:Fail to connect to camera service using SurfaceViewandroid java.lang.RuntimeException: 无法使用 SurfaceView 连接到相机服务
【发布时间】:2018-06-18 09:14:20
【问题描述】:

我收到异常 java.lang.RuntimeException:重新打开同一活动时无法连接到相机服务。 第一次代码可以正常工作而无需捕获视频文件(仅相机预览)。但是在完成 MainActivity 之后。如果我再次调用 Mainactivity 那么对于 mCamera = Camera.open(0);它抛出异常 我检查了有关 stackoverflow 的问题,但没有一个解决方案适用。

代码

public class MainActivity extends AppCompatActivity  implements SurfaceHolder.Callback, View.OnClickListener {
    private VideoView videoView = null;
    private MediaController mc = null;
    private SurfaceHolder surfaceHolder;
    private SurfaceView surfaceView;
    public MediaRecorder mediaRecorder = new MediaRecorder();
    private Camera mCamera;
    private Button btnStart;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        surfaceView = (SurfaceView) findViewById(R.id.surface_camera);

        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        btnStart = (Button) findViewById(R.id.btnStart);
        btnStart.setOnClickListener(this);
        if (mCamera == null) {
            mCamera = Camera.open(0);
            Camera.Parameters params = mCamera.getParameters();
            mCamera.setParameters(params);
            mCamera.setDisplayOrientation(90);

        }

    }

    @SuppressLint("NewApi")
    protected void startRecording() throws IOException {


        File sdCard = Environment.getExternalStorageDirectory();
        File dir = new File(sdCard.getAbsolutePath() + "/myVideos");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        Date date = new Date();
        String fileName =  "/rec" + date.toString().replace(" ", "_").replace(":", "_") + ".mp4";
        File file = new File(dir, fileName);

        mediaRecorder = new MediaRecorder();
        mCamera.lock();
        mCamera.unlock();

        mediaRecorder.setCamera(mCamera);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
        mediaRecorder.setOutputFile(dir + fileName);
        mediaRecorder.setOrientationHint(90);
        mediaRecorder.prepare();
        mediaRecorder.start();
        refreshGallery(file);
    }

    private void refreshGallery(File file) {
        Intent mediaScanIntent = new Intent(
                Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        mediaScanIntent.setData(Uri.fromFile(file));
        sendBroadcast(mediaScanIntent);
    }



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

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (mCamera != null) {

            try {
                if (mCamera != null) {
                    mCamera.setPreviewDisplay(surfaceHolder);
                    mCamera.startPreview();
                    mCamera.unlock();


                }
            }
            catch(Exception ex)
            {

                ex.printStackTrace();
            }
        } else {
            Toast.makeText(getApplicationContext(), "Camera not available!",
                    Toast.LENGTH_LONG).show();
            finish();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mCamera.stopPreview();
        mCamera.setPreviewCallback(null);
        mCamera.release();
        mCamera = null;

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnStart:
                if (btnStart.getText().toString().equalsIgnoreCase("Start")) {
                    btnStart.setText("Stop");
                    try {
                        startRecording();
                    } catch (IOException e) {
                        String message = e.getMessage();
                        Log.i(null, "Problem " + message);
                        mediaRecorder.release();
                        e.printStackTrace();
                    }
                } else {
                    btnStart.setText("Start");
                    mediaRecorder.stop();
                    mediaRecorder.release();
                    mediaRecorder = null;
                }
                break;

            default:
                break;
        }
    }
   @Override
public void onDestroy()
{
    super.onDestroy();

    if(mCamera!=null) {
        mCamera.stopPreview();
        mCamera.setPreviewCallback(null);
        mCamera.release();
        mCamera = null;
   }

}

    @Override
    public void onBackPressed()
    {

        Intent intent=new Intent(MainActivity.this,FirstActivityActivity.class);
        startActivity(intent);
        super.onBackPressed();


    }
}

谁能告诉我,代码有什么问题?

这里是日志猫

FATAL EXCEPTION: main
    Process: com.example.surfaceviewrecord, PID: 11717
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.surfaceviewrecord/com.example.surfaceviewrecord.MainActivity}: 
    java.lang.RuntimeException: Fail to connect to camera service
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5776)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
     Caused by: java.lang.RuntimeException: Fail to connect to camera service
        at android.hardware.Camera.<init>(Camera.java:647)
        at android.hardware.Camera.open(Camera.java:489)
        at com.example.surfaceviewrecord.MainActivity.onCreate(MainActivity.java:47)
        at android.app.Activity.performCreate(Activity.java:6582)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667) 
        at android.app.ActivityThread.-wrap11(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494) 
        at android.os.Handler.dispatchMessage(Handler.java:111) 
        at android.os.Looper.loop(Looper.java:207) 
        at android.app.ActivityThread.main(ActivityThread.java:5776) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

清单文件中的权限

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

【问题讨论】:

    标签: android surfaceview surfaceholder


    【解决方案1】:

    您需要从棉花糖及以上应用运行时相机权限。所以在这里你没有相机权限,这就是发生这个错误的原因。

    请查看Link

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseMediaRecorder();
        if (camera != null) {
            camera.stopPreview();
            camera.setPreviewCallback(null);
            camera.release();
            camera = null;
        }
    }
    
    private void releaseMediaRecorder() {
        if (mediaRecorder != null) {
            mediaRecorder.release(); // release the recorder object
            mediaRecorder = null;
        }
    }
    

    请检查上面的代码并放入 onDestroy() 方法。

    【讨论】:

    • 我已经添加了运行时权限。并且还检查了设置。
    • 哦,你在 onDestroy() 释放相机了吗?
    • 请在 surfaceDestroyed() 方法中写入日志并检查实际发生的情况。我认为这里出了点问题。
    • surfaceDestroyed() 工作正常我调试代码并将相机设置为 null。该代码中没有问题
    • 哦,...请在此步骤中检查,1)打开您的应用程序相机(MainActivity,正如您所说的第一次打开时不会失败)2)然后关闭主要活动然后尝试打开您的手机设备摄像头(可能无法正常打开并引发与我预期相同的错误)。请检查这些东西并更新我的信息。所以我可以在这里为您提供适当的帮助。
    猜你喜欢
    • 2011-10-16
    • 2020-12-03
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多