Search code examples
androidkotlinregisterforactivityresult

Fatal error LifecycleOwners must call register before they are STARTED on registerForActivityResult


I have a simple empty activity that checks if permissions need to be requested. When registerForActivityResult is called, it crashes with the error java.lang.IllegalStateException: LifecycleOwner com.example.app.PermsRequester@41a30da is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED. From my research, I think I need to check if savedInstanceState is null and if so, create a new fragment? I'm not sure if that is the correct solution or how to implement. Below is the code:

class PermsRequester : AppCompatActivity() {
    requestPerms = false

    override fun onCreate(savedInstanceState: Bundle?) {
        setTheme(R.style.AppTheme)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_perms_requester)

        findViewById<Button>(R.id.acceptButton).setOnClickListener { accepted() }
    }

    private fun accepted() {
        //There is code here to check if rationale dialog needs to be displayed
        //There is code here to build a mutable list of permissions that need to be requested and sets requestPerms = true

        if(requestPerms)
            requestPermissions()
    }

    private fun requestPermissions() {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //app crashes on the following line
            val requestMultiplePermissions = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
                 permissions -> permissions.entries.forEach {
                     //Handles permission result
                 }
            }
        }
    }
}

Solution

  • You need to registerForActivityResult before onStart of the Activity.

    private lateinit var requestMultiplePermissionsLauncher: 
        ActivityResultLauncher<Array<String>>
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        requestMultiplePermissionsLauncher =
            registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
                permissions.entries.forEach {
                    //Handles permission result
                }
            }
    }
    
    private fun accepted() {
        if(requestPerms) {
            val permissions = arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CAMERA)
            requestMultiplePermissionsLauncher.launch(permissions)
        }
    }