web-dev-qa-db-ja.com

Android 6.0でカメラサービスにアクセスするための権限がありません

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

}

13
user3051460

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
}
_

私が発見したもう1つのことは、grantResultsフラグを使用する代わりに、onRequestPermissionsResult()で実際にアクセス許可を確認する必要があるということです。

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