2016-05-23 63 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 
       } 
      });