fix(train): Health Connect's permissions asked as the system's from Android 14 on
From Android 14 on, Health Connect's permission contract makes AndroidX's
REQUEST_PERMISSIONS intent, which only a ComponentActivity's result registry
handles: FlutterActivity started it, no activity answered, and the app
crashed on answering twice, the error and then the empty result ("Reply
already submitted"). It asks with requestPermissions there now, answered in
MainActivity's onRequestPermissionsResult; a permission or route request
that doesn't start is no longer kept waiting, so it is answered once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
cb486af671
commit
5f8514b441
2 changed files with 35 additions and 5 deletions
|
|
@ -153,6 +153,15 @@ class HealthConnectBridge(private val activity: Activity) : MethodChannel.Method
|
|||
return true
|
||||
}
|
||||
|
||||
/** Answers the question for permissions the system asked (Android 14 on); false for any other. */
|
||||
fun onRequestPermissionsResult(requestCode: Int): Boolean {
|
||||
if (requestCode != PERMISSIONS_REQUEST) return false
|
||||
val result = asking ?: return true
|
||||
asking = null
|
||||
scope.launch { result.success(granted()) }
|
||||
return true
|
||||
}
|
||||
|
||||
/** Stops what is still running. */
|
||||
fun dispose() {
|
||||
scope.cancel()
|
||||
|
|
@ -181,9 +190,23 @@ class HealthConnectBridge(private val activity: Activity) : MethodChannel.Method
|
|||
return
|
||||
}
|
||||
asking = result
|
||||
val contract = PermissionController.createRequestPermissionResultContract()
|
||||
@Suppress("DEPRECATION") // FlutterActivity is no ComponentActivity, so no result registry.
|
||||
activity.startActivityForResult(contract.createIntent(activity, wanted), PERMISSIONS_REQUEST)
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
// From Android 14 on, Health Connect's permissions are the system's:
|
||||
// the contract's intent there is AndroidX's REQUEST_PERMISSIONS, which
|
||||
// only a ComponentActivity's result registry handles and no activity
|
||||
// answers (v0.1.0 failed so on every request).
|
||||
activity.requestPermissions(wanted.toTypedArray(), PERMISSIONS_REQUEST)
|
||||
} else {
|
||||
val contract = PermissionController.createRequestPermissionResultContract()
|
||||
@Suppress("DEPRECATION") // FlutterActivity is no ComponentActivity, so no result registry.
|
||||
activity.startActivityForResult(contract.createIntent(activity, wanted), PERMISSIONS_REQUEST)
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
// Not asked: the caller answers with the error, and nothing else may.
|
||||
asking = null
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -246,8 +269,14 @@ class HealthConnectBridge(private val activity: Activity) : MethodChannel.Method
|
|||
return
|
||||
}
|
||||
routing = result
|
||||
@Suppress("DEPRECATION") // As in ask: no result registry.
|
||||
activity.startActivityForResult(ExerciseRouteRequestContract().createIntent(activity, id), ROUTE_REQUEST)
|
||||
try {
|
||||
@Suppress("DEPRECATION") // As in ask: no result registry.
|
||||
activity.startActivityForResult(ExerciseRouteRequestContract().createIntent(activity, id), ROUTE_REQUEST)
|
||||
} catch (error: Exception) {
|
||||
// As in ask: not asked, so answered only with the error.
|
||||
routing = null
|
||||
throw error
|
||||
}
|
||||
}
|
||||
else -> result.success(null)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ class MainActivity : FlutterActivity() {
|
|||
grantResults: IntArray,
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
if (health.onRequestPermissionsResult(requestCode)) return
|
||||
if (requestCode != RECORDER_REQUEST) return
|
||||
asking?.let { (wanted, result) ->
|
||||
asking = null
|
||||
|
|
|
|||
Loading…
Reference in a new issue