Health Connect接入及填坑

在这里插入图片描述

之前App中一直使用的是Google Fit API,今年五月的Google I/O 大会上已经宣布停止服务。所以我们需要迁移到 Health Connect

在这里插入图片描述
官方文档地址:https://developer.android.com/health-and-fitness/guides/health-connect

1.迁移

Google Fit 迁移首先就是删除相关代码及依赖,主要的依赖库如下。

implementation 'com.google.android.gms:play-services-auth:20.4.1'
implementation 'com.google.android.gms:play-services-fitness:21.1.0'

如果你有谷歌登录相关功能,保留play-services-auth

2.接入

配置

  • 添加依赖
implementation "androidx.health.connect:connect-client:1.1.0-alpha07"

Health Connect SDK目前限制最小api支持到26(Android 8.0),所以一旦接入此功能后,需要将minSdkVersion改为26。
如果你的应用还支持到8.0以下。可以添加以下配置覆盖此依赖库的限制:

<manifest>
  <uses-sdk tools:overrideLibrary="androidx.health.connect.client"/>
  ...
</manifest>

另外注意此功能最小只支持到Android 9.0,所以需要判断大于等于P(28)。比如此功能的开关只有9.0及以上手机展示。

  • 添加所需的权限及声明Health Connect可见包名:
<manifest>
  <uses-permission android:name="android.permission.health.WRITE_EXERCISE"/>
  <uses-permission android:name="android.permission.health.WRITE_TOTAL_CALORIES_BURNED"/>

  <application>
  ...
  </application>
  <queries>
    <package android:name="com.google.android.apps.healthdata" />
  </queries>
</manifest>

权限根据App的情况添加,比如这里我不需要读取权限,只需要运动和卡路里的写入权限。

如需查看权限及其对应数据类型的完整列表,请参阅数据类型列表

  • 应用的隐私权政策

Android 清单需要有一个显示应用隐私权政策的承载页面,用于说明如何使用和处理用户数据。一般可以写一个Webview页面,加载对应的隐私政策链接。

...
<application>
  ...
  <!-- For supported versions through Android 13, create an activity to show the rationale
       of Health Connect permissions once users click the privacy policy link. -->
  <activity
      android:name=".PermissionsRationaleActivity"
      android:exported="true">
    <intent-filter>
      <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
    </intent-filter>
  </activity>

  <!-- For versions starting Android 14, create an activity alias to show the rationale
       of Health Connect permissions once users click the privacy policy link. -->
  <activity-alias
      android:name="ViewPermissionUsageActivity"
      android:exported="true"
      android:targetActivity=".PermissionsRationaleActivity"
      android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
    <intent-filter>
      <action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
      <category android:name="android.intent.category.HEALTH_PERMISSIONS" />
    </intent-filter>
  </activity-alias>
  ...
</application>
...

显示位置如下:

在这里插入图片描述

处理流程

检查Health Connect是否可用。
fun isSupported(context: Context): Boolean {
    
    
    val providerPackageName = "com.google.android.apps.healthdata"
    val availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName)
    if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) {
    
    
        return false // sdk不可用
    }
    if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
    
    
        // 安装healthconnect
        val uriString = "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding"
        context.startActivity(
            Intent(Intent.ACTION_VIEW).apply {
    
    
                setPackage("com.android.vending")
                data = Uri.parse(uriString)
                putExtra("overlay", true)
                putExtra("callerId", context.packageName)
            }
        )
        return false
    }
    return true
}

上面的代码首先检测Android版本是否符合,其次是否可用。

在这里插入图片描述

  • Health Connect 作为 Android 14系统的一部分打包在一起, 直接可用。且无法从设备上卸载,用户在设置 >安全与隐私权 >隐私权里进行设置。
  • Android 13 或更低版本需要在Google Play 商店中下载。
权限及数据操作

Health Connect 可用后,我们可以进行申请权限,判断权限,读写数据、

  • 申请权限
private val permissions = setOf(
    HealthPermission.getWritePermission(ExerciseSessionRecord::class),
    HealthPermission.getWritePermission(ActiveCaloriesBurnedRecord::class),
)
private val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()

