開始使用 Health Connect

本指南說明如何開始在應用程式使用 Health Connect。

步驟 1:準備 Health Connect 應用程式

Health Connect 應用程式負責處理應用程式透過 Health Connect SDK 傳送的所有要求,包括儲存資料及管理其讀取和寫入權限。

Health Connect 的存取權取決於手機安裝的 Android 版本。下列各節會概述如何處理多個近期的 Android 版本。

Android 14

從 Android 14 (API 級別 34) 開始,Health Connect 是 Android 架構的一部分。此版本的 Health Connect 是「架構模組」,因此您不需要進行設定。

Android 13 以下版本

在 Android 13 (API 級別 33) 以下版本中,Health Connect 不屬於 Android 架構,因此您必須從 Google Play 商店安裝 Health Connect 應用程式

如果您已在 Android 13 以下版本將應用程式與 Health Connect 整合,且想在 Android 14 執行遷移,請參閱「從 Android 13 遷移至 Android 14」。

開啟 Health Connect 應用程式

Health Connect 不再預設出現於主畫面。因此如要開啟 Health Connect,請依序前往「設定」>「應用程式」>「Health Connect」,也可以將 Health Connect 新增到「快速設定」選單。

此外,Health Connect 會要求使用者啟用設有 PIN 碼、解鎖圖案或密碼的螢幕鎖定功能,以便在裝置鎖定時防止惡意人士取得儲存在 Health Connect 中的健康資料。如要設定螢幕鎖定功能,請依序前往「設定」>「安全性」>「螢幕鎖定」

步驟 2:在應用程式中加入 Health Connect SDK

Health Connect SDK 負責透過 Health Connect API,在執行中的作業內,傳送要求到 Health Connect 應用程式中的資料儲存庫。

在模組層級的 build.gradle 檔案中新增 Health Connect SDK 依附元件:

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

如需查看最新版本,請參閱 Health Connect 版本

步驟 3:設定應用程式

以下各節說明如何設定應用程式,進而與 Health Connect 整合。

宣告權限

存取健康與健身資料需搭配保護措施。Health Connect 導入讀取與寫入作業安全層,可提供使用者信任感。

請依據需要的資料類型,在 AndroidManifest.xml 檔案宣告讀取及寫入權限。填妥表單後,請確保您使用的權限組,與所要求的存取權相應。

Health Connect 使用標準 Android 權限聲明格式,請以 <uses-permission> 標記指派權限。然後,在 <manifest> 標記內建立巢狀結構。

<manifest>
  <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>
  ...
  </application>
</manifest>

如需權限及對應資料類型的完整清單,請參閱「資料類型清單」一文。

顯示應用程式的隱私權政策對話方塊

您的 Android 資訊清單必須有顯示應用程式隱私權政策的 Activity,也就是應用程式要求權限的理由,說明使用者資料的使用和處理方式。

當使用者在 Health Connect 權限畫面中點選「隱私權政策」連結時,請宣告這個活動以處理傳送至應用程式的 ACTION_SHOW_PERMISSIONS_RATIONALE 意圖。

...
<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 用戶端

HealthConnectClient 是 Health Connect API 的進入點。 它會允許應用程式在 Health Connect 應用程式中使用資料儲存庫,會自動管理自身與基礎儲存空間層的連線,並處理傳出要求與傳入回應的所有處理序間通訊 (IPC) 和序列化作業。

如要取得用戶端執行個體,請先在 Android 資訊清單中宣告 Health Connect 套件名稱。

<application> ... </application>
...
<!-- Check if Health Connect is installed -->
<queries>
    <package android:name="com.google.android.apps.healthdata" />
</queries>

接著在 Activity 中,使用 getSdkStatus 檢查是否已安裝 Health Connect。如果已安裝,請取得 HealthConnectClient 執行個體。

val availabilityStatus = HealthConnectClient.getSdkStatus(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:要求使用者授予權限

建立用戶端執行個體後,應用程式必須要求使用者授予權限。使用者必須能隨時授予或拒絕權限。

如要這麼做,請為所需資料類型建立一組權限。請務必先在 Android 資訊清單中聲明該組權限。

// Create a set of permissions 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 要求這些權限。系統接著會顯示 Health Connect 權限畫面。

// 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 的各項功能,以及可實現流暢整合的最佳做法指南:

資源

請查看下列資源,以便日後開發。

後續步驟

請參考常見工作流程,瞭解如何在 Health Connect 中執行作業,例如: