寫入醫療資料

本指南適用於 Health Connect 1.1.0-beta02 版

如要在 Health Connect 中使用個人健康記錄 (PHR) 寫入醫療資料,請按照下列步驟操作:

  1. 檢查功能是否可用
  2. 要求寫入權限
  3. 建立資料來源 (MedicalDataSource)
  4. 撰寫醫學資源 (MedicalResource)

功能適用情況

如要判斷使用者的裝置是否支援 Health Connect 上的個人健康記錄,請檢查用戶端是否有 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

請在 Play 管理中心和應用程式資訊清單中,為應用程式聲明下列權限:

<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 要求這些權限。系統接著會顯示 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)
  }
}

由於使用者可隨時授予或撤銷權限,因此您的應用程式需要定期檢查授予的權限,並處理權限遺失的情況。

資料來源

Health Connect 中的 MedicalDataSource 代表面向使用者的資料來源,例如醫療機構、醫院或 API。

儲存在 Health Connect 中的醫療記錄會整理成 MedicalDataSource。這可讓您將來自不同來源 (例如 API 或醫療照護系統) 的相同病患醫療記錄分開。

如果所有記錄都來自相同來源,寫入應用程式只需建立一個 MedicalDataSource。如果記錄來自多個來源,只要資料已完成比對,且所有記錄都具有 FHIR 資源類型和 FHIR 資源 ID 的獨特組合,應用程式仍可建立單一 MedicalDataSource。否則,應為每個資料來源建立 MedicalDataSource

所有醫療記錄都必須與 MedicalDataSource 建立關聯,因此必須先建立 MedicalDataSource,才能寫入資源。

MedicalDataSource 的屬性:

  • 顯示名稱 (必要):資料來源的使用者端顯示名稱,每個寫入應用程式都有專屬的識別資訊。
  • FHIR 基本網址 (必要):如果資料來自 FHIR 伺服器,則應為 FHIR 基本網址 (例如 https://example.com/fhir/)。多個資料來源可與相同的 FHIR 基本網址建立關聯。

    如果資料是由應用程式產生,但沒有 FHIR 網址,則應為應用程式定義的專屬且易懂的 URI (例如 myapp://..),指向資料來源。

    舉例來說,如果用戶端應用程式支援深層連結,這個深層連結可用做為 FHIR 基本 URI。URI 的長度上限為 2000 個半形字元。

  • 套件名稱 (自動填入) - 寫入資料的應用程式。

  • 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)

醫療資源

Health Connect 中的 MedicalResource 代表 FHIR 資源 (包含醫療記錄) 和中繼資料。

MedicalResource 的屬性:

  • DataSourceId (必要):MedicalDataSource 的資料來源。
  • FHIR 版本 (必要) - FHIR 版本。必須是支援的版本
  • FHIR 資源 (必要):以 JSON 編碼的 FHIR 資源例項。
  • 醫療資源類型 (自動填入) - 資源的面向使用者的類別,對應至面向使用者的權限。

以 JSON 格式準備 FHIR 資源

將醫療資源寫入 Health Connect 之前,請先使用 JSON 格式準備 FHIR 資源記錄。將每個 JSON 儲存在各自的變數中,以便插入做為醫療資源。

如果您需要 FHIR JSON 格式相關協助,請參閱 HL7 機構提供的範例資料

插入或更新 MedicalResource 記錄

使用 UpsertMedicalResourceRequestMedicalDataSource 插入新的 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 字串。

以下是 JSON 的範例,其中 AllergyIntolerance 是 FHIR 資源類型,會對應至個人健康記錄中的 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)
    )
)