val requestPermissions = registerForActivityResult(requestPermissionActivityContract) {
    
     granted ->
    if (granted.containsAll(permissions)) {
    
    
        // 成功授权
    } else {
    
    
        // 缺少所需的权限
    }
}
// 请求权限
requestPermissions.launch(permissions)
  • 检查权限

先使用getGrantedPermissions检查权限,没有权限时做权限申请。

suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
    
    
  val granted = healthConnectClient.permissionController.getGrantedPermissions()
  if (granted.containsAll(permissions)) {
    
    
    // 已授予的权限,可以继续执行插入或读取数据
  } else {
    
    
    requestPermissions.launch(PERMISSIONS)
  }
}
  • 写入数据
suspend fun writeExerciseSession(min: Int, calories: Double) {
    
    
    try {
    
    
        val end = ZonedDateTime.now().withNano(0)
        val start = end.plusMinutes(-min.toLong())
        healthConnectClient?.insertRecords(
            listOf(
                ExerciseSessionRecord(
                    startTime = start.toInstant(),
                    startZoneOffset = start.offset,
                    endTime = end.toInstant(),
                    endZoneOffset = end.offset,
                    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_STRENGTH_TRAINING,
                    title = "Workout"
                ),
                TotalCaloriesBurnedRecord(
                    startTime = start.toInstant(),
                    startZoneOffset = start.offset,
                    endTime = end.toInstant(),
                    endZoneOffset = end.offset,
                    energy = Energy.calories(calories)
                )
            )
        )
    } catch (e: Exception) {
    
    
        // Run error handling here
    }
}

这里简单演示了写入时长卡路里数据,其他类型数据操作方法可以参考官方文档。可以根据项目实际需求使用,这里就不赘述了。

另外注意

3.已知问题记录

三星健康

Health Connect让健康与健身应用在统一生态系统中存储和共享设备上的相同数据。所以除了常用的Google Fit外,三星健康也是可以读取其中的数据。

但是在测试的过程中发现三星健康中并不会读取显示。三星健康设置中也没有对应的Health Connect选项,即使我在Health Connect的管理页中发现了三星健康,并授予了全部权限。

经过后面的查找相关问题,发现在国行版本的三星健康上未开放此功能,据说可以使用国外SIM卡进行解锁(此方法未验证)。

检查是否已安装 Health Connect

Android 14以下手机需要安装Health Connect,没有安装时会跳转应用市场引导下载。这里注意对跳转方法做异常处理。否则会有ActivityNotFoundException异常。比如部分机型(华为)。

No Activity found to handle Intent {
    
     act=android.intent.action.VIEW dat=market://details?id=com.google.android.apps.healthdata&url=healthconnect://onboarding pkg=com.android.vending (has extras) }

RemoteException

Android 14以下手机因为安装了Health Connect,所以此APP一旦被杀死,服务停止,就无法正常使用。例如我们判断权限是否授权的方法getGrantedPermissions

报错信息:

android.os.RemoteException:Binding to service failed
androidx.health.connect.client.impl.HealthConnectClientImpl.getGrantedPermissions(SourceFile:23)
Caused by:
android.os.RemoteException:Binding to service failed
androidx.health.platform.client.impl.ipc.internal.ServiceConnection.connect(SourceFile:11)
androidx.health.platform.client.impl.ipc.internal.ServiceConnection.enqueue(SourceFile:4)
androidx.health.platform.client.impl.ipc.internal.ConnectionManager.handleMessage(SourceFile:27)
android.os.Handler.dispatchMessage(Handler.java:106)
android.os.Looper.loop(Looper.java:219)
android.os.HandlerThread.run(HandlerThread.java:67)

处理方法还是捕获一下异常,同时也可以提示用户启动Health Connect。打开应用后台自启动等开关。

总结

总体接入难度不高,只是会踩点小坑。记录分享出来,帮助有需要的人。

猜你喜欢

转载自blog.csdn.net/qq_17766199/article/details/142559877