Android 缺少访问已授予权限的摄像头服务的权限

Android 缺少访问已授予权限的摄像头服务的权限,android,android-camera,android-6.0-marshmallow,android-permissions,Android,Android Camera,Android 6.0 Marshmallow,Android Permissions,我正在尝试使用谷歌示例在我的应用程序中添加Camera2API。我的应用程序有使用摄像头的权限,旧的API工作正常。在执行Android抛出异常的代码之前,我已经检查了不止一行权限,但我仍然没有获得访问摄像头服务的权限 private void createCameraPreviewSession() { try{ SurfaceTexture texture = mTextureView.getSurfaceTexture(); //assert tex

我正在尝试使用谷歌示例在我的应用程序中添加Camera2API。我的应用程序有使用摄像头的权限,旧的API工作正常。在执行Android抛出异常的代码之前,我已经检查了不止一行权限,但我仍然没有获得访问摄像头服务的权限

private void createCameraPreviewSession() {
    try{
        SurfaceTexture texture = mTextureView.getSurfaceTexture();
        //assert texture != null;

        Log.d(TAG,String.format("Textureview is null: %b, texture is null: %b",mTextureView==null, texture==null));
        // We configure the size of default buffer to be the size of camera preview we want.
        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

        // This is the output Surface we need to start preview.
        Surface surface = new Surface(texture);

        // We set up a CaptureRequest.Builder with the output Surface.

        if (ActivityCompat.checkSelfPermission(a, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "Permission granted");
            mPreviewRequestBuilder= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            Log.d(TAG, "Capture request created");
        }
        else{
            return ;
        }

        mPreviewRequestBuilder.addTarget(surface);

        // Here, we create a CameraCaptureSession for camera preview.

        mCameraDevice.createCaptureSession(Arrays.asList(surface),
            new CameraCaptureSession.StateCallback() {

                @Override
                public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                    // The camera is already closed
                    if (null == mCameraDevice) {
                        return;
                    }

                    // When the session is ready, we start displaying the preview.
                    mCaptureSession = cameraCaptureSession;
                    try {
                        // Auto focus should be continuous for camera preview.
                        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);

                        // Finally, we start displaying the camera preview.
                        mPreviewRequest = mPreviewRequestBuilder.build();
                        mCaptureSession.setRepeatingRequest(mPreviewRequest, null, null);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(
                        @NonNull CameraCaptureSession cameraCaptureSession) {
                    Toast.makeText(a,a.getString(R.string.error_configuring_camera),Toast.LENGTH_LONG).show();
                }
            }, null);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}
以下是日志:

12-02 20:30:07.427 697-697/kiam.cameraintentpractice.pendant D/ICAMERA2: Textureview is null: false, texture is null: false
12-02 20:30:07.428 697-697/kiam.cameraintentpractice.pendant D/ICAMERA2: Permission granted
12-02 20:30:07.429 697-697/kiam.cameraintentpractice.pendant D/AndroidRuntime: Shutting down VM
12-02 20:30:07.430 697-697/kiam.cameraintentpractice.pendant E/AndroidRuntime: FATAL EXCEPTION: main
   Process: kiam.cameraintentpractice.pendant, PID: 697
   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.createDefaultRequest(Unknown Source)
       at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureRequest(CameraDeviceImpl.java:636)
       at kiam.cameraintentpractice.model.CameraV2.createCameraPreviewSession(CameraV2.java:377)
       at kiam.cameraintentpractice.model.CameraV2.access$400(CameraV2.java:55)
       at kiam.cameraintentpractice.model.CameraV2$2.onOpened(CameraV2.java:340)
       at android.hardware.camera2.impl.CameraDeviceImpl$1.run(CameraDeviceImpl.java:134)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5525)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
12-02 20:30:08.752 697-797/kiam.cameraintentpractice.pendant D/TaskManager: Error processing queue - Call: 3
代码在此处称为表单:

private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {

    @Override
    public void onOpened(@NonNull CameraDevice cameraDevice) {
        // This method is called when the camera is opened.  We start camera preview here.
        mCameraOpenCloseLock.release();
        mCameraDevice = cameraDevice;
        createCameraPreviewSession();
    }

    @Override
    public void onDisconnected(@NonNull CameraDevice cameraDevice) {
        mCameraOpenCloseLock.release();
        cameraDevice.close();
        mCameraDevice = null;
    }

    @Override
    public void onError(@NonNull CameraDevice cameraDevice, int error) {
        mCameraOpenCloseLock.release();
        cameraDevice.close();
        mCameraDevice = null;
        Toast.makeText(a, a.getString(R.string.error_using_camera), Toast.LENGTH_SHORT).show();
        a.finish();
    }
};
下面是回调的形式:

private void openCamera(int width, int height) {

    if (ContextCompat.checkSelfPermission(a, Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {
        Log.d(TAG, "Permission denied");
        return;
    }
    setUpCameraOutputs(width, height);
    configureTransform(width, height);

    try {
        /*if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
            throw new RuntimeException("Time out waiting to lock camera opening.");
        }*/
        if (ActivityCompat.checkSelfPermission(a, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "Permission accepted");
            CameraManager manager = (CameraManager) a.getSystemService(Context.CAMERA_SERVICE);
            manager.openCamera(mCameraId, mStateCallback, null);
        }
        else{
            Log.d(TAG, "Permission denied");
            return;
        }

    } catch (CameraAccessException e) {
        e.printStackTrace();
    } /*catch (InterruptedException e) {
        throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
    }*/
}
编辑-按要求过帐清单

    <?xml version="1.0" encoding="utf-8"?>



我在三星Galaxy S7等设备上也遇到了同样的问题。我通过在打开摄像头之前添加延迟来解决此问题,如下所示:

TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        mSurfaceTextureAvailable = true;
        if (ContextCompat.checkSelfPermission(CameraActivity.this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(CameraActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
            return;
        }else {
            mPermissionsGranted = true;

            // Execute some code after 500 milliseconds have passed
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    setupCameraIfPossible();
                }
            }, 500);


        }

    }
...
以下是我用来打开相机的方法:

 private void setupCameraIfPossible() {
    if (mSurfaceTextureAvailable && mPermissionsGranted) {
        openCamera();
    }
} 

我希望它能帮助您

我在三星Galaxy S7等设备上也遇到了同样的问题。我通过在打开摄像头之前添加延迟来解决此问题,如下所示:

TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        mSurfaceTextureAvailable = true;
        if (ContextCompat.checkSelfPermission(CameraActivity.this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(CameraActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
            return;
        }else {
            mPermissionsGranted = true;

            // Execute some code after 500 milliseconds have passed
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    setupCameraIfPossible();
                }
            }, 500);


        }

    }
...
以下是我用来打开相机的方法:

 private void setupCameraIfPossible() {
    if (mSurfaceTextureAvailable && mPermissionsGranted) {
        openCamera();
    }
} 

我希望这会对你有所帮助

不要耽误打开摄像头的时间。只需关闭SurfaceTextureDestroyed()方法中的摄像头()。

不要延迟打开摄像头。只需关闭SurfaceTextureDistromed()方法中的Camera()。

请发布您的清单。请发布您的清单。