如何修复 Android 模拟器中的“无法连接到相机服务”异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26305107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:13:56  来源:igfitidea点击:

How to fix "Fail to connect to camera service" exception in Android emulator

androidcameraandroid-emulatoremulationintellij-13

提问by Alyoshak

I'm getting a Fail to connect to camera service exception when I run my Android app in the emulator. I've read the various existing posts but none have fixed this. It is clearly the Camera.open() call which is failing. I would eventually like to get the webcam going in the emulator, as many SO posts discuss, but right now just want the app to run without bombing. I do not care whether any camera video gets shown or not, since there are other features besides the camera that I need to test, and will primarily test the camera on my device anyway.

当我在模拟器中运行我的 Android 应用程序时,出现无法连接到相机服务异常。我已经阅读了各种现有的帖子,但没有一个解决了这个问题。显然是 Camera.open() 调用失败了。我最终想让网络摄像头在模拟器中运行,正如许多 SO 帖子所讨论的那样,但现在只想让应用程序在不爆炸的情况下运行。我不在乎是否显示任何摄像头视频,因为除了摄像头之外还有其他功能需要测试,并且主要是在我的设备上测试摄像头。

My manifest seems to be ok. The following lines are in it:

我的清单似乎没问题。其中有以下几行:

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

In my AVD manager I have set both the front and back camera to be "Emulated" and the SD Card value to 64. These seem to be the recommended values. The full stack trace is now below. Solution has to be something straightforward, but what?

在我的 AVD 管理器中,我将前后摄像头都设置为“模拟”,并将 SD 卡值设置为 64。这些似乎是推荐值。完整的堆栈跟踪现在在下面。解决方案必须是直截了当的,但是什么?

10-09 08:14:32.375    2628-2628/com.allinlearning.AILAndroidScanner E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.allinlearning.AILAndroidScanner, PID: 2628
java.lang.RuntimeException: Fail to connect to camera service
        at android.hardware.Camera.native_setup(Native Method)
        at android.hardware.Camera.<init>(Camera.java:350)
        at android.hardware.Camera.open(Camera.java:309)
        at com.allinlearning.AILAndroidScanner.AsynCamPreview.surfaceCreated(AsynCamPreview.java:104)
        at android.view.SurfaceView.updateWindow(SurfaceView.java:572)
        at android.view.SurfaceView.access
import java.io.IOException;
import java.util.List;

import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.SurfaceHolder;
import android.webkit.MimeTypeMap;
import android.widget.ImageView;

public class AsynCamPreview extends MainActivity
        implements SurfaceHolder.Callback,  Camera.PreviewCallback
{

    private Camera mCamera;
    public Camera.Parameters params;
    private SurfaceHolder sHolder;
    private ImageView myCameraPreview = null;
    private Bitmap mBitmap = null;

    // data arrays
    private int[] pixels = null;
    private float[] floatpixels = null;
    private byte[] FrameData = null;

    // Camera params
    public float maxZoom;
    private int imageFormat;
    private int previewSizeWidth;
    private int previewSizeHeight;
    private int camId = 1;

    // flags and counts
    private boolean bProcessing = false;
    private int frameCount = 0;
    private boolean doProcessing = false;
    public boolean mProcessInProgress = false;

    public static final String TAG = "AsynCamPreview";

    private long mTiming[] = new long[50];
    private int mTimingSlot = 0;

    Handler mHandler = new Handler(Looper.getMainLooper());

    static {
//      System.loadLibrary("ImageProcessing");
        Log.i(TAG, "Native library loaded");
    }

    public AsynCamPreview(int previewLayoutWidth, int previewLayoutHeight, ImageView cameraPreview)
    {
        previewSizeWidth = previewLayoutWidth;
        previewSizeHeight = previewLayoutHeight;
        myCameraPreview =cameraPreview;
    }


    @Override
    public void onPreviewFrame(byte[] data, Camera camera)
    {
        // Do nothing for now
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        sHolder = holder;
        if (camId == 0) {
            mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
        }
        else {
            mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
        }

        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.setPreviewCallback(this);
        } catch (IOException e) {
            mCamera.release();
            mCamera= null;
        }

        params = mCamera.getParameters();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
        // TODO Auto-generated method stub
        params = mCamera.getParameters();
        List<Camera.Size> sizes = params.getSupportedPictureSizes();
        this.params.setPreviewSize(previewSizeWidth, previewSizeHeight);

        mBitmap = Bitmap.createBitmap(previewSizeWidth, previewSizeHeight,
                Bitmap.Config.ARGB_8888);
        myCameraPreview.setImageBitmap(mBitmap);

        pixels = new int[previewSizeWidth * previewSizeHeight];
        //floatpixels = new float[previewSizeWidth * previewSizeHeight * 3];
        imageFormat = params.getPreviewFormat();
        mCamera.setParameters(params);
        mCamera.startPreview();

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }

    @Override
    public void onPause() {
        this.mCamera.stopPreview();
    }

}
0(SurfaceView.java:86) at android.view.SurfaceView.onPreDraw(SurfaceView.java:175) at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1871) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761) at android.view.Choreographer.doCallbacks(Choreographer.java:574) at android.view.Choreographer.doFrame(Choreographer.java:544) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) 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:779) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) at dalvik.system.NativeStart.main(Native Method)

