在授予权限的情况下缺乏访问摄像头服务的权限

问题描述 投票:0回答:2

我正在尝试使用Google示例在我的应用上添加相机2 API。我的应用程序有权使用相机,旧API工作正常。我已经检查了多个权限甚至是之前执行Android抛出异常的代码,但我仍然获得了访问摄像头服务的Lacking权限。

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"?>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-feature
    android:name="android.hardware.camera"
    android:required="false" />
<uses-feature
    android:name="android.hardware.camera.front"
    android:required="false" />
<uses-feature
    android:name="android.hardware.camera.autofocus"
    android:required="false" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:screenOrientation="reversePortrait"
    android:hardwareAccelerated="true">
    <activity
        android:name=".UI.ImageAcquisition"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:screenOrientation="reversePortrait"
    />
    <activity
        android:name=".UI.ImageManipulation"
        android:label="@string/title_activity_image_manuplation"
        android:launchMode="singleTop"
        android:screenOrientation="reversePortrait"
        android:theme="@style/AppTheme" />
    <activity
        android:name=".UI.ProjectsActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:screenOrientation="reversePortrait">
        <intent-filter android:label="@string/app_name">
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".UI.IndividualProjectDetailActivity"
        android:label="@string/title_activity_individual_project_detail"
        android:parentActivityName=".UI.ProjectsActivity"
        android:theme="@style/AppTheme"
        android:screenOrientation="reversePortrait">

        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="kiam.cameraintentpractice.UI.ProjectsActivity" />
    </activity>

    <service
        android:name=".model.CalculatorService"
        android:enabled="true"
        android:exported="true"></service>
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
</application>

android android-camera android-6.0-marshmallow android-permissions
2个回答
1
投票

我在三星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();
    }
} 

我希望它会对你有所帮助


1
投票

不要把延迟打开相机。只需在SurfaceTextureListener的onSurfaceTextureDestroyed()方法中使用closeCamera()。

© www.soinside.com 2019 - 2024. All rights reserved.