如何修复Camera Instance Opening失败?

时间:2017-04-12 13:49:19

标签: android android-layout android-fragments

经过这么长时间的斗争。我发现问题无法找到解决方案。我有一个按钮点击它的活动启动一个打开相机的片段。我遵循了这个tutorial,并添加了带有错误日志的创建视图的代码。

P.S:我已经添加了所有权限。



 public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_scan, container, false);

        if(checkCameraHardware(getActivity().getApplicationContext())){
            getCameraInstance();
            mCamera = getCameraInstance();
            mPreview = new CameraPreview(this.getActivity(), mCamera);

            //container.addView(mPreview);--->Remove this line
            //Add this line
            FrameLayout preview =(FrameLayout)view.findViewById(R.id.camera_preview);
            preview.addView(mPreview);
        }
        // Inflate the layout for this fragment
        return view;
    }






public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }






//permissions

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

&#13;
&#13;
//error log

D/tag:  C not null
W/CameraBase: An error occurred while connecting to camera: 0
D/tag2: cannot get Camera Instance
W/System.err: java.lang.RuntimeException: Fail to connect to camera service
W/System.err:     at android.hardware.Camera.native_setup(Native Method)
W/System.err:     at android.hardware.Camera.<init>(Camera.java:469)
W/System.err:     at android.hardware.Camera.open(Camera.java:442)
W/System.err:     at layout.scan.getCameraInstance(scan.java:113)
W/System.err:     at layout.scan.onCreateView(scan.java:84)
W/System.err:     at android.app.Fragment.performCreateView(Fragment.java:1700)
W/System.err:     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
W/System.err:     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
W/System.err:     at android.app.BackStackRecord.run(BackStackRecord.java:698)
W/System.err:     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
W/System.err:     at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:808)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:103)
W/System.err:     at android.os.Looper.loop(Looper.java:193)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5330)
W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err:     at java.lang.reflect.Method.invoke(Method.java:515)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
W/System.err:     at dalvik.system.NativeStart.main(Native Method)
D/SurfaceView: checkGLSurfaceViewlLogProperty get invalid command
I/SurfaceView: updateWindow -- onWindowVisibilityChanged, visibility = 0
I/Choreographer: Skipped 31 frames!  The application may be doing too much work on its main thread.
D/GraphicBuffer: close handle(0x6169bce0) (w:720 h:1280 f:1)
D/GraphicBuffer: close handle(0x623215a8) (w:720 h:1280 f:1)
D/GraphicBuffer: close handle(0x61daa2a8) (w:720 h:1280 f:1)
D/GraphicBuffer: close handle(0x61db12f8) (w:720 h:1280 f:1)
D/GraphicBuffer: create handle(0x61db12f8) (w:720, h:1280, f:1)
I/MaliEGL: [Mali]window_type=1, is_framebuffer=0, errnum = 0
I/MaliEGL: [Mali]surface->num_buffers=4, surface->num_frames=3, win_min_undequeued=1
I/MaliEGL: [Mali]max_allowed_dequeued_buffers=3
D/GraphicBuffer: close handle(0x61db12f8) (w:720 h:1280 f:1)
D/GraphicBuffer: create handle(0x61db12f8) (w:720, h:1280, f:1)
I/SurfaceView: updateWindow -- setFrame
I/SurfaceView: updateWindow -- OnPreDrawListener, mHaveFrame = true
I/SurfaceView: Changes: creating=true format=true size=true visible=true left=true top=true mUpdateWindowNeeded=false mReportDrawNeeded=false redrawNeeded=false forceSizeChanged=true mVisible=false mRequestedVisible=true
I/SurfaceView: Cur surface: Surface(name=null)/@0x42481d80
V/SurfaceView: layout.CameraPreview{42481ad8 V.E..... ......ID 0,0-720,1118} got resized: w=720 h=1118, cur w=-1 h=-1
I/SurfaceView: New surface: Surface(name=null)/@0x42481e50, vis=true, frame=Rect(0, 162 - 720, 1280)
I/SurfaceView: Callback --> surfaceCreated
I/SurfaceView: surfaceCreated callback +
I/SurfaceView: finishedDrawing
D/AndroidRuntime: Shutting down VM
W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41a2fcf8)
W/dalvikvm: threadid=1: uncaught exception occurred
W/System.err: java.lang.NullPointerException
W/System.err:     at layout.CameraPreview.surfaceCreated(CameraPreview.java:37)
W/System.err:     at android.view.SurfaceView.updateWindow(SurfaceView.java:662)
W/System.err:     at android.view.SurfaceView.access$000(SurfaceView.java:90)
W/System.err:     at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:195)
W/System.err:     at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847)
W/System.err:     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2191)
W/System.err:     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1189)
W/System.err:     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6223)
W/System.err:     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788)
W/System.err:     at android.view.Choreographer.doCallbacks(Choreographer.java:591)
W/System.err:     at android.view.Choreographer.doFrame(Choreographer.java:560)
W/System.err:     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:808)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:103)
W/System.err:     at android.os.Looper.loop(Looper.java:193)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5330)
W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err:     at java.lang.reflect.Method.invoke(Method.java:515)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
W/System.err:     at dalvik.system.NativeStart.main(Native Method)
W/dalvikvm: threadid=1: calling UncaughtExceptionHandler
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.root.meeransunday, PID: 3179
                  java.lang.NullPointerException
                      at layout.CameraPreview.surfaceCreated(CameraPreview.java:37)
                      at android.view.SurfaceView.updateWindow(SurfaceView.java:662)
                      at android.view.SurfaceView.access$000(SurfaceView.java:90)
                      at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:195)
                      at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847)
                      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2191)
                      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1189)
                      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6223)
                      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788)
                      at android.view.Choreographer.doCallbacks(Choreographer.java:591)
                      at android.view.Choreographer.doFrame(Choreographer.java:560)
                      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774)
                      at android.os.Handler.handleCallback(Handler.java:808)
                      at android.os.Handler.dispatchMessage(Handler.java:103)
                      at android.os.Looper.loop(Looper.java:193)
                      at android.app.ActivityThread.main(ActivityThread.java:5330)
                      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:828)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
                      at dalvik.system.NativeStart.main(Native Method)
