エミュレータでAndroidアプリを実行すると、カメラへの接続に失敗するという例外が発生します。さまざまな既存の投稿を読みましたが、これを修正したものはありません。 .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();
}
}
カメラが別のアプリケーションで既に使用されている場合、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;
}
}
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();
を使用して
if (ContextCompat.checkSelfPermission(getApplicationContext(), Android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(CodeScanner.this, new String[]{Android.Manifest.permission.CAMERA}, 50);
}
私のために働いた
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.カメラを適切にリリースしました。ロックを使用するので、他のアプリケーションや2回目の使用のために安全にアクセスできるようになります(再度開く場合)。
if (camera != null) {
camera.lock();
camera.stopPreview();
camera.release();
camera = null;
}
カメラのビューの代わりに白い画面が定期的に表示される場合-次を使用します:
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();
}