The code for the entire class is below. Again, it's the Camera.open() call that throws the exception:

整个类的代码如下。同样,引发异常的是 Camera.open() 调用:

try {
    releaseCameraAndPreview();
    if (camId == 0) {
        mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
    }
    else {
        mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
    }
} catch (Exception e) {
    Log.e(getString(R.string.app_name), "failed to open Camera");
    e.printStackTrace();
}

回答by aProperFox

From the Android Developers Docs:

来自Android 开发者文档

Calling Camera.open() throws an exception if the camera is already in use by another application, so we wrap it in a try block.

如果相机已被另一个应用程序使用,则调用 Camera.open() 会引发异常,因此我们将其包装在 try 块中。

Try wrapping that code in a try catch block like so:

尝试将该代码包装在 try catch 块中,如下所示:

private void releaseCameraAndPreview() {
    myCameraPreview.setCamera(null);
    if (mCamera != null) {
        mCamera.release();
        mCamera = null;
    }
}

Then add this function somewhere:

然后在某处添加这个函数:

    //If authorisation not granted for camera
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
        //ask for authorisation
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 50);
    else
        //start your camera
        this.startCamera();

回答by lucasddaniel

回答by Kevin ABRIOUX

With Android 6.0, this error can appened if you don't check for manifest authorisation :

在 Android 6.0 中,如果您不检查清单授权,则可能会出现此错误:

if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
  ActivityCompat.requestPermissions(CodeScanner.this, new String[]{android.Manifest.permission.CAMERA}, 50);
}

回答by Adam Johns

OP mentions this in his question, but my issue was I forgot to enable camera emulation in my AVD emulator settings:

OP 在他的问题中提到了这一点,但我的问题是我忘记在我的 AVD 模拟器设置中启用相机模拟:

enter image description here

在此处输入图片说明

回答by Arnyminer Z

Using

使用

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

worked for me

为我工作

回答by Dattatray Nande

1.Use below permissions in manifest file and always put permissions above Application tag.

1.在清单文件中使用以下权限,并始终将权限放在应用程序标签上方。

camera.unlock();
recorder.setCamera(camera);

2.Use Unlock while camera used by other service like MediaRecorder.

2.在MediaRecorder等其他服务使用相机时使用解锁。

if (camera != null) {
        camera.lock();
        camera.stopPreview();
        camera.release();
        camera = null;
    }

2.Released camera properly, I prefer to use lock so become safely accessible for other application and second time use (In case if we reopen).

2.正确释放相机,我更喜欢使用锁,以便其他应用程序和第二次使用可以安全访问(以防我们重新打开)。

private void releaseCameraAndPreview() {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCameraView.getHolder().removeCallback(mCameraView);
            mCamera.release();
            mCamera = null;
        }
    }

回答by nicolas asinovich

If you periodically got a white screen instead your view of camera - use:

如果您定期看到白屏而不是您的相机视图 - 使用:

try {
            releaseCameraAndPreview();
            mCamera = getCameraInstance();
        }...

and put it here

并把它放在这里

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

and here

和这里

 Observable.create(CameraUtils.getCameraOnSubscribe())
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(camera -> {

                 mCamera = camera.open();
...    
}};

回答by varnith kumar

If you are using surface View and using code like this`

如果您正在使用表面视图并使用这样的代码`

##代码##

Then replace mCamera=camera;

然后替换 mCamera=camera;