camera2抛出SecurityException

时间:2017-11-28 13:55:56

标签: android

我正在使用android中的camera2 api,并尝试在TextureView和SurfaceView之间切换,因此我唯一的改变是使用SurfaceView替换TextureView,使用SurfaceHolder.Callback替换TextureView.SurfaceTextureListener。现在android 7下的所有手机都崩溃了。 (我有所需的权限和所需的运行时权限。 - 在切换到SurfaceView之前,应用程序运行良好)。

应用程序崩溃:

mPreviewBuilder = 
    mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

旧代码:

private TextureView.SurfaceTextureListener mSurfaceTextureListener
        = new TextureView.SurfaceTextureListener() {

    @Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
                                      int width, int height) {
    openCamera(width, height);
}

@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture,
                                        int width, int height) {
    configureTransform(width, height);
}

@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
    return true;
}

@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}

};
/**
 * Start the camera preview.
 */
private void startPreview() {
    if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) {
        return;
    }
    try {
        closePreviewSession();
        SurfaceTexture texture = mTextureView.getSurfaceTexture();
        assert texture != null;
        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);

        Surface previewSurface = new Surface(texture);
        mPreviewBuilder.addTarget(previewSurface);

mCameraDevice.createCaptureSession(Collections.singletonList(previewSurface),
        new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                    mPreviewSession = session;
                    updatePreview();
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                    if (null != activity) {
                        Toast.makeText(activity, "Failed", Toast.LENGTH_SHORT).show();
                    }
                }
            }, mBackgroundHandler);
} catch (CameraAccessException e) {
    e.printStackTrace();
}
}

新代码:

private SurfaceHolder.Callback mSurfaceViewListener =
        new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                SurfaceViewLifeCycle.setSurfaceState(SurfaceViewLifeCycle.SURFACE_VIEW_LIFE_CYCLE_CREATED);
                openCamera(640, 480);
            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                SurfaceViewLifeCycle.setSurfaceState(SurfaceViewLifeCycle.SURFACE_VIEW_LIFE_CYCLE_DESTROYED);
                closeCamera();
            }
        };


    /**
 * Start the camera preview.
 */
private void startPreview() {
    if (null == mCameraDevice ||
            SurfaceViewLifeCycle.getSurfaceState() != SurfaceViewLifeCycle.SURFACE_VIEW_LIFE_CYCLE_CREATED ||
            null == mPreviewSize) {
        return;
    }
    try {
        closePreviewSession();
        //SurfaceTexture texture = mTextureView.getSurfaceTexture();
        //assert texture != null;
        //texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        //Surface previewSurface = new Surface(texture);
        Surface previewSurface = mSurfaceView.getHolder().getSurface();
        mPreviewBuilder.addTarget(previewSurface);

        mCameraDevice.createCaptureSession(Collections.singletonList(previewSurface),
                new CameraCaptureSession.StateCallback() {

                    @Override
                    public void onConfigured(@NonNull CameraCaptureSession session) {
                        mPreviewSession = session;
                        updatePreview();
                    }

                    @Override
                    public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                        if (null != activity) {
                            Toast.makeText(activity, "Failed", Toast.LENGTH_SHORT).show();
                        }
                    }
                }, mBackgroundHandler);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

错误日志:

11-28 15:38:32.253 13516-13516/rifdsafsda.com.phase9try12 E/AndroidRuntime: FATAL EXCEPTION: main
                                                                            Process: rifdsafsda.com.phase9try12, PID: 13516
                                                                            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 $Proxy1.createDefaultRequest(Unknown Source)
                                                                                at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureRequest(CameraDeviceImpl.java:628)
                                                                                at rifdsafsda.com.phase9try12.media.camera.RecordingManager.startPreview(RecordingManager.java:282)
                                                                                at rifdsafsda.com.phase9try12.media.camera.RecordingManager.access$300(RecordingManager.java:41)
                                                                                at rifdsafsda.com.phase9try12.media.camera.RecordingManager$2.onOpened(RecordingManager.java:121)
                                                                                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:5417)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

1 个答案:

答案 0 :(得分:0)

似乎在调用openCamera后已授予相机权限,请尝试此操作并检查:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && 
ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) 
{
  ActivityCompat.requestPermissions(AndroidCameraApi.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, CAMERA_PERMISSION_REQUEST_ID);
}
else
{
     openCamera(640, 480);
}