当我在模拟器中运行我的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();
}
}
答案 0 :(得分:35)
如果相机已被其他应用程序使用,则调用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;
}
}
答案 1 :(得分:18)
不是android 6.x的权限吗?
http://developer.android.com/training/permissions/requesting.html
答案 2 :(得分:8)
对于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();
答案 3 :(得分:7)
答案 4 :(得分:5)
使用
if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(CodeScanner.this, new String[]{android.Manifest.permission.CAMERA}, 50);
}
为我工作
答案 5 :(得分:2)
1.在清单文件中使用以下权限,并始终将权限放在Application标记之上。
<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等其他服务使用的相机时使用解锁。
camera.unlock();
recorder.setCamera(camera);
2.正确发布相机,我更喜欢使用锁定,以便安全地进行其他应用和第二次使用(如果我们重新打开)。
if (camera != null) {
camera.lock();
camera.stopPreview();
camera.release();
camera = null;
}
答案 6 :(得分:1)
如果您定期使用白色屏幕而不是相机视图 - 请使用:
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();
}
答案 7 :(得分:0)
如果您正在使用Surface View并使用类似的代码`
EntityManager
然后替换mCamera = camera;