Je reçois une exception d'échec de connexion au service de caméra lorsque j'exécute mon application Android dans l'émulateur. J'ai lu les divers articles existants, mais aucun n'a résolu ce problème. C'est clairement l'appel Camera.open () qui échoue. J'aimerais finalement que la webcam soit connectée à l'émulateur, comme le stipulent de nombreux messages SO, mais pour l'instant, je veux simplement que l'application s'exécute sans bombardement. Je me moque de savoir si une vidéo de caméra est affichée ou non, car il y a d'autres fonctionnalités que la caméra que je dois tester, et testera principalement la caméra sur mon appareil.
Mon manifeste semble être ok. Les lignes suivantes sont dedans:
<uses-feature Android:name="Android.hardware.camera" />
<uses-feature Android:name="Android.hardware.camera.autofocus" />
<uses-permission Android:name="Android.permission.CAMERA"></uses-permission>
Dans mon gestionnaire AVD, j'ai défini les caméras avant et arrière sur "Emulé" et la valeur de la carte SD sur 64. Celles-ci semblent être les valeurs recommandées. La trace de pile complète est maintenant en dessous. La solution doit être simple, mais quoi?
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)
Le code pour toute la classe est ci-dessous. Encore une fois, c'est l'appel Camera.open () qui lève l'exception:
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();
}
}
Depuis le Documents pour développeurs Android :
L'appel de Camera.open () lève une exception si la caméra est déjà utilisée par une autre application. Nous l'enveloppons donc dans un bloc try.
Essayez d’emballer ce code dans un bloc catch try comme suit:
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();
}
Ajoutez ensuite cette fonction quelque part:
private void releaseCameraAndPreview() {
myCameraPreview.setCamera(null);
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
Une autorisation sur Android 6.x n'est-elle pas?
http://developer.Android.com/training/permissions/requesting.html
Avec Android 6.0, cette erreur peut survenir si vous ne vérifiez pas l’autorisation du manifeste:
//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();
En utilisant
if (ContextCompat.checkSelfPermission(getApplicationContext(), Android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(CodeScanner.this, new String[]{Android.Manifest.permission.CAMERA}, 50);
}
a travaillé pour moi
1.Utilisez les autorisations ci-dessous dans le fichier manifeste et mettez toujours les autorisations au-dessus de la balise 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.Utilisez Déverrouiller lorsque l'appareil photo est utilisé par un autre service tel que MediaRecorder.
camera.unlock();
recorder.setCamera(camera);
2. Caméra relâchée correctement, je préfère utiliser le verrou afin de devenir facilement accessible pour une autre application et une deuxième utilisation (dans le cas où nous rouvririons).
if (camera != null) {
camera.lock();
camera.stopPreview();
camera.release();
camera = null;
}
Si vous avez régulièrement un écran blanc à la place de votre vision de la caméra, utilisez:
private void releaseCameraAndPreview() {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCameraView.getHolder().removeCallback(mCameraView);
mCamera.release();
mCamera = null;
}
}
et le mettre ici
try {
releaseCameraAndPreview();
mCamera = getCameraInstance();
}...
et ici
@Override
protected void onPause() {
super.onPause();
releaseCameraAndPreview();
}