&#13;
&#13;
&#13;

&#13;
&#13;
//One more method Just to add detail
    public static Camera getCameraInstance(){
        Camera c = null;
        try {

            c = Camera.open(); // attempt to get a Camera instance
        if(c!=null)
        {
           Log.d("tag"," C not null");
        }
        }
        catch (Exception e)
        {
            Log.d("tag2","cannot get Camera Instance");
            e.printStackTrace();
        }
        return c; // returns null if camera is unavailable
    }
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:0)

使用以下方法

android.hardware.Camera.open(int cameraId)

你应该传递cameraId,如果你想要前置摄像头,你可以使用以下方法

private int findFrontFacingCamera() {

    // Search for the front facing camera
    int numberOfCameras = Camera.getNumberOfCameras();
    for (int i = 0; i < numberOfCameras; i++) {
        CameraInfo info = new CameraInfo();
        Camera.getCameraInfo(i, info);
        if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
            cameraId = i;
            cameraFront = true;
            break;
        }
    }
    return cameraId;
}

如果其他应用程序打开了同一个摄像头,则会抛出RuntimeException。 使用完相机后必须调用release(),否则它将保持锁定状态并且对其他应用程序不可用。 您的应用程序一次只能为一个特定的硬件摄像头激活一个Camera对象。 如果这不起作用,请告诉我。

答案 1 :(得分:0)

在更改相机的朝向之前,请确保停止预览并释放相机。 如果您正在看摄像机,并且立即调用面向摄像机的设置并开始预览,则会抛出诸如“无法连接摄像机服务”之类的错误。

我在这里添加了停止和释放相机的功能。

void stop() {
    Log.w(TAG,"stop");
    if (mCamera != null) {
        mCamera.stopPreview();
    }
    mShowingPreview = false;
    releaseCamera();
}


 private void releaseCamera() {
    Log.w(TAG,"releaseCamera");
    if (mCamera != null) {
        mCamera.release();
        mCamera = null;
        mCallback.onCameraClosed();
    }
}

将此功能放到camera1或camera2 api类中。 只需在更改和设置头像之前停止,如下面的代码所示即可。

void setFacing(int facing) {
    Log.w(TAG,"setFacing: "+facing);
    if (mFacing == facing) {
        Log.w(TAG,"Same Facing return");
        return;
    }
    mFacing = facing;
    if (isCameraOpened()) {
        Log.w(TAG,"Camera is Opened");
        stop();
        start();
    }else{
        Log.w(TAG,"Camera is Not Opened");
    }
}