Android 相机 2 API SecurityException
Android Camera2 API SecurityException
我正在尝试使用新的 Android camera2 api。我从本教程的源代码开始:http://jylee-world.blogspot.com/2014/12/a-tutorial-of-androidhardwarecamera2.html。当我尝试将其 usb-debug-deploy 到任何 phone 时,我从 CameraManager.openCamera(...)
.
得到了一个 SecurityException
我的Android清单如下所示:
<uses-feature android:name="com.android.hardware.camera2.full"/>
<uses-permission android:name="android.permission.CAMERA"/>
这似乎是我能够找到的每个教程所做的。我可以获得其他操作的许可;例如,我可以让相机振动得很好。我也可以用 CameraManager.getCameraIdLists()
枚举相机,但我不确定这是否真的需要许可。但是我不能openCamera
.
我需要一些额外的权限吗?我做错了什么吗?
感谢您的帮助!
这是我的完整堆栈跟踪:
SecurityException
java.lang.SecurityException: Lacking privileges to access camera serviceat android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:108)
at android.hardware.camera2.legacy.CameraDeviceUserShim.connectBinderShim(CameraDeviceUserShim.java:336)
at android.hardware.camera2.CameraManager.openCameraDeviceUserAsync(CameraManager.java:327)
at android.hardware.camera2.CameraManager.openCamera(CameraManager.java:457)
at com.example.quinnfreedman.camera2test.MainActivity.onSurfaceTextureAvailable(MainActivity.java:74)
at android.view.TextureView.getHardwareLayer(TextureView.java:368)
at android.view.View.updateDisplayListIfDirty(View.java:15167)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.updateDisplayListIfDirty(View.java:15185)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.updateDisplayListIfDirty(View.java:15185)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.updateDisplayListIfDirty(View.java:15185)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.draw(View.java:16197)
at com.android.internal.policy.PhoneWindow$DecorView.draw(PhoneWindow.java:2690)
at android.view.View.updateDisplayListIfDirty(View.java:15190)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:281)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:287)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:322)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2627)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2446)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2079)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6060)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
在AndroidM中,运行时间权限检查需要危险权限。可以看到危险权限here.
检查权限:
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.CAMERA);
如果应用程序有权限,方法returns PackageManager.PERMISSION_GRANTED
,应用程序可以继续操作。如果应用程序没有权限,方法returns PERMISSION_DENIED
,应用程序必须明确请求用户权限。
详情:https://developer.android.com/training/permissions/requesting.html#perm-request
当您 运行 您的应用程序在 android 6+ 上时,您需要授予著名的运行时权限。
https://developer.android.com/training/permissions/requesting.html
您尝试授予的权限被认为是危险的权限android。
https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
与其他关于运行时权限的回复不同,我建议你使用这个https://github.com/Karumi/Dexter
这个库使权限处理变得容易
只需在 onSurfaceTextureDestroyed 函数中关闭您的相机设备
onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture){cameraDevice.close();cameraDevice = null;}
安全异常将得到修复
断断续续地为此苦苦挣扎了数周,多次思考我已经解决了这个问题。最后,我在这里读到的 "fixes" 中的 none 起作用了。然后,在我的 Java 中输入 ~100 Log.v 语句后,我意识到这是一个线程问题,可能会或可能不会引发此错误,具体取决于相机上的事件。基本上,我认为,主程序是 运行 在主线程上,但是下面的语句启动了一个额外的线程:
//this code seems to be the culprit ... commenting it out solve my problem
private void showToast(final String text) {
final Activity activity = MyStupidProgram.this;
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();
}
});
}
}
因此,虽然此语句中没有任何内容调用相机,但可能是因为线程安全,Android 5.x 和 6.x 在我调用 showToast('some crap');
注释掉并仅使用 Toast.makeText('blah blah');声明,我能够摆脱安全错误。
此外,我将此添加到页面 onCreate() 的代码中;声明,以捕获主线程上的任何问题:
Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(
Thread paramThread,
Throwable paramThrowable
) {
//Do your own error handling here
if (exceptionHandler != null)
exceptionHandler.uncaughtException(
paramThread,
paramThrowable
); //Delegates to Android's error handling
else
System.exit(2); //Prevents the service/app from freezing
}
});
我正在尝试使用新的 Android camera2 api。我从本教程的源代码开始:http://jylee-world.blogspot.com/2014/12/a-tutorial-of-androidhardwarecamera2.html。当我尝试将其 usb-debug-deploy 到任何 phone 时,我从 CameraManager.openCamera(...)
.
我的Android清单如下所示:
<uses-feature android:name="com.android.hardware.camera2.full"/>
<uses-permission android:name="android.permission.CAMERA"/>
这似乎是我能够找到的每个教程所做的。我可以获得其他操作的许可;例如,我可以让相机振动得很好。我也可以用 CameraManager.getCameraIdLists()
枚举相机,但我不确定这是否真的需要许可。但是我不能openCamera
.
我需要一些额外的权限吗?我做错了什么吗?
感谢您的帮助!
这是我的完整堆栈跟踪:
SecurityException
java.lang.SecurityException: Lacking privileges to access camera serviceat android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:108)
at android.hardware.camera2.legacy.CameraDeviceUserShim.connectBinderShim(CameraDeviceUserShim.java:336)
at android.hardware.camera2.CameraManager.openCameraDeviceUserAsync(CameraManager.java:327)
at android.hardware.camera2.CameraManager.openCamera(CameraManager.java:457)
at com.example.quinnfreedman.camera2test.MainActivity.onSurfaceTextureAvailable(MainActivity.java:74)
at android.view.TextureView.getHardwareLayer(TextureView.java:368)
at android.view.View.updateDisplayListIfDirty(View.java:15167)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.updateDisplayListIfDirty(View.java:15185)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.updateDisplayListIfDirty(View.java:15185)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.updateDisplayListIfDirty(View.java:15185)
at android.view.View.draw(View.java:15964)
at android.view.ViewGroup.drawChild(ViewGroup.java:3612)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)
at android.view.View.draw(View.java:16197)
at com.android.internal.policy.PhoneWindow$DecorView.draw(PhoneWindow.java:2690)
at android.view.View.updateDisplayListIfDirty(View.java:15190)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:281)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:287)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:322)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2627)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2446)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2079)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6060)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:606)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
在AndroidM中,运行时间权限检查需要危险权限。可以看到危险权限here.
检查权限:
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.CAMERA);
如果应用程序有权限,方法returns PackageManager.PERMISSION_GRANTED
,应用程序可以继续操作。如果应用程序没有权限,方法returns PERMISSION_DENIED
,应用程序必须明确请求用户权限。
详情:https://developer.android.com/training/permissions/requesting.html#perm-request
当您 运行 您的应用程序在 android 6+ 上时,您需要授予著名的运行时权限。 https://developer.android.com/training/permissions/requesting.html
您尝试授予的权限被认为是危险的权限android。 https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
与其他关于运行时权限的回复不同,我建议你使用这个https://github.com/Karumi/Dexter
这个库使权限处理变得容易
只需在 onSurfaceTextureDestroyed 函数中关闭您的相机设备
onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture){cameraDevice.close();cameraDevice = null;}
安全异常将得到修复
断断续续地为此苦苦挣扎了数周,多次思考我已经解决了这个问题。最后,我在这里读到的 "fixes" 中的 none 起作用了。然后,在我的 Java 中输入 ~100 Log.v 语句后,我意识到这是一个线程问题,可能会或可能不会引发此错误,具体取决于相机上的事件。基本上,我认为,主程序是 运行 在主线程上,但是下面的语句启动了一个额外的线程:
//this code seems to be the culprit ... commenting it out solve my problem
private void showToast(final String text) {
final Activity activity = MyStupidProgram.this;
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();
}
});
}
}
因此,虽然此语句中没有任何内容调用相机,但可能是因为线程安全,Android 5.x 和 6.x 在我调用 showToast('some crap');
注释掉并仅使用 Toast.makeText('blah blah');声明,我能够摆脱安全错误。
此外,我将此添加到页面 onCreate() 的代码中;声明,以捕获主线程上的任何问题:
Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(
Thread paramThread,
Throwable paramThrowable
) {
//Do your own error handling here
if (exceptionHandler != null)
exceptionHandler.uncaughtException(
paramThread,
paramThrowable
); //Delegates to Android's error handling
else
System.exit(2); //Prevents the service/app from freezing
}
});