简体   繁体   English

Android Camera2 API SecurityException

[英]Android Camera2 API SecurityException

I'm trying to use the new Android camera2 api. 我正在尝试使用新的Android camera2 API。 I started with source from this tutorial : http://jylee-world.blogspot.com/2014/12/a-tutorial-of-androidhardwarecamera2.html . 我从本教程的源开始: http : //jylee-world.blogspot.com/2014/12/a-tutorial-of-androidhardwarecamera2.html When I try to usb-debug-deploy it to any phone, I get a SecurityException from CameraManager.openCamera(...) . 当我尝试将其usb调试部署到任何电话时,我从CameraManager.openCamera(...)获得SecurityException。

My AndroidManifest looks like this: 我的AndroidManifest看起来像这样:

<uses-feature android:name="com.android.hardware.camera2.full"/>
<uses-permission android:name="android.permission.CAMERA"/>

This seems to be what every tutorial I've been able to find does. 这似乎是我所能找到的每个教程的功能。 I'm able to get permission for other actions; 我能够获得其他操作的许可; for example, I can make the camera vibrate just fine. 例如,我可以使相机振动很好。 I'm also able to enumerate cameras with CameraManager.getCameraIdLists() just fine, but I'm not sure if that actually requires permission. 我也可以使用CameraManager.getCameraIdLists()枚举相机,但是我不确定这是否真的需要许可。 But I can't openCamera . 但是我不能openCamera

Are there some additional permissions I need? 我需要一些其他权限吗? Am I doing something wrong? 难道我做错了什么?

Thanks for the help! 谢谢您的帮助!

This is my full stack trace: 这是我的完整堆栈跟踪:

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$1.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)

In Android M, run time permission check is required for dangerous permission. 在Android M中,危险权限需要运行时权限检查。 You can see dangerous permission here . 您可以在这里看到危险的许可。

Check for permission : 检查权限:

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.CAMERA);

If the app has the permission, the method returns PackageManager.PERMISSION_GRANTED , and the app can proceed with the operation. 如果应用程序具有该权限,则该方法返回PackageManager.PERMISSION_GRANTED ,并且该应用程序可以继续进行操作。 If the app does not have the permission, the method returns PERMISSION_DENIED , and the app has to explicitly ask the user for permission. 如果该应用程序没有该权限,则该方法返回PERMISSION_DENIED ,并且该应用程序必须明确向用户询问权限。

For details: https://developer.android.com/training/permissions/requesting.html#perm-request 有关详细信息: https : //developer.android.com/training/permissions/requesting.html#perm-request

Just close your camera device in onSurfaceTextureDestroyed function 只需在onSurfaceTextureDestroyed函数中关闭相机设备

 onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture){cameraDevice.close();cameraDevice = null;}

Security exception will get fix 安全异常将得到修复

When you are running your application on android 6+, you need to give the famous runtime permissions. 在android 6+上运行应用程序时,需要授予著名的运行时权限。 https://developer.android.com/training/permissions/requesting.html https://developer.android.com/training/permissions/requesting.html

The permission you are trying to give is considered a dangerous permissions android. 您尝试给予的权限被认为是危险的android权限。 https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous

Different of other responses about runtime permission, I suggest you to use this https://github.com/Karumi/Dexter 与其他有关运行时权限的响应不同,我建议您使用此https://github.com/Karumi/Dexter

This lib makes the permission handling easily 这个lib使权限处理很容易

Struggled with this off and on for weeks, thinking several times I'd solved the problem. 挣扎着断断续续地挣扎了好几个星期,认为我已经解决了好几次。 In the end, none of the "fixes" I'd read about here worked. 最后,我在这里没有读到的任何“修复”都起作用。 Then, after putting in ~100 Log.v statements in my Java, I realized it was a threading issue that might, or might not, kick off this error depending on events on the camera. 然后,在Java中放入约100个Log.v语句后,我意识到这是一个线程问题,根据摄像头上的事件,该问题可能会或可能不会引发此错误。 Basically, I think, the main program was running on the main thread, but there was an extra thread kicked off by the following statement: 我认为,基本上,主程序在主线程上运行,但是以下语句启动了一个额外的线程:

//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();
            }
        });
    }
}

So while there's nothing in this statement calling the camera, perhaps because of thread safety, Android 5.x and 6.x were throwing security errors when I called showToast('some crap'); 因此,尽管此语句中没有任何内容调用相机,但也许是出于线程安全性的缘故,当我调用showToast('some crap');时,Android 5.x和6.x引发了安全错误。

Commenting that out and just using a Toast.makeText('blah blah'); 评论出来,只使用Toast.makeText('blah blah'); statement, I was able to get rid of the security error. 声明,我能够摆脱安全错误。

Additionally, I added this to the code on the page's onCreate(); 另外,我将此添加到页面onCreate()的代码中; statement, to catch any issues on the main thread: 语句,以捕获主线程上的任何问题:

    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
                }
            });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM