Как исправить ошибку "Fail to connect to camera service" в Android-эмуляторе
Я получаю сообщение об ошибке для подключения к исключению службы камеры, когда запускаю приложение для 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 я установил переднюю и заднюю камеры как "Emulated", а значение SD Card - 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();
}
}
Ответы
Ответ 1
Из Android Developers Docs:
Вызов Camera.open() выдает исключение, если камера уже используется другим приложением, поэтому мы завершаем его в блок try.
Попробуйте обернуть этот код в блок catch try следующим образом:
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;
}
}
Ответ 2
Не разрешено ли на android 6.x?
http://developer.android.com/training/permissions/requesting.html
Ответ 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
OP упоминает об этом в своем вопросе, но в моей проблеме я забыл включить эмуляцию камеры в настройках эмулятора AVD:
![введите описание изображения здесь]()
Ответ 5
Использование
if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(CodeScanner.this, new String[]{android.Manifest.permission.CAMERA}, 50);
}
работал у меня
Ответ 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.
camera.unlock();
recorder.setCamera(camera);
2.Реалированная камера должным образом, я предпочитаю использовать блокировку, чтобы она стала безопасно доступной для другого приложения и использования во второй раз (в случае, если мы снова открываем).
if (camera != null) {
camera.lock();
camera.stopPreview();
camera.release();
camera = null;
}
Ответ 7
Если вы периодически получаете белый экран вместо своего вида камеры - используйте:
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();
}
Ответ 8
Если вы используете Surface View и используете такой код, как этот
Observable.create(CameraUtils.getCameraOnSubscribe())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(camera -> {
mCamera = camera.open();
...
}};
Затем замените mCamera = camera;