缺乏在Android 6.0中访问相机服务的权限

时间:2016-11-01 03:23:51

标签: android android-camera android-6.0-marshmallow android-permissions

我在Android 6.0中使用Camera2API。我在Android 5.0中没有错误地完成了。但是,当我在Android 6.0中使用我的代码时,我遇到了问题。问题是,有时我可以成功打开相机并拍照。但是,有时相机无法打开而且有错误

java.lang.SecurityException: Lacking privileges to access camera service
    at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:108)

我添加了运行时权限,如下所示:

String[] PERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA};
if (Build.VERSION.SDK_INT >= 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 >= Build.VERSION_CODES.M && context != null && permissions != null) {
        for (String permission : permissions) {
            if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
    }
    return true;
}

这是所有日志

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)

更新:对于想要查看我的完整代码的人。我在这里上传完整的代码

公共类AndroidCamera扩展了AppCompatActivity {

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 >= 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 >= Build.VERSION_CODES.M && context != null && 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 >= 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<Size>() {
                        @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<Size> collectorSizes = new ArrayList<>();
    for (Size option : mapSizes) {
        if (width > height) {
            if (option.getWidth() > width &&
                    option.getHeight() > height) {
                collectorSizes.add(option);
            }
        } else {
            if (option.getWidth() > height &&
                    option.getHeight() > width) {
                collectorSizes.add(option);
            }
        }
    }
    if (collectorSizes.size() > 0) {
        return Collections.min(collectorSizes, new Comparator<Size>() {
            @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 >= 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;
}

}

1 个答案:

答案 0 :(得分:9)

setupCamera()onSurfaceTextureAvailable开始调用,可以早于授予的权限。

您需要做的是跟踪是否授予权限以及两个回调中是否有表面纹理。

创建一个条目以检查这些条件并设置相机

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);
}

onResume()中,您无需检查权限。如果他们在后台被拒绝,您的活动将被杀死,您将再次通过onCreate()

删除onPause()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();
//    }

将此添加到onStart()

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

将关闭相机移至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
}

我发现另一件事是您必须在onRequestPermissionsResult()中实际检查权限,而不是使用grantResults标记

@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;
    }
}