ヘルスコネクトの医療記録を使用して医療データを書き込むには、次の手順を行います。
- 使用できる機能を確認する
- 書き込み権限をリクエストする
- データソースを作成する(MedicalDataSource)
- 医療リソースを作成する(MedicalResource)
機能の提供状況
ユーザーのデバイスがヘルスコネクトの医療記録をサポートしているかどうかを判断するには、クライアントでFEATURE_PERSONAL_HEALTH_RECORD の可用性を確認します。
if (healthConnectClient
     .features
     .getFeatureStatus(
       HealthConnectFeatures.FEATURE_PERSONAL_HEALTH_RECORD
     ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {
  // Feature is available
} else {
  // Feature isn't available
}
必要な権限
医療データの書き込みは、次の権限によって保護されています。
- android.permission.health.WRITE_MEDICAL_DATA
これらの権限は、アプリの Google Play Console とアプリのマニフェストで宣言します。
<application>
  <uses-permission
android:name="android.permission.health.WRITE_MEDICAL_DATA" />
</application>
デバイスとアプリで使用するすべての適切な権限を宣言する責任はお客様にあります。また、使用前に各権限がユーザーによって付与されていることを確認する必要があります。
ユーザーに権限をリクエストする
クライアント インスタンスを作成した後、アプリはユーザーに権限をリクエストする必要があります。ユーザーがいつでも権限を付与または拒否できるようにする必要があります。
そのためには、必要なデータ型の権限セットを作成します。まず、セット内の権限が Android マニフェストで宣言されていることを確認します。
// Create a set of permissions for required data types
import androidx.health.connect.client.permission.HealthPermission.Companion.PERMISSION_WRITE_MEDICAL_DATA
val PERMISSIONS =
    setOf(
       PERMISSION_WRITE_MEDICAL_DATA
)
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)
  }
}
ユーザーはいつでも権限を付与または取り消すことができるため、アプリは許可されている権限を定期的に確認し、権限がなくなっている場合に対処できるようにする必要があります。
データソース
ヘルスコネクトの MedicalDataSource は、医療機関、病院、API などのユーザー向けのデータソースを表します。
ヘルスコネクトに保存された医療記録は MedicalDataSource に整理されます。これにより、API や医療システムなど、異なるソースから提供された同じ個人の医療記録を分離できます。
MedicalDataSource レコードを作成する際は、次の点を考慮してください。
- すべてのレコードが同じソースから取得された場合は、1 つの MedicalDataSourceを作成します。
- レコードが複数のソースから生成される場合は、次の条件を満たせば、1 つの MedicalDataSourceを作成できます。- データが調整されます。
- すべてのレコードには、FHIR リソースタイプと FHIR リソース ID の一意の組み合わせがあります。MedicalDataSource内には、FHIR リソース ID を持つ FHIR リソースタイプのレコードを 1 つだけ含めることができます。
 
- それ以外の場合は、重複する ID を防ぐため、データソースごとに MedicalDataSourceを作成します。
すべての医療記録は MedicalDataSource に関連付けられている必要があるため、リソースを書き込む前に作成する必要があります。
MedicalDataSource のプロパティ:
- 表示名(必須) - データソースのユーザー向けの表示名。書き込みアプリごとに一意に識別されます。
- FHIR ベース URI(必須) - FHIR サーバーから取得したデータの場合、これは FHIR ベース URL( - https://example.com/fhir/など)である必要があります。複数のデータソースを同じ FHIR ベース URL に関連付けることができます。- データが FHIR URL のないアプリによって生成された場合、これはアプリによって定義された一意でわかりやすい URI(例: - myapp://..)で、データのソースを指している必要があります。- たとえば、クライアント アプリがディープリンクをサポートしている場合、このディープリンクを FHIR ベース URI として使用できます。URI の最大長は 2,000 文字です。 
- パッケージ名(自動入力) - データを書き込むアプリ。 
- FHIR バージョン(必須) - FHIR バージョン。サポートされているバージョンである必要があります。 
MedicalDataSource レコードを作成する
アプリがリンクされている医療機関またはエンティティごとにレコードを作成します。
// Create a `MedicalDataSource`
// Note that `displayName` must be unique across `MedicalDataSource`s
// Each `MedicalDataSource` is assigned an `id` by the system on creation
val medicalDataSource: MedicalDataSource =
    healthConnectClient.createMedicalDataSource(
        CreateMedicalDataSourceRequest(
            fhirBaseUri = Uri.parse("https://fhir.com/oauth/api/FHIR/R4/"),
            displayName = "Test Data Source",
            fhirVersion = FhirVersion(4, 0, 1)
        )
    )
MedicalDataSource レコードを削除する
前の例では、作成時にシステムによって id が返されます。MedicalDataSource レコードを削除する必要がある場合は、同じ id を参照します。
// Delete the `MedicalDataSource` that has the specified `id`
healthConnectClient.deleteMedicalDataSourceWithData(medicalDataSource.id)
医療リソース
ヘルスコネクトの MedicalResource は、メタデータとともに FHIR リソース(医療記録を含む)を表します。
MedicalResource のプロパティ:
- DataSourceId(必須)- MedicalDataSourceで説明されているデータソース。
- FHIR バージョン(必須) - FHIR バージョン。サポートされているバージョンである必要があります。
- FHIR リソース(必須): JSON エンコードされた FHIR リソース インスタンス。
- 医療リソースのタイプ(自動入力) - リソースのユーザー向けカテゴリ。ユーザー向け権限にマッピングされます。
JSON で FHIR リソースを準備する
医療リソースをヘルスコネクトに書き込む前に、FHIR リソース レコードを JSON で準備します。各 JSON を独自の変数に保存して、医療リソースとして挿入します。
FHIR JSON 形式についてサポートが必要な場合は、HL7 組織が提供するサンプルデータをご覧ください。
MedicalResource レコードを挿入または更新する
UpsertMedicalResourceRequest を使用して、MedicalDataSource の新しい MedicalResource レコードを挿入するか、既存の MedicalResource レコードを更新します。
// Insert `MedicalResource`s into the `MedicalDataSource`
val medicalResources: List<MedicalResource> =
    healthConnectClient.upsertMedicalResources(
        listOf(
            UpsertMedicalResourceRequest(
                medicalDataSource.id,
                medicalDataSource.fhirVersion,
                medicationJsonToInsert // a valid FHIR json string
            )
        )
    )
// Update `MedicalResource`s in the `MedicalDataSource`
val updatedMedicalResources: List<MedicalResource> =
    healthConnectClient.upsertMedicalResources(
        listOf(
            UpsertMedicalResourceRequest(
                medicalDataSource.id,
                medicalDataSource.fhirVersion,
                // a valid FHIR json string
                // if this resource has the same type and ID as in `medicationJsonToInsert`,
                // this `upsertMedicalResources()` call will update the previously inserted
                // `MedicalResource`
                updatedMedicationJsonToInsert
            )
        )
    )
FHIR リソースの例
前の例では、変数 medicationJsonToInsert は有効な FHIR JSON 文字列を表していました。
FHIR リソースタイプとして AllergyIntolerance を使用した場合の JSON の例を次に示します。これは、Medical Records の FHIR_RESOURCE_TYPE_ALLERGY_INTOLERANCE の医療リソースタイプにマッピングされます。
{
  "resourceType": "AllergyIntolerance",
  "id": "allergyintolerance-1",
  "criticality": "high",
  "code": {
    "coding": [
      {
        "system": "http://snomed.info/sct",
        "code": "91936005",
        "display": "Penicillin allergy"
      }
    ],
    "text": "Penicillin allergy"
  },
  "recordedDate": "2020-10-09T14:58:00+00:00",
   "asserter": {
    "reference": "Patient/patient-1"
  },
  "lastOccurrence": "2020-10-09",
  "patient": {
    "reference": "Patient/patient-1",
    "display": "B., Alex"
  }
  ...
}
MedicalResource レコードを削除する
MedicalResource レコードは ID で削除できます。
// Delete `MedicalResource`s matching the specified `dataSourceId`, `type` and `fhirResourceId`
healthConnectClient.deleteMedicalResources(
    medicalResources.map { medicalResource: MedicalResource ->
        MedicalResourceId(
            dataSourceId = medicalDataSource.id,
            fhirResourceType = medicalResource.id.fhirResourceType,
            fhirResourceId = medicalResource.id.fhirResourceId
        )
    }
)
または、medicalResourceType で削除することもできます。
// Delete all `MedicalResource`s that are in any pair of provided `dataSourceIds` and
// `medicalResourceTypes`
healthConnectClient.deleteMedicalResources(
    DeleteMedicalResourcesRequest(
        dataSourceIds = setOf(medicalDataSource.id),
        medicalResourceTypes = setOf(MEDICAL_RESOURCE_TYPE_MEDICATIONS)
    )
)
