如何修复 Android 模拟器中的“无法连接到相机服务”异常
Posted
技术标签:
【中文标题】如何修复 Android 模拟器中的“无法连接到相机服务”异常【英文标题】:How to fix "Fail to connect to camera service" exception in Android emulator 【发布时间】:2014-12-05 23:00:54 【问题描述】:当我在模拟器中运行我的 android 应用程序时,我遇到了无法连接到相机服务的异常。我已经阅读了各种现有的帖子,但都没有解决这个问题。显然是 Camera.open() 调用失败了。正如许多 SO 帖子所讨论的那样,我最终希望让网络摄像头进入模拟器,但现在只想让应用程序在不被轰炸的情况下运行。我不在乎是否显示任何摄像头视频,因为除了摄像头之外,我还需要测试其他功能,并且无论如何我都会主要在我的设备上测试摄像头。
我的清单似乎没问题。里面有以下几行:
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
在我的 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$000(SurfaceView.java:86)
at android.view.SurfaceView$3.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)
整个类的代码如下。同样,引发异常的是 Camera.open() 调用:
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();
【问题讨论】:
你能发布Java代码吗?还有整个堆栈跟踪? 泰勒,我已根据您的要求更新了问题。 谢谢,虽然我们可能需要更多的 Java 代码。可以发全班吗?我猜是 mCamera 的声明没有正确完成。 除了尝试打开它之外,一旦设置了 Camera var,似乎并没有做太多事情。但是这段代码在我的设备的 Eclipse 项目中运行良好(我现在在模拟器上的 IntelliJ 中) 【参考方案1】:来自Android Developers Docs:
如果相机已被另一个应用程序使用,则调用 Camera.open() 会引发异常,因此我们将其包装在 try 块中。
尝试将代码包装在 try catch 块中,如下所示:
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();
然后在某处添加这个函数:
private void releaseCameraAndPreview()
myCameraPreview.setCamera(null);
if (mCamera != null)
mCamera.release();
mCamera = null;
【讨论】:
在我看来,调用 releaseCameraAndPreview() 是真正解决问题的方法。相机一定是在不知何故被使用,虽然我不知道怎么用。无论如何,为什么 myCameraPreview.setCamera(null) 调用?我不得不评论它。 myCameraPreview 上没有 setCamera() 方法,它是一个 ImageView 对象。 我刚刚从 Android Dev Docs 中获取了它。我认为可能需要使用 mcamera = null; 来初始化相机。我的研究表明,大多数人都需要添加这个。或者只是相机正在被另一个应用程序使用:P 我只想说明,如果设备上的摄像头不工作,也会出现这个错误。 @Alyoshak:可能发生这种情况的一种情况:Facebook 视频通话最小化会创建一个较小的视频通话对话框,并且不会释放摄像头。当您从另一个应用程序使用相机时,您会收到此错误。 什么是 myCameraPreview?【参考方案2】:OP 在他的问题中提到了这一点,但我的问题是我忘记在我的 AVD 模拟器设置中启用相机模拟:
【讨论】:
我已经在 AVD 中启用了此选项,但我的模拟器中仍然出现此错误。我错过了什么吗? 我已经在 AVD 中启用了此选项,但我的模拟器中仍然出现此错误。我错过了什么吗?【参考方案3】:在 Android 6.0 中,如果您不检查清单授权,可能会出现此错误:
//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();
【讨论】:
【参考方案4】:使用
if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(CodeScanner.this, new String[]android.Manifest.permission.CAMERA, 50);
为我工作
【讨论】:
这里一样,完全忘记了新的android需要运行时权限:-)【参考方案5】:如果您定期看到白屏而不是您的相机视图 - 使用:
private void releaseCameraAndPreview()
if (mCamera != null)
mCamera.setPreviewCallback(null);
mCameraView.getHolder().removeCallback(mCameraView);
mCamera.release();
mCamera = null;
放在这里
try
releaseCameraAndPreview();
mCamera = getCameraInstance();
...
这里
@Override
protected void onPause()
super.onPause();
releaseCameraAndPreview();
【讨论】:
【参考方案6】:1.在清单文件中使用以下权限,并始终将权限放在应用程序标记之上。
<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" />
2.在 MediaRecorder 等其他服务使用相机时使用 Unlock。
camera.unlock();
recorder.setCamera(camera);
2.正确释放相机,我更喜欢使用锁定,以便其他应用程序和第二次使用安全访问(以防我们重新打开)。
if (camera != null)
camera.lock();
camera.stopPreview();
camera.release();
camera = null;
【讨论】:
【参考方案7】:如果您正在使用表面视图并使用这样的代码`
Observable.create(CameraUtils.getCameraOnSubscribe())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(camera ->
mCamera = camera.open();
...
;
然后替换 mCamera=camera;
【讨论】:
以上是关于如何修复 Android 模拟器中的“无法连接到相机服务”异常的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 React Native 中的 Firebase/firestore 错误?