In my project I make a custom camera, but I ran into a small problem, which in turn manifests itself only on Android 6 versions. Here is a method for getting an instance of a camera class that I call in the snippet:

private Camera getCameraInstance() { Camera camera = null; try { camera = Camera.open(); } catch (Exception e) { // cannot get camera or does not exist } return camera; } 

If you go into the body of the open() method, you will see the following code:

  public static Camera open() { int numberOfCameras = getNumberOfCameras(); CameraInfo cameraInfo = new CameraInfo(); for (int i = 0; i < numberOfCameras; i++) { getCameraInfo(i, cameraInfo); if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) { return new Camera(i); } } return null; } 

There are two cameras under debug. And return new Camera(i); is called return new Camera(i); , but in a fragment for some reason null returns that defies any explanation (at least for me). Once again, on the fourth and fifth versions, everything works correctly. The fact that googled - nothing helped.

  • one
    Do you request permission? developer.android.com/intl/ru/training/permissions/… - Yura Ivanov
  • Trace please - Senior Pomidor
  • @YuraIvanov You are right, already started digging in this direction, in 6 you need to request permissions in runtime. - Android Android
  • @YuraIvanov You can post as an answer, I will mark it correct - Android Android

2 answers 2

For Android-M, you should request permissions in runtime. For example, three permissions at once:

 private static final int PERMISSION_REQUEST=1; .... private void checkCamera(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(mContext, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(context, new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA }, PERMISSION_REQUEST); } else { useCamera(); } } else { useCamera(); } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { if (requestCode == PERMISSION_REQUEST) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED && grantResults[2] == PackageManager.PERMISSION_GRANTED) { useCamera(); } } } 

See also https://developer.android.com/intl/ru/training/permissions/requesting.html

    Judging by the source, this constructor can throw exceptions:

     Camera(int cameraId) { int err = cameraInitNormal(cameraId); if (checkInitErrors(err)) { switch(err) { case EACCESS: throw new RuntimeException("Fail to connect to camera service"); case ENODEV: throw new RuntimeException("Camera initialization failed"); default: // Should never hit this. throw new RuntimeException("Unknown camera error"); } } } 

    Based on your code, the camera object will be NULL in this case.