-2

症狀:首次啓動我的應用程序崩潰java.lang.SecurityException: Lacking privileges to access camera service。我收到了「不幸您的應用程序崩潰」對話框,單擊「確定」,在此對話框中有兩個對話框詢問必要的權限。我說「OK」,從現在開始我的應用程序工作。接下來的開始沒有崩潰。Android M請求onSurfaceTextureAvailable回調權限不在活動

原因:以後的閱讀和調試一段時間,我才理解我的應用程序的問題是,它希望做一些與攝像機相關的邏輯,獲得所需的權限(onSurfaceTextureAvailable回調在我CameraHandler類)之前或相機前表面視圖來到前景。

關於SO和Github上的類似錯誤還有很多問題,但是我仍然很難弄清楚。

我試圖通過this答案,但我的設置有點不同,即我有我的相機邏輯裏面不是一個活動的不同類,我真的很想保持它不混亂我的CameraActivity類。有處理這個問題的好方法嗎?

如何確保當我的CameraHandler類中的onSurfaceTextureAvailable被激發時,權限已被授予,以便在第一次運行時我沒有獲得java.lang.SecurityException: Lacking privileges to access camera service

這是我SurfaceTextureListener位於CameraHandler類:

private val surfaceTextureListener = object : TextureView.SurfaceTextureListener { 
    override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) { 
     openCamera(width, height) //this line here makes my app crash 
    } 

    override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) { 
     configureTransform(width, height) 
    } 

    override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean { 
     return true 
    } 

    override fun onSurfaceTextureUpdated(surface: SurfaceTexture) { 

    } 
} 

我CameraActivity的onCreate,的onResume(),並在onPause():

override fun onCreate(savedInstanceState: Bundle?) { 
       super.onCreate(savedInstanceState) 

       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
        if (!canAccessCamera() || !canRecordAudio()) { 
         requestPermissions(INITIAL_PERMISSIONS, INITIAL_REQUEST) 
        } 
       } 
      } 

    override fun onResume() { 
      super.onResume() 
      cameraHandler.startHandler() 
     } 

    override fun onPause() { 
      cameraHandler.stopHandler() 
      super.onPause() 
     } 

權限內CameraActivity檢查

@RequiresApi(api = Build.VERSION_CODES.M) 
    private fun canAccessCamera() : Boolean { 
     return (hasPermission(android.Manifest.permission.CAMERA)) 
    } 

    @RequiresApi(api = Build.VERSION_CODES.M) 
    private fun canRecordAudio() : Boolean { 
     return (hasPermission(android.Manifest.permission.RECORD_AUDIO)) 
    } 

    @RequiresApi(api = Build.VERSION_CODES.M) 
    private fun hasPermission(perm : String) : Boolean{ 
     return (PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm)) 
    } 

    @RequiresApi(Build.VERSION_CODES.M) 
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { 
     super.onRequestPermissionsResult(requestCode, permissions, grantResults) 
     if (requestCode == INITIAL_REQUEST) { 
      if (canAccessCamera() && canRecordAudio()) { 
       recordButton2.setOnClickListener { 
        if (isRecording) { 
         cameraHandler.endRecording() 
        } else { 
         currentFileName = generateTimestampName() 
         createCSVFile(currentFileName) 

         cameraHandler.startStopRecording() 
        } 

        isRecording = !isRecording 
       } 
      } else { 
       Toast.makeText(this, "We need it to perform magic", Toast.LENGTH_SHORT).show() 
      } 
     } 
    } 

回答

1

我寫了自己一點PermissionRequestHandler出於這樣的目的,你可以在這裏找到:https://gist.github.com/Hikaru755/0ae45a4184bdbc28dcc5c1af659b4508

您只需要在活動創建它的一個實例,並確保到onRequestPermissionsResult任何調用傳遞給它,就像在例如BaseActivity中的要點。然後,您可以將它傳遞給其他類,通過它請求權限並獲得需要它們的回調,而不會混淆您的活動。不過,要小心不要讓內存泄漏持續時間超過Activity的壽命!