没有权限访问相机服务并获得许可
Posted
技术标签:
【中文标题】没有权限访问相机服务并获得许可【英文标题】:Lacking privileges to access camera service with permission granted 【发布时间】:2017-04-18 00:33:56 【问题描述】:我正在尝试使用 Google 示例在我的应用中添加相机 2 API。我的应用程序有权使用相机,旧 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"?>
<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>
【问题讨论】:
请发布您的清单。 【参考方案1】:不要延迟打开相机。只需在 SurfaceTextureListener 的 onSurfaceTextureDestroyed() 方法中 closeCamera() 即可。
【讨论】:
【参考方案2】:我在三星 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();
希望对你有帮助
【讨论】:
以上是关于没有权限访问相机服务并获得许可的主要内容,如果未能解决你的问题,请参考以下文章