Подтвердить что ты не робот

Как исправить ошибку "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();
    }

}
4b9b3361

Ответ 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;
    }
}

Ответ 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;