registerForActivityResult 可以在协程中使用吗?

utt*_*led 4 android coroutine kotlin

我认为这个问题是你必须保证在你自己的活动的 OnCreate() 完成之前调用 registerForActivityResult() 。OnCreate() 显然不是一个挂起函数,因此我无法将 registerForActivityResult() 和 ActivityResultLauncher.launch() 包装在 suspendCoroutine{} 中以等待回调,因为我无法从 OnCreate 启动 suspendCoroutine 并等待它在 OnCreate 完成之前完成...

...我确实认为我可以使用 runBlocking{} 来做到这一点,但我发现在 OnCreate 中调用 runBlocking 会导致应用程序永远挂起,而不会运行 runBlocking{} 块中的代码。

所以我的问题是 runBlocking{} 是否是正确的答案但我使用错误,或者是否有其他方法可以在协程中使用 registerForActivityResult() ,或者它是否根本不可能。

Pon*_*rai 7

你可以做这样的事情。请参考下面的实现。

class RequestPermission(activity: ComponentActivity) {
    private var requestPermissionContinuation: CancellableContinuation<Boolean>? = null
    @SuppressLint("MissingPermission")
    private val requestFineLocationPermissionLauncher =
        activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
            requestPermissionContinuation?.resumeWith(Result.success(isGranted))
        }

    suspend operator fun invoke(permission: String) = suspendCancellableCoroutine<Boolean> { continuation ->
        requestPermissionContinuation = continuation
        requestFineLocationPermissionLauncher.launch(permission)
        continuation.invokeOnCancellation {
            requestPermissionContinuation = null
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

确保在活动 onStart 之前初始化此类。registerForActivityResultAPI 应在 Activity 的 onStart 之前调用。请参考下面的示例

class SampleActivity : AppCompatActivity()  {
    val requestPermission: RequestPermission = RequestPermission(this)

    override fun onResume() {
        super.onResume()
        lifecycleScope.launch {
            val isGranted = requestPermission(Manifest.permission.ACCESS_FINE_LOCATION)
            //Do your actions here
        }

    }
}
Run Code Online (Sandbox Code Playgroud)