Why does my app crash when using android.hardware.Camera.Open()?

10.7k views Asked by At

I am re-writing an app for most versions of Android. The app is set to call android.hardware.Camera.Open() on launch. When the app launches it gives the error Camera Error: Could not connect to camera

The permissions in AndroidManifest.xml are

<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.camera"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>`.

Why can't it connect to the camera?

3

There are 3 answers

1
stringlapse On BEST ANSWER

Problem solved!

The issue was simply a matter of capitalization. The line <uses-permission android:name="android.permission.camera"/> should actually read <uses-permission android:name="android.permission.CAMERA"/>. This happened because camera is a hardware feature, while CAMERA is a permission.

8
ArturS On

In previous versions of android in order to use camera hardware there was enough to state proper permissions and uses in android manifest, but since the Marshmallow version has appeared it's not enough to run the app anymore. As there is also need to enable runtime permissions. Consider using similar code, and suit it to your project, as it gives You opportunity to check and enable permission.

  @Override
public void onRequestPermissionsResult(int requestCode,  String[] permissions, int[] grantResults) {
    if (requestCode == PERMISSION_REQUEST_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            cameraPreview.initializeCamera();
        } else {

        }
        return;
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == PERMISSION_REQUEST_CODE) {
        cameraPreview.initializeCamera();
        return;
    }
    super.onActivityResult(requestCode, resultCode, data);
}


   public void requestCameraPermission() {
    ActivityCompat.requestPermissions(this,
            new String[]{
                    Manifest.permission.CAMERA
            },
            PERMISSION_REQUEST_CODE);
}

public void requestPermissionWithRationale() {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
        Snackbar.make(findViewById(android.R.id.content), R.string.no_cam_permission, Snackbar.LENGTH_INDEFINITE)
                .setAction(R.string.snackbar_action_grant, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        requestCameraPermission();
                    }
                })
                .show();
    } else {
        requestCameraPermission();
    }
}
1
Raut Darpan On

Use Camera for Deprecated

Below is the code

UPDATE --->

  @Module
public class CameraModule {

    @Provides
    CameraSupport provideCameraSupport() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return new CameraNew(context);
        } else {
            return new CameraOld();
        }
    }
}

and then for Old target :

 @SuppressWarnings("deprecation")
public class CameraOld implements CameraSupport {

    private Camera camera;

    @Override
    public CameraSupport open(final int cameraId) {
        this.camera = Camera.open(cameraId);
        return this;
    }

    @Override
    public int getOrientation(final int cameraId) {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraId, info);
        return info.orientation;
    }
}

for New Target :

  public class CameraNew implements CameraSupport {

    private CameraDevice camera;
    private CameraManager manager;

    public CameraNew(final Context context) {
        this.manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public CameraSupport open(final int cameraId) {
        try {
            String[] cameraIds = manager.getCameraIdList();
            if (ActivityCompat.checkSelfPermission(CameraPreview.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.

                return null;
            }
            manager.openCamera(cameraIds[cameraId], new CameraDevice.StateCallback() {
                @Override
                public void onOpened(CameraDevice camera) {
                    CameraNew.this.camera = camera;
                }

                @Override
                public void onDisconnected(CameraDevice camera) {
                    CameraNew.this.camera = camera;
                    // TODO handle
                }

                @Override
                public void onError(CameraDevice camera, int error) {
                    CameraNew.this.camera = camera;
                    // TODO handle
                }
            }, null);
        } catch (Exception e) {
            // TODO handle
        }
        return this;
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public int getOrientation(final int cameraId) {
        try {
            String[] cameraIds = manager.getCameraIdList();
            CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraIds[cameraId]);
            return characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
        } catch (CameraAccessException e) {
            // TODO handle
            return 0;
        }
    }
}