2016-05-23 96 views
0

我正在尝试使用新的Android camera2 api。我从本教程的源代码开始:http://jylee-world.blogspot.com/2014/12/a-tutorial-of-androidhardwarecamera2.html。当我尝试将usb调试 - 部署到任何电话时,我从CameraManager.openCamera(...)得到SecurityException。Android Camera2 API安全性例外

我AndroidManifest看起来是这样的:

<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$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) 
+0

您是否在Android 6上运行应用程序? – Alex

+0

@Alex是的,我在6.1上运行它 – B1CL0PS

+0

你是否要求获得许可?如果您的应用目标的API 23那么您需要征求权限。或者至少对于这个测试,如果你现在不想实现额外的东西,你需要去设置和授予权限。但是,您将不得不迟到 – Alex

回答

3

在Android中男,需要风险的权限运行时的权限检查。您可以看到危险的许可here

检查权限:

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

如果应用许可,该方法返回PackageManager.PERMISSION_GRANTED,以及应用程序可以继续操作。如果该应用程序没有权限,该方法返回PERMISSION_DENIED,并且该应用程序必须明确要求用户许可。

详情:https://developer.android.com/training/permissions/requesting.html#perm-request

1

只要闭上你的相机设备onSurfaceTextureDestroyed功能

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

安全异常将得到修复

+0

你能解释得更好吗?为什么用'cameraDevice.close()'关闭相机不会抛出安全异常? – CPHPython

0

为此挣扎了好几个星期,我多次想到解决了这个问题。最后,我在这里读到的“修复”都没有奏效。然后,在我的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('等等等等');声明,我能够摆脱安全错误。

此外,我将此添加到页面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 
       } 
      });