이 가이드는 Health Connect 버전 1.1.0-beta02와 호환됩니다.
헬스 커넥트에서 개인 건강 기록 (PHR)을 사용하여 의료 데이터를 쓰려면 다음 단계를 따르세요.
- 기능 사용 가능 여부 확인
- 쓰기 권한 요청
- 데이터 소스 만들기 (
MedicalDataSource
) - 의료 리소스 작성 (
MedicalResource
)
기능 사용 가능 여부
사용자의 기기가 헬스 커넥트에서 PHR을 지원하는지 확인하려면 클라이언트에서 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 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
를 하나만 만들면 됩니다. 레코드가 여러 소스에서 발생하는 경우에도 데이터가 조정되고 모든 레코드에 고유한 FHIR 리소스 유형과 FHIR 리소스 ID 조합이 있는 경우 앱은 단일 MedicalDataSource
를 만들 수 있습니다.
그러지 않으면 각 데이터 소스에 대해 MedicalDataSource
가 만들어져야 합니다.
모든 의료 기록은 MedicalDataSource
와 연결되어야 하므로 리소스를 작성하기 전에 만들어야 합니다.
MedicalDataSource
의 속성:
- 표시 이름 (필수) - 데이터 소스의 사용자 대상 표시 이름으로, 작성 앱별로 고유하게 식별됩니다.
FHIR 기본 URI (필수) - FHIR 서버에서 가져온 데이터의 경우 FHIR 기본 URL이어야 합니다 (예:
https://example.com/fhir/
). 여러 데이터 소스를 동일한 FHIR 기본 URL과 연결할 수 있습니다.데이터가 FHIR URL이 없는 앱에서 생성된 경우 데이터 소스를 가리키는 앱에서 정의한 고유하고 이해하기 쉬운 URI(예:
myapp://..
)여야 합니다.예를 들어 클라이언트 앱이 딥 링크를 지원하는 경우 이 딥 링크를 FHIR Base 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 리소스 준비
헬스 커넥트에 의료 리소스를 쓰기 전에 JSON으로 FHIR 리소스 레코드를 준비합니다. 각 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 문자열을 나타냈습니다.
다음은 AllergyIntolerance를 FHIR 리소스 유형으로 사용하여 PHR의 FHIR_RESOURCE_TYPE_ALLERGY_INTOLERANCE
의학 리소스 유형에 매핑되는 JSON의 예입니다.
{
"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)
)
)