Запись медицинских данных

Это руководство совместимо с платформой "Здоровье и спорт" версии 1.1.0-beta02 или более поздней.

Чтобы записывать медицинские данные с помощью функции "Медицинские карты" на платформе "Здоровье и спорт", выполните следующие действия:

  1. Проверьте доступность функции
  2. Запросите разрешение на запись
  3. Создание источника данных (MedicalDataSource)
  4. Запись медицинского ресурса (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

Укажите эти разрешения в 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 учитывайте следующее:

  • Если все записи получены из одного источника, создайте один объект MedicalDataSource.
  • Если записи поступают из нескольких источников, вы можете создать один файл MedicalDataSource, если:
    • Данные согласованы.
    • У всех записей есть уникальная комбинация типа и идентификатора ресурса FHIR. В MedicalDataSource может быть только одна запись типа ресурса FHIR с любым идентификатором ресурса FHIR.
  • В противном случае, чтобы избежать дублирования идентификаторов, создайте MedicalDataSource для каждого источника данных.

Все медицинские карты должны быть связаны с MedicalDataSource, поэтому его нужно создать до записи ресурсов.

Свойства MedicalDataSource:

  • Отображаемое название (обязательно) – название источника данных, которое видит пользователь. Оно должно быть уникальным для каждого приложения, записывающего данные.
  • Базовый URI FHIR (обязательно). Для данных, поступающих с сервера FHIR, это должен быть базовый URL FHIR (например, https://example.com/fhir/). С одним базовым URL FHIR можно связать несколько источников данных.

    Если данные генерируются приложением без URL-адреса FHIR, это должен быть уникальный и понятный URI, определенный приложением (например, myapp://..), который указывает на источник данных.

    Например, если клиентское приложение поддерживает ссылки на контент, то такую ссылку можно использовать в качестве базового URI FHIR. Максимальная длина 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)

Медицинские ресурсы

MedicalResource на платформе "Здоровье и спорт" представляет собой ресурс FHIR (содержащий медицинскую карту) и метаданные.

Свойства MedicalResource:

  • DataSourceId (обязательно) – источник данных, как описано для MedicalDataSource.
  • Версия FHIR (обязательно) – версия FHIR. Убедитесь, что у вас поддерживаемая версия.
  • Ресурс FHIR (обязательно). Экземпляр ресурса FHIR в кодировке JSON.
  • Тип медицинского ресурса (заполняется автоматически) – пользовательская категория ресурса, сопоставленная с пользовательскими разрешениями.

Подготовьте ресурсы FHIR в формате JSON

Прежде чем записывать медицинские ресурсы на платформу "Здоровье и спорт", подготовьте записи ресурсов FHIR в формате JSON. Сохраните каждый JSON в отдельной переменной, чтобы вставить его как медицинский ресурс.

Если вам нужна помощь с форматом FHIR JSON, ознакомьтесь с примером данных, предоставленным организацией HL7.

Вставка или обновление записей MedicalResource

Используйте UpsertMedicalResourceRequest, чтобы вставить новые или обновить существующие записи MedicalResource для MedicalDataSource:

// 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 представляла собой допустимую строку JSON FHIR.

Ниже приведен пример того, как может выглядеть 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 записей можно удалить по идентификатору:

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