Lacking privileges to access camera service in Android 6.0

岁酱吖の 提交于 2019-12-04 00:16:23

setupCamera() is called right from onSurfaceTextureAvailable, which can be earlier than the permissions are granted.

What you need to do is to track whether the permissions are granted and if the surface texture available in both callbacks.

Make a single entry for checking these conditions and setting up camera

private boolean mSurfaceTextureAvailable;
private boolean mPermissionsGranted;
private boolean mCameraOpened;

private void setupCameraIfPossible() {
    if (!mCameraOpened && mSurfaceTextureAvailable && mPermissionsGranted) {
        String cameraLens = BleUtils.getCameraLens(AndroidCamera.this);
        if (TextUtils.isEmpty(cameraLens)) {
            cameraLens = "1";
        }
        setupCamera(mTextureView.getWidth(), mTextureView.getHeight(), cameraLens);
        openCamera();
    }
}

private final TextureView.SurfaceTextureListener mSurfaceTextureListener =
        new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                mSurfaceTextureAvailable = true;
                setupCameraIfPossible();
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                //closeCamera();
                mSurfaceTextureAvailable = false;
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {

            }
        };

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.camera_activity);
    openBackgroundThread();

    // Make sure the boolean flag is set. Will be true for lower SDK
    mPermissionsGranted = hasAllPermissions(this, PERMISSIONS);
    if (!mPermissionsGranted) {
        ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
    }
    mTextureView = (TextureView) findViewById(R.id.texture);
}

In onResume() you don't need to check for permissions. If they will be denied while in background your Activity will get killed and you will go through onCreate() again.

Remove the code in onPause() and onResume()!

//    @Override
//    public void onResume() {
//        super.onResume();
//        if (Build.VERSION.SDK_INT >= 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);
//        }
//    }

//    public void onPause() {
//        Log.d(TAG,"onPause");
//        closeCamera();
//
//        closeBackgroundThread();
//        super.onPause();
//    }

Add this to onStart()

@Override
public void onStart() {
    super.onStart();
    openCameraIfPossible();
}

Move closing camera to onStop()

@Override
public void onStop() {
    super.onStop();
    closeCamera();
}

private void closeCamera() {
    mCameraOpened = false; // set a field indicating it is closed
    ...
}

private void openCamera() {
    ...
    mCameraOpened = true; // If successful, set a field indicating it is opened
}

Now another thing I discovered is that you must actually check for permissions in onRequestPermissionsResult() instead of using grantResults flags

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode){
        case REQUEST_CAMERA_RESULT:
            mPermissionsGranted = hasAllPermissions(this, PERMISSIONS);
            setupCameraIfPossible();
            break;

        default:
            break;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!