ヘルスコネクトを使ってみる

このガイドは、ヘルスコネクトのバージョン 1.1.0-alpha12 に対応しています。

このガイドでは、アプリでヘルスコネクトの使用を開始する方法について説明します。

ステップ 1: ヘルスコネクト アプリを準備する

ヘルスコネクト アプリは、アプリがヘルスコネクト SDK を介して送信するすべてのリクエストを処理します。リクエストには、データの保存や読み取り / 書き込みアクセス権の管理などがあります。

ヘルスコネクトへのアクセスは、スマートフォンにインストールされている Android のバージョンによって異なります。以下のセクションでは、Android の最近のバージョンを処理する方法の概要を示します。

Android 14

Android 14(API レベル 34)以降、ヘルスコネクトは Android フレームワークの一部になっています。このバージョンのヘルスコネクトはフレームワーク モジュールです。そのため、セットアップは必要ありません。

Android 13 以前

Android 13(API レベル 33)以前のバージョンでは、ヘルスコネクトは Android フレームワークの一部ではありません。そのため、Google Play ストアからヘルスコネクト アプリをインストールする必要があります。

Android 13 以前のヘルスコネクトとアプリを統合していて、Android 14 に移行する場合は、Android 13 から Android 14 に移行するをご覧ください。

ヘルスコネクト アプリを開く

ヘルスコネクトは、デフォルトではホーム画面に表示されません。ヘルスコネクトを開くには、[**設定**] に移動します。パスは Android のバージョンによって異なります。

  • Android 14 以降の場合: 設定 > セキュリティとプライバシー > プライバシー管理 > ヘルスコネクト に移動するか、設定で「ヘルスコネクト 」を検索します。
  • Android 13 以前の場合: 設定 > アプリ > ヘルスコネクト に移動するか、[クイック設定] メニューにヘルスコネクトを追加します。

ステップ 2: ヘルスコネクト SDK をアプリに追加する

ヘルスコネクト SDK は、Health Connect API を使用して、ヘルスコネクト アプリでデータストアに対してオペレーションを実行するときにリクエストを送信します。

ヘルスコネクト SDK の依存関係をモジュール レベルの build.gradle ファイルに追加します。

dependencies {
  ...
  implementation "androidx.health.connect:connect-client:1.2.0-alpha04"
  ...
}

最新バージョンについては、ヘルスコネクトのリリース情報をご覧ください。

カナリア リリース チャンネルの機能を使用する

[Canary] リリース チャンネルの機能を使用するには、モジュール レベルの build.gradle ファイルで compileSdk のバージョンを変更します。

android {
  compileSdkPreview = "CANARY"
}

ステップ 3: アプリを構成する

以下のセクションでは、ヘルスコネクトと統合するようにアプリを構成する方法について説明します。

使用できる機能を確認する

ヘルスコネクトに新機能が追加されても、ユーザーがヘルスコネクトのバージョンを更新するとは限りません。Feature Availability API を使用すると、ヘルスコネクトの機能がユーザーのデバイスで利用可能かどうかを確認し、取るべきアクションを決定できます。

機能の可用性を確認する主な関数は getFeatureStatus()です。この関数は、整数定数 FEATURE_STATUS_AVAILABLE または FEATURE_STATUS_UNAVAILABLE を返します。

if (healthConnectClient
     .features
     .getFeatureStatus(
       HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND
     ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {

  // Feature is available
  ...
} else {
  // Feature is not available
  ...
}

権限を宣言する

健康とフィットネスに関するデータへのアクセス権は機密情報です。ヘルスコネクトは、読み取りおよび書き込みオペレーションにセキュリティ レイヤを実装し、ユーザーの信頼を保ちます。

アプリでは、必要なデータ型に基づいて AndroidManifest.xml ファイルで読み取り権限と書き込み権限を宣言します。これらのデータ型は、Google Play Console でアクセスを宣言したデータ型と一致している必要があります。

ヘルスコネクトは、標準の 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 マニフェストには、アプリのプライバシー ポリシーを表示するアクティビティが必要です。プライバシー ポリシーとは、アプリがリクエストする権限の根拠であり、ユーザーデータの使用方法と処理方法を説明します。

このアクティビティを宣言し、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 API のエントリ ポイントは HealthConnectClient です。これにより、アプリはヘルスコネクト アプリでデータストアを使用できるようになります。基盤となるストレージ レイヤへの接続を自動的に管理し、すべての IPC を処理し、送信リクエストと受信レスポンスをシリアル化します。

クライアント インスタンスを取得するには、まず Android マニフェストでヘルスコネクト パッケージ名を宣言します。

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

次に、アクティビティで、ヘルスコネクトがインストールされているかどうかを確認します getSdkStatus。インストールされている場合は、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を使用して 権限をリクエストします。ヘルスコネクトの権限画面が表示されます。

// 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)
  }
}

ユーザーはいつでも権限を付与または取り消すことができるため、アプリは権限を使用するたびに権限を確認し、権限が失われた場合の処理を行う必要があります。

ユーザーをオンボーディングする

多くのアプリには機能の説明やユーザーの同意の確認など、カスタムのオンボーディング フローがあります。ヘルスコネクトでオンボーディング フローを起動できるようにするには、マニフェストに以下を追加します。

<!-- Required to support pre-Android 14 devices with APK Health Connect -->
<activity
  android:name=".OnboardingActivity"
  android:exported="true"
  android:permission="com.google.android.apps.healthdata.permission.START_ONBOARDING">
  <intent-filter>
    <action android:name="androidx.health.ACTION_SHOW_ONBOARDING"/>
  </intent-filter>
</activity>
<!-- Required to support Android 14+ devices with platform Health Connect -->
<activity-alias
  android:name="UAndAboveOnboardingActivity"
  android:exported="true"
  android:targetActivity=".OnboardingActivity"
  android:permission="android.permission.health.START_ONBOARDING">
  <intent-filter>
    <action android:name="android.health.connect.action.SHOW_ONBOARDING" />
  </intent-filter>
</activity-alias>

ユーザーは、アプリ内からではなく、ヘルスコネクト アプリから直接アプリへの接続を開始する場合があります。データの読み取りまたは書き込み権限の付与以外に追加の操作が必要な場合は、オンボーディング アクティビティを提供します。

オンボーディング アクティビティは、複数回起動される場合があります。後でユーザーがアプリの権限を取り消して、再度接続した場合などが該当します。

ステップ 5: オペレーションを実行する

すべての設定が完了したので、アプリで読み取りオペレーションと書き込みオペレーションを実行します。

ユーザーは、アプリがアクセスするデータをヘルスコネクトと同期する他のアプリを使用している可能性があります。ユーザーがこれらのアプリをヘルスコネクトに書き込むように設定していない 場合は、Matchmaking API を使用して、これらのアプリをユーザーにシームレスに接続できます。

データを書き込む

データをレコードに構造化します。ヘルスコネクトで利用可能なデータ型のリストを確認します。

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) {
    val endTime = Instant.now()
    val startTime = endTime.minus(Duration.ofMinutes(15))
    try {
        val stepsRecord = StepsRecord(
            count = 120,
            startTime = startTime,
            endTime = endTime,
            startZoneOffset = ZoneOffset.UTC,
            endZoneOffset = ZoneOffset.UTC,
            metadata = Metadata.autoRecorded(
                device = Device(type = Device.TYPE_WATCH)
            ),
        )
        healthConnectClient.insertRecords(listOf(stepsRecord))
    } catch (e: Exception) {
        // Run error handling here
    }
}

データを読み取る

readRecords を使用すると、データを個別に読み取ることができます。

suspend fun readHeartRateByTimeRange(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    try {
        val response = healthConnectClient.readRecords(
            ReadRecordsRequest(
                HeartRateRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
        for (record in response.records) {
            // Process each 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
    }
}

動画チュートリアル

ヘルスコネクトの機能と、スムーズな統合を実現するためのベスト プラクティスのガイドラインについては、次の動画をご覧ください。

リソース

今後の開発に役立つ以下のリソースをご覧ください。

次のステップ

ヘルスコネクトで次のような操作を行う方法については、一般的なワークフローをご覧ください。