Skip to content

Commit

Permalink
[Health] Add HC health history permission
Browse files Browse the repository at this point in the history
Created two new methods isHealthDataHistoryAuthorized() and
requestHealthDataHistoryAuthorization().

Both methods are no-op on iOS and return true since Apple Health does
not restrict history length.

Closes cph-cachet#1126
  • Loading branch information
cachapa committed Feb 3, 2025
1 parent f1f4ee0 commit d2c831d
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/health/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ dependencies {
implementation(composeBom)
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

implementation("androidx.health.connect:connect-client:1.1.0-alpha07")
implementation("androidx.health.connect:connect-client:1.1.0-alpha11")
def fragment_version = "1.6.2"
implementation "androidx.fragment:fragment-ktx:$fragment_version"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.annotation.NonNull
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.PermissionController
import androidx.health.connect.client.permission.HealthPermission
import androidx.health.connect.client.permission.HealthPermission.Companion.PERMISSION_READ_HEALTH_DATA_HISTORY
import androidx.health.connect.client.records.*
import androidx.health.connect.client.records.MealType.MEAL_TYPE_BREAKFAST
import androidx.health.connect.client.records.MealType.MEAL_TYPE_DINNER
Expand Down Expand Up @@ -147,6 +148,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
when (call.method) {
"installHealthConnect" -> installHealthConnect(call, result)
"getHealthConnectSdkStatus" -> getHealthConnectSdkStatus(call, result)
"isHealthDataHistoryAuthorized" -> isHealthDataHistoryAuthorized(call, result)
"requestHealthDataHistoryAuthorization" -> requestHealthDataHistoryAuthorization(call, result)
"hasPermissions" -> hasPermissions(call, result)
"requestAuthorization" -> requestAuthorization(call, result)
"revokePermissions" -> revokePermissions(call, result)
Expand Down Expand Up @@ -512,6 +515,41 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
}
}

/**
* Checks if PERMISSION_READ_HEALTH_DATA_HISTORY has been granted
*/
private fun isHealthDataHistoryAuthorized(call: MethodCall, result: Result) {
scope.launch {
result.success(
healthConnectClient
.permissionController
.getGrantedPermissions()
.containsAll(listOf(PERMISSION_READ_HEALTH_DATA_HISTORY)),
)
}
}

/**
* Requests authorization for PERMISSION_READ_HEALTH_DATA_HISTORY
*/
private fun requestHealthDataHistoryAuthorization(call: MethodCall, result: Result) {
if (context == null) {
result.success(false)
return
}

if (healthConnectRequestPermissionsLauncher == null) {
result.success(false)
Log.i("FLUTTER_HEALTH", "Permission launcher not found")
return
}

// Store the result to be called in [onHealthConnectPermissionCallback]
mResult = result
isReplySubmitted = false
healthConnectRequestPermissionsLauncher!!.launch(setOf(PERMISSION_READ_HEALTH_DATA_HISTORY))
}

private fun hasPermissions(call: MethodCall, result: Result) {
val args = call.arguments as HashMap<*, *>
val types = (args["types"] as? ArrayList<*>)?.filterIsInstance<String>()!!
Expand Down
42 changes: 42 additions & 0 deletions packages/health/lib/src/health_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,48 @@ class Health {
}
}

/// Checks the current status of the Health Data History permission.
///
/// See this for more info: https://developer.android.com/reference/androidx/health/connect/client/permission/HealthPermission#PERMISSION_READ_HEALTH_DATA_HISTORY()
///
///
/// Android only. Returns true on iOS or false if an error occurs.
Future<bool> isHealthDataHistoryAuthorized() async {
if (Platform.isIOS) return true;

try {
final status =
await _channel.invokeMethod<bool>('isHealthDataHistoryAuthorized');
return status ?? false;
} catch (e) {
debugPrint('$runtimeType - Exception in getHealthConnectSdkStatus(): $e');
return false;
}
}

/// Requests the Health Data History permission.
///
/// Returns true if successful, false otherwise.
///
/// See this for more info: https://developer.android.com/reference/androidx/health/connect/client/permission/HealthPermission#PERMISSION_READ_HEALTH_DATA_HISTORY()
///
///
/// Android only. Returns true on iOS or false if an error occurs.
Future<bool> requestHealthDataHistoryAuthorization() async {
if (Platform.isIOS) return true;

await _checkIfHealthConnectAvailableOnAndroid();
try {
final bool? isAuthorized =
await _channel.invokeMethod('requestHealthDataHistoryAuthorization');
return isAuthorized ?? false;
} catch (e) {
debugPrint(
'$runtimeType - Exception in requestHealthDataHistoryAuthorization(): $e');
return false;
}
}

/// Requests permissions to access health data [types].
///
/// Returns true if successful, false otherwise.
Expand Down

0 comments on commit d2c831d

Please sign in to comment.