Search code examples
javaandroidkotlinmobilescreen-recording

Screen recording asks permission every time in android version 12 or above


Thanks for your attention about my trouble. I am working with android + java & kotlin app. It needs to be screen recorded but it asks permission every time in android version 12 or above.

Screen Record Permission Request

1

I hope this would ask only one time for permission request. I've seen XRecorder does require once for screen recording permission not every time. Isn't there anyway to make my app to ask only one time for permission request. Wish someone would help me to solve this.


Solution

  • In my experience, you can save the result of media projection intent and reuse it during the same application process session. That is how most applications overcome this issue.

    But be aware that it is more a hack than a solution because the docs do not guarantee it. In contrast, it says you can not reuse it. So use it at your own risk.

    From my observations, it will work almost everywhere except some Xiaomi and Huawei devices. You can add them to ignore list and ask every time. Another good idea will be to add a try-catch when reusing an intent, so you can request permission again if the intent is expired.

    Context: we use this hack in an application with millions of active users, so it has some credibility.

    Code snippet to get the idea, but not production ready:

    object MediaProjectionIntentHolder {
        
        var intent: Intent? = null
    
    }
    
    class ScreenRecordingFragment : Fragment() {
        
    
        // A user clicked button and this function is called
        private fun startScreenRecording() {
            val intent = MediaProjectionIntentHolder.intent
            // You can check Huawei / Xiaomi devices here to ask permission every time
            if (intent != null) {
                recordScreen(intent)
            } else {
                requestPermission()
            }
        }
    
        private fun recordScreen(intent: Intent) {
            // Actual screen recording start
        }
    
        private showError() {
            // show error
        }
    
    
        private fun requestPermission() {
            val service = requireContext().getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
            val intent = service.createScreenCaptureIntent()
    
            val screenRecordingSupported = context.packageManager.queryIntentActivities(intent, 0).isNotEmpty()
    
            if (screenRecordingSupported) {
                startActivityForResult(intent, REQUEST_CODE)
            } else {
                showError()
            }
        }
    
        override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            super.onActivityResult(requestCode, resultCode, data)
            if (requestCode == REQUEST_CODE) {
                if (resultCode == Activity.RESULT_OK && data != null) {
                    MediaProjectionIntentHolder.intent = data
                    recordScreen(data)
                } else {
                    showError()
                }
            }
        }
    
        private companion object {
            private consta val REQUEST_CODE = 42
        }
    }