开始使用

本指南介绍如何开始在应用中使用 Health Connect API。

资源

在开始之前,您可以查看以下资源,它们有助于之后的开发工作。

  • Health Connect SDK(可在 Jetpack 上获取)。在您的应用中添加此 SDK,以便使用 Health Connect API。
  • API 参考文档。查看适用于 Health Connect API 的 Jetpack 参考文档
  • API 请求开发者声明表单。可使用此表单请求对数据类型的读取和写入权限。
  • 可选:GitHub 代码示例和 Codelab。参阅 GitHub 代码示例仓库Codelab 练习,以便快速上手。

第 1 步:访问 Health Connect

如何访问 Health Connect 取决于您使用的 Android 版本。

Android 13

从 Google Play 商店安装 Health Connect。它使用 Health Connect SDK 处理您的应用发送的所有请求。

Android 14

对于 Android 14 及更高版本,Health Connect 是 Android 框架的一部分。此版本被称为框架模块。

如果您已在 Android 13 上与 Health Connect 集成,并且希望在 Android 14 上这样做,请参阅从 Android 13 迁移到 Android 14

第 2 步:将 Health Connect SDK 添加到您的应用

在模块级别的 build.gradle 文件中添加对 Health Connect SDK 的依赖项:

dependencies {
  ...
  implementation "androidx.health.connect:connect-client:1.1.0-alpha02"
  ...
}

如需查看最新版本,请参阅 Health Connect 版本

第 3 步:配置并初始化 Health Connect

若要与 Health Connect 集成,请配置 Android 清单以执行以下操作:

  • 声明权限以获取对所选数据类型的读写权限。如需查看权限及其对应数据类型的完整列表,请参阅数据类型列表
  • 对相应 activity 声明 ACTION_SHOW_PERMISSIONS_RATIONALE intent,以向用户显示获取相应 Health Connect 权限的理由。此 activity 会将用户引导至阅读隐私权政策对话框。
  • 声明 Health Connect 软件包名称以将某个 HealthConnectClient 实例初始化。
<manifest>
  ...
  <!-- Declare permissions -->
  <uses-permission android:name="android.permission.health.READ_HEART_RATE"/>
  <uses-permission android:name="android.permission.health.WRITE_HEART_RATE"/>
  <uses-permission android:name="android.permission.health.READ_STEPS"/>
  <uses-permission android:name="android.permission.health.WRITE_STEPS"/>

  <application>
    ...
    <!-- Create an activity to show rationale of Android 13 Health Connect permissions -->
    <activity
        android:name=".PermissionsRationaleActivity"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
      </intent-filter>
    </activity>

<!-- Create an activity alias to show rationale of Android 14 Health Connect permissions -->
    <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>

  <!-- Declare the Health Connect package name to initialize the client -->
  <queries>
      <package android:name="com.google.android.apps.healthdata" />
  </queries>
  ...
</manifest>

在您的 activity 的 onCreate() 函数中,创建一个用于检查 Health Connect 是否可用的条件。如果可用,则获取 HealthConnectClient 实例。

val availabilityStatus = HealthConnectClient.sdkStatus(context, providerPackageName)
if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) {
  return // early return as there is no viable integration
}
if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
  // Optionally redirect to package installer to find a provider, for example:
  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
}
val healthConnectClient = HealthConnectClient.getOrCreate(context)
// Issue operations with healthConnectClient

第 4 步:向用户请求权限

为所需的数据类型创建一个权限集。先确保此集中的权限已在清单中声明。

// Create a set of permission strings for required data types
val PERMISSIONS =
setOf(
  HealthPermission.getReadPermission(HeartRateRecord::class),
  HealthPermission.getWritePermission(HeartRateRecord::class),
  HealthPermission.getReadPermission(StepsRecord::class),
  HealthPermission.getWritePermission(StepsRecord::class)
)

使用 getGrantedPermissions 查看您的应用是否已具备所需的权限。如不具备,请使用 createRequestPermissionResultContract 请求权限。

// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()

val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
  if (granted.containsAll(PERMISSIONS)) {
    // Permissions successfully granted
  } else {
    // Lack of required permissions
  }
}

suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
  val granted = healthConnectClient.permissionController.getGrantedPermissions()
  if (granted.containsAll(PERMISSIONS)) {
    // Permissions already granted; proceed with inserting or reading data
  } else {
    requestPermissions.launch(PERMISSIONS)
  }
}

第 5 步:执行操作

现在,一切都已设置完毕,在您的应用中执行读写操作。

写入数据

将您的数据构建成一个记录。查看 Health Connect 中支持的数据类型列表。

val stepsRecord = StepsRecord(
    count = 120,
    startTime = START_TIME,
    endTime = END_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endZoneOffset = END_ZONE_OFFSET,
)

然后,使用 insertRecords 写入记录。

suspend fun insertSteps(healthConnectClient: HealthConnectClient) {
    try {
        val stepsRecord = StepsRecord(
            count = 120,
            startTime = START_TIME,
            endTime = END_TIME,
            startZoneOffset = START_ZONE_OFFSET,
            endZoneOffset = END_ZONE_OFFSET,
        )
        healthConnectClient.insertRecords(listOf(stepsRecord))
    } catch (e: Exception) {
        // Run error handling here
    }
}

读取数据

您可以使用 readRecords 逐个读取数据。

suspend fun readStepsByTimeRange(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response =
            healthConnectClient.readRecords(
                ReadRecordsRequest(
                    StepsRecord::class,
                    timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
                )
            )
        for (stepRecord in response.records) {
            // Process each step record
        }
    } catch (e: Exception) {
        // Run error handling here.
    }
}

您还可以使用 aggregate 以汇总方式读取数据。

suspend fun aggregateSteps(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response = healthConnectClient.aggregate(
            AggregateRequest(
                metrics = setOf(StepsRecord.COUNT_TOTAL),
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
        // The result may be null if no data is available in the time range
        val stepCount = response[StepsRecord.COUNT_TOTAL]
    } catch (e: Exception) {
        // Run error handling here
    }
}

视频教程

观看以下视频,详细了解 Health Connect 功能以及实现顺畅集成方面的最佳实践指南:

后续步骤

查看以下指南,详细了解此处提及的步骤: