title: Lacking privileges to access camera service in Android 6.0
body: <p>I am using Camera2API in Android 6.0. I was done without error in Android 5.0. However, when I used my code in the Android 6.0, I have a issue. The issue is that sometime I can open the camera successfully and take picture. However, sometime the camera cannot open and it has error</p>
  
  <pre><code>java.lang.SecurityException: Lacking privileges to access camera service
      at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:108)
  </code></pre>
  
  <p>I added the runtime permission as follows:</p>
  
  <pre><code>String[] PERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA};
  if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M){
      if(!hasAllPermissions(this, PERMISSIONS)){
          ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
      }
  }
  
  public static boolean hasAllPermissions(Context context, String... permissions) {
      if (android.os.Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M &amp;&amp; context != null &amp;&amp; permissions != null) {
          for (String permission : permissions) {
              if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                  return false;
              }
          }
      }
      return true;
  }
  </code></pre>
  
  <p>This is all log </p>
  
  <pre><code>FATAL EXCEPTION: main
  Process: com.example.camera2api, PID: 5376
  java.lang.SecurityException: Lacking privileges to access camera service
  at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:108)
  at android.hardware.camera2.utils.CameraBinderDecorator$CameraBinderDecoratorListener.onAfterInvocation(CameraBinderDecorator.java:73)
  at android.hardware.camera2.utils.Decorator.invoke(Decorator.java:81)
  at java.lang.reflect.Proxy.invoke(Proxy.java:393)
  at $Proxy2.cancelRequest(Unknown Source)
  at android.hardware.camera2.impl.CameraDeviceImpl.stopRepeating(CameraDeviceImpl.java:926)
  at android.hardware.camera2.impl.CameraCaptureSessionImpl.close(CameraCaptureSessionImpl.java:378)
  at android.hardware.camera2.impl.CameraCaptureSessionImpl$2.onDisconnected(CameraCaptureSessionImpl.java:514)
  at android.hardware.camera2.impl.CameraDeviceImpl$7.run(CameraDeviceImpl.java:228)
  at android.os.Handler.handleCallback(Handler.java:739)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:158)
  at android.app.ActivityThread.main(ActivityThread.java:7229)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
  </code></pre>
  
  <p>update: For someone who want to look at my full code. I upload my full code here</p>
  
  <p>public class AndroidCamera extends AppCompatActivity {</p>
  
  <pre><code>private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
  
  static {
      ORIENTATIONS.append(Surface.ROTATION_0, 90);
      ORIENTATIONS.append(Surface.ROTATION_90, 0);
      ORIENTATIONS.append(Surface.ROTATION_180, 270);
      ORIENTATIONS.append(Surface.ROTATION_270, 180);
  }
  
  private static final String TAG = "Camera2App";
  private String mImageFileLocation = "";
  private static final int STATE_PREVIEW = 0;
  private static final int STATE_WAIT_LOCK = 1;
  private static final int STATE_WAITING_PRECAPTURE = 2;
  /**
   * Camera state: Waiting for the exposure state to be something other than precapture.
   */
  private static final int STATE_WAITING_NON_PRECAPTURE = 3;
  
  /**
   * Camera state: Picture was taken.
   */
  private static final int STATE_PICTURE_TAKEN = 4;
  private int mState;
  private TextureView mTextureView;
  private Size mPreviewSize;
  
  private String mCameraId;
  String[] PERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA};
  private static final int PERMISSION_ALL = 105;
  private  static final int REQUEST_CAMERA_RESULT = 106;
  private boolean isRegistred=false;
  private int mSensorOrientation;
  private TextureView.SurfaceTextureListener mSurfaceTextureListener =
          new TextureView.SurfaceTextureListener() {
              @Override
              public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                  if (!TextUtils.isEmpty(BleUtils.getCameraLens(AndroidCamera.this)))
                      setupCamera(width, height,BleUtils.getCameraLens(AndroidCamera.this));
                  else
                      setupCamera(width, height,"1");
                  openCamera();
  
              }
  
              @Override
              public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
  
              }
  
              @Override
              public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                  //closeCamera();
  
                  return false;
              }
  
              @Override
              public void onSurfaceTextureUpdated(SurfaceTexture surface) {
  
              }
          };
  private Semaphore mCameraOpenCloseLock = new Semaphore(1);
  private CameraDevice mCameraDevice;
  private CameraDevice.StateCallback mCameraDeviceStateCallback =
          new CameraDevice.StateCallback() {
              @Override
              public void onOpened(CameraDevice camera) {
                  mCameraOpenCloseLock.release();
                  mCameraDevice = camera;
                  //Toast.makeText(getApplicationContext(),"Camera Opened!", Toast.LENGTH_SHORT).show();
                  createCameraPreviewSession();
              }
  
              @Override
              public void onDisconnected(CameraDevice camera) {
                  camera.close();
                  mCameraDevice = null;
  
              }
  
              @Override
              public void onError(CameraDevice camera, int error) {
                  camera.close();
                  mCameraDevice = null;
  
              }
          };
  private CaptureRequest mPreviewCaptureRequest;
  private CaptureRequest.Builder mPreviewCaptureRequestBuilder;
  private CameraCaptureSession mCameraCaptureSession;
  private CameraCaptureSession.CaptureCallback mSessionCaptureCallback
          = new CameraCaptureSession.CaptureCallback() {
  
      private void process(CaptureResult result){
  
          switch (mState){
              case STATE_PREVIEW:
                  break;
              case STATE_WAIT_LOCK:
                  Integer afState=result.get(CaptureResult.CONTROL_AF_STATE);
                  if(afState==CaptureRequest.CONTROL_AF_STATE_FOCUSED_LOCKED){
                      captureStillImage();
                  }
                  else{
                      captureStillImage();
                  }
  
                  break;
          }
  
  
      }
  
      @Override
      public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
          super.onCaptureStarted(session, request, timestamp, frameNumber);
      }
  
      @Override
      public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
          super.onCaptureCompleted(session, request, result);
  
          process(result);
      }
  
      @Override
      public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {
          super.onCaptureFailed(session, request, failure);
          Handler mHandler = new Handler(getMainLooper());
          mHandler.post(new Runnable() {
              @Override
              public void run() {
                  Toast.makeText(getApplicationContext(), "Focus Lock UnSuccesful", Toast.LENGTH_SHORT).show();
              }
          });
  
      }
  };
  
  private HandlerThread mBackgroundThread;
  private Handler mBackgroundHandler;
  private static File mImageFile;
  private ImageReader mImageReader;
  private final ImageReader.OnImageAvailableListener mOnImageAvailableListener =
          new ImageReader.OnImageAvailableListener() {
              @Override
              public void onImageAvailable(ImageReader reader) {
  
                  mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage()));
              }
          };
  
  private static class ImageSaver implements Runnable {
  
  
      private final Image mImage;
  
      private ImageSaver(Image image) {
          mImage = image;
      }
  
      @Override
      public void run() {
  
          ByteBuffer byteBuffer = mImage.getPlanes()[0].getBuffer();
          byte[] bytes = new byte[byteBuffer.remaining()];
          byteBuffer.get(bytes);
  
          FileOutputStream fileOutputStream = null;
  
          try {
  
              fileOutputStream = new FileOutputStream(mImageFile);
              fileOutputStream.write(bytes);
  
          } catch (IOException e) {
              e.printStackTrace();
          } finally {
  
              mImage.close();
              if (fileOutputStream != null) {
                  try {
                      fileOutputStream.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
  
          }
  
      }
  }
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.camera_activity);
      if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M){
          if(!hasAllPermissions(this, PERMISSIONS)){
              ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
          }
      }
  
  
  
  
      mTextureView = (TextureView) findViewById(R.id.texture);
  }
  public static boolean hasAllPermissions(Context context, String... permissions) {
      if (android.os.Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M &amp;&amp; context != null &amp;&amp; permissions != null) {
          for (String permission : permissions) {
              if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                  return false;
              }
          }
      }
      return true;
  }
  @Override
  public void onStart() {
      super.onStart();
      if (!EventBus.getDefault().isRegistered(this)) {
          EventBus.getDefault().register(this);
      }
  }
  //onStop
  @Override
  public void onStop() {
      super.onStop();
      EventBus.getDefault().unregister(this);
  }
  
  
  @Subscribe
  public void onCaptureNumberReceived(OnCaptureEvent event) {
      //get the phone number value here and do something with it
      String capturecode = event.getCodeCapture();
      Log.d(TAG, capturecode);
      if (capturecode.equals("capture")) {
          try {
              mImageFile = createImageFile();
  
          } catch (IOException e) {
              e.printStackTrace();
          }
  
          lockFocus();
          MediaActionSound sound = new MediaActionSound();
          sound.play(MediaActionSound.SHUTTER_CLICK);
      }
      else if(capturecode.equals("end_capture")) {
          finish(); // call this to finish the current activity
          Intent homeIntent = new Intent(Intent.ACTION_MAIN);
          homeIntent.addCategory( Intent.CATEGORY_HOME );
          homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
          startActivity(homeIntent);
      }
  
  }
  
  public void takepicture(View view) {
  
      try {
          mImageFile = createImageFile();
          Log.d("TAG","=====Take picture=====");
  
      } catch (IOException e) {
          e.printStackTrace();
      }
  
      lockFocus();
      MediaActionSound sound = new MediaActionSound();
      sound.play(MediaActionSound.SHUTTER_CLICK);
  }
  
  public void switch_camera(View view) {
      closeCamera();
      //swap the id of the camera to be used
      if(mCameraId == String.valueOf(Camera.CameraInfo.CAMERA_FACING_BACK)){
          mCameraId = String.valueOf(Camera.CameraInfo.CAMERA_FACING_FRONT);
      }
      else {
          mCameraId = String.valueOf(Camera.CameraInfo.CAMERA_FACING_BACK);
      }
      BleUtils.setCameraLens(this, mCameraId);
      if (mTextureView.isAvailable()) {
  
          setupCamera(mTextureView.getWidth(), mTextureView.getHeight(),mCameraId);
          openCamera();
      } else {
          mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
      }
  
  }
  
  File createImageFile() throws IOException {
  
      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
      String imageFileName = "BLE_" + timeStamp + "_";
      File storageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
      if(!storageDirectory.exists()){
          if(!storageDirectory.mkdirs()){
              Log.e("Dir", "Failed to create directory");
              Log.d("MAKE DIR", storageDirectory.mkdir() + "" +  storageDirectory.getParentFile() + "");
              return null;
          }
      }
      File image = File.createTempFile(imageFileName, ".jpg", storageDirectory);
      mImageFileLocation = image.getAbsolutePath();
  
      return image;
  }
  
  @Override
  public void onResume() {
      super.onResume();
      if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M){
          if(!hasAllPermissions(this, PERMISSIONS)){
              ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
          }
      }
      openBackgroundThread();
      if (mTextureView.isAvailable()) {
          if (!TextUtils.isEmpty(BleUtils.getCameraLens(AndroidCamera.this)))
              setupCamera(mTextureView.getWidth(), mTextureView.getHeight(),BleUtils.getCameraLens(AndroidCamera.this));
          else
              setupCamera(mTextureView.getWidth(), mTextureView.getHeight(),"1");
          closeCamera();
          openCamera();
      } else {
          mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
      }
  }
  @Override
  public void onDestroy() {
      super.onDestroy();
      Log.d(TAG,"onDestroy");
  }
  public void onPause() {
      Log.d(TAG,"onPause");
      closeCamera();
  
      closeBackgroundThread();
      super.onPause();
  }
  
  private void setupCamera(int width, int height, String cameraId) {
      CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
      try {
              CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
              StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
  
              Size largestImageSize = Collections.max(
                      Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
                      new Comparator&lt;Size&gt;() {
                          @Override
                          public int compare(Size lhs, Size rhs) {
                              return Long.signum(lhs.getWidth() * lhs.getHeight() -
                                      rhs.getWidth() * rhs.getHeight());
                          }
                      }
              );
              mImageReader = ImageReader.newInstance(largestImageSize.getWidth(),
                      largestImageSize.getHeight(),
                      ImageFormat.JPEG,
                      1);
              mImageReader.setOnImageAvailableListener(mOnImageAvailableListener,
                      mBackgroundHandler);
              mPreviewSize = getPreferredPreviewSize(map.getOutputSizes(SurfaceTexture.class), width, height);
              mCameraId = cameraId;
              Log.d("CAMERA_ID",String.valueOf(mCameraId));
      //    }
  
      } catch (CameraAccessException e) {
          e.printStackTrace();
      }
  }
  
  private Size getPreferredPreviewSize(Size[] mapSizes, int width, int height) {
      List&lt;Size&gt; collectorSizes = new ArrayList&lt;&gt;();
      for (Size option : mapSizes) {
          if (width &gt; height) {
              if (option.getWidth() &gt; width &amp;&amp;
                      option.getHeight() &gt; height) {
                  collectorSizes.add(option);
              }
          } else {
              if (option.getWidth() &gt; height &amp;&amp;
                      option.getHeight() &gt; width) {
                  collectorSizes.add(option);
              }
          }
      }
      if (collectorSizes.size() &gt; 0) {
          return Collections.min(collectorSizes, new Comparator&lt;Size&gt;() {
              @Override
              public int compare(Size lhs, Size rhs) {
                  return Long.signum(lhs.getWidth() * lhs.getHeight() - rhs.getWidth() * rhs.getHeight());
              }
          });
      }
      return mapSizes[0];
  
  }
  
  private void openCamera() {
      CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
      try {
          Log.v("CAMERA", mCameraId + " " + mCameraDeviceStateCallback);
          if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.M){
              if(ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA)
                      == PackageManager.PERMISSION_GRANTED){
                  cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback,mBackgroundHandler);
              }
              else {
                  if (shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA)){
                      Toast.makeText(this,"No Permission to use the Camera services", Toast.LENGTH_SHORT).show();
                  }
                  requestPermissions(new String[] {android.Manifest.permission.CAMERA},REQUEST_CAMERA_RESULT);
              }
          }
          else {
              cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
          }
      } catch (CameraAccessException e) {
          e.printStackTrace();
      }
  
  
  }
  @Override
  public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
      switch (requestCode){
          case  REQUEST_CAMERA_RESULT:
              if (grantResults[0] != PackageManager.PERMISSION_GRANTED){
                  Toast.makeText(this, "Cannot run application because camera service permission have not been granted", Toast.LENGTH_SHORT).show();
              }
              break;
          default:
              super.onRequestPermissionsResult(requestCode, permissions, grantResults);
              break;
      }
  }
  private void closeCamera(){
      if(mCameraCaptureSession!=null){
          mCameraCaptureSession.close();
          mCameraCaptureSession=null;
      }
      if (mCameraDevice!=null){
          mCameraDevice.close();
          mCameraDevice=null;
  
          if(mImageReader!=null){
  
              mImageReader.close();
              mImageReader=null;
  
          }
      }
  }
  private void createCameraPreviewSession(){
      try{
          SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
          surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(),mPreviewSize.getHeight());
          Surface previewSurface= new Surface(surfaceTexture);
          mPreviewCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
          mPreviewCaptureRequestBuilder.addTarget(previewSurface);
          mPreviewCaptureRequestBuilder.set(CaptureRequest.JPEG_QUALITY, (byte)100);
          mCameraDevice.createCaptureSession(Arrays.asList(previewSurface,mImageReader.getSurface()),
                  new CameraCaptureSession.StateCallback() {
                      @Override
                      public void onConfigured(CameraCaptureSession session) {
                          if(mCameraDevice==null){
                              return;
                          }
                          try {
                              mPreviewCaptureRequest = mPreviewCaptureRequestBuilder.build();
                              mCameraCaptureSession = session;
                              mCameraCaptureSession.setRepeatingRequest(
                                      mPreviewCaptureRequest,
                                      mSessionCaptureCallback,
                                      mBackgroundHandler
                              );
  
                          }catch (CameraAccessException e){
                              e.printStackTrace();
                          }
  
                      }
  
                      @Override
                      public void onConfigureFailed(CameraCaptureSession session) {
                          Handler mHandler = new Handler(getMainLooper());
                          mHandler.post(new Runnable() {
                              @Override
                              public void run() {
                                  Toast.makeText(
                                          getApplicationContext(),
                                          "create camera session failed!",
                                          Toast.LENGTH_SHORT
                                  ).show();
                              }
                          });
  
                      }
                  },null);
  
      }catch (CameraAccessException e){
          e.printStackTrace();
      }
  }
  
  private void openBackgroundThread(){
      mBackgroundThread=new HandlerThread("Camera2 background thread");
      mBackgroundThread.start();
      mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
  }
  private  void closeBackgroundThread(){
  
      mBackgroundThread.quitSafely();
      try{
  
          mBackgroundThread.join();
          mBackgroundThread=null;
          mBackgroundHandler=null;
  
      }catch (InterruptedException e){
          e.printStackTrace();
      }
  
  }
  
  private void lockFocus(){
      try{
  
          mState=STATE_WAIT_LOCK;
          mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                  CaptureRequest.CONTROL_AF_TRIGGER_START);
          mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(),
                  mSessionCaptureCallback,mBackgroundHandler);
  
      }catch (CameraAccessException e){
          e.printStackTrace();
      }
  }
  
  private void unLockFocus(){
      try{
  
          mState=STATE_PREVIEW;
          mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                  CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
          mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(),
                  mSessionCaptureCallback,mBackgroundHandler);
  
      }catch (CameraAccessException e){
          e.printStackTrace();
      }
  }
  
  private void captureStillImage(){
      try {
  
          CaptureRequest.Builder captureStillBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
          captureStillBuilder.addTarget(mImageReader.getSurface());
  
          // Use the same AE and AF modes as the preview.
          captureStillBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                  CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
         // setAutoFlash(captureBuilder);
  
          // Orientation
          int rotation=0;
          //Front camera
          if(mCameraId.equals("1")) {
              rotation = this.getWindowManager().getDefaultDisplay().getRotation();
              captureStillBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
          }
          else {
              rotation = this.getWindowManager().getDefaultDisplay().getRotation();
              captureStillBuilder.set(CaptureRequest.JPEG_ORIENTATION,
                      ORIENTATIONS.get(rotation));
          }
  
          CameraCaptureSession.CaptureCallback captureCallback =
                  new CameraCaptureSession.CaptureCallback() {
                      @Override
                      public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
                          super.onCaptureCompleted(session, request, result);
  
                          //Toast.makeText(getApplicationContext(),"Image Captured",Toast.LENGTH_SHORT).show();
  
                          unLockFocus();
                      }
                  };
  
          mCameraCaptureSession.capture(
  
                  captureStillBuilder.build(),captureCallback,null
          );
  
      }catch (CameraAccessException e){
          e.printStackTrace();
      }
  }
  
  private int getOrientation(int rotation) {
      return (ORIENTATIONS.get(rotation) + mSensorOrientation +180) % 360;
  }
  </code></pre>
  
  <p>}</p>