Search code examples
androidfluttermobilehealthconnect

Health Connect revokeAllPermissions() not changing the state of permission in Health connect for a given app session


I'm getting the permission status as true even after revokePermissions() is invoked.
When I checked the health connect setting after invoking revokeAllPermissions() and while my app was running in the background, it showed that the app was still allowed Health Connect permissions. But on next reload of the app is showed the app was disconnected from Health connect.

Saw the same issue in Health connects Sample App

I have a function in Flutter side which goes like this:

void revoke() {
          revokePermission();
          checkForPermissions();
          Get.back();
}

This invokes two android native functions which are:
revokePermissions() and checkForPermissions() respectively.

Their respective implementations are as follows:

private fun revokePermissions() {
        scope.launch {
            if (healthConnectAvailable && !::healthConnectClient.isInitialized) {
                healthConnectClient = HealthConnectClient.getOrCreate(context!!)
            }
            healthConnectClient.permissionController.revokeAllPermissions()
        }

    }

and

private fun checkForPermissions(call: MethodCall, result: Result) {
        val args = call.arguments as HashMap<*, *>
        val types =
            (args["types"] as? ArrayList<*>)?.filterIsInstance<String>()!!
        val permissions =
            (args["permissions"] as? ArrayList<*>)?.filterIsInstance<Int>()!!

        var permList = mutableListOf<String>()
        for ((i, typeKey) in types.withIndex()) {
            val access = permissions[i]!!
            val dataType = MapToHCType[typeKey]!!
            if (access == 0) {
                permList.add(
                    HealthPermission.getReadPermission(dataType),
                )
            } else {
                permList.addAll(
                    listOf(
                        HealthPermission.getReadPermission(dataType),
                        HealthPermission.getWritePermission(dataType),
                    )
                )
            }
            // Workout also needs distance and total energy burned too
            if (typeKey == WORKOUT) {
                if (access == 0) {
                    permList.addAll(
                        listOf(
                            HealthPermission.getReadPermission(DistanceRecord::class),
                            HealthPermission.getReadPermission(
                                TotalCaloriesBurnedRecord::class
                            ),
                        )
                    )
                } else {
                    permList.addAll(
                        listOf(
                            HealthPermission.getReadPermission(DistanceRecord::class),
                            HealthPermission.getReadPermission(
                                TotalCaloriesBurnedRecord::class
                            ),
                            HealthPermission.getWritePermission(DistanceRecord::class),
                            HealthPermission.getWritePermission(
                                TotalCaloriesBurnedRecord::class
                            ),
                        )
                    )
                }
            }
        }
        scope.launch {
            if (healthConnectAvailable && !::healthConnectClient.isInitialized) {
                healthConnectClient = HealthConnectClient.getOrCreate(context!!)
            }
            var temp =
                healthConnectClient.permissionController.getGrantedPermissions()
                    .containsAll(permList)
            print(temp)
            result.success(temp)
        }
    }

Solution

  • This is intended behavior as Health Connect permissions follow the standard permissions model on Android 14+. You can see the reference to this behavior in the Android developer documentation here: https://developer.android.com/training/permissions/requesting#remove-access