Gravar dados médicos

Este guia é compatível com a versão 1.1.0-beta02 do Health Connect.

Para gravar dados médicos usando os registros médicos na Conexão Saúde, siga estas etapas:

  1. Verificar a disponibilidade de recursos
  2. Solicitar permissões de gravação
  3. Criar uma fonte de dados (MedicalDataSource)
  4. Escrever um recurso médico (MedicalResource)

Disponibilidade do recurso

Para determinar se o dispositivo de um usuário é compatível com os registros médicos no Conexão Saúde, verifique a disponibilidade de FEATURE_PERSONAL_HEALTH_RECORD no cliente:

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

  // Feature is available
} else {
  // Feature isn't available
}

Consulte Verificar a disponibilidade de recursos para saber mais.

Permissões necessárias

A gravação de dados médicos é protegida pela seguinte permissão:

  • android.permission.health.WRITE_MEDICAL_DATA

Declare essas permissões no Play Console para seu app e no manifesto dele:

<application>
  <uses-permission
android:name="android.permission.health.WRITE_MEDICAL_DATA" />
</application>

Você é responsável por declarar todas as permissões adequadas que pretende usar nos seus dispositivos e apps. Verifique também se cada permissão foi concedida pelo usuário antes do uso.

Solicitar permissões do usuário

Depois de criar uma instância de cliente, seu app precisa solicitar permissões do usuário. Os usuários precisam poder conceder ou negar permissões a qualquer momento.

Para isso, crie um conjunto de permissões para os tipos de dados necessários. Verifique se as permissões no conjunto foram declaradas primeiro no manifesto do 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
)

Use getGrantedPermissions para verificar se o app já tem as permissões necessárias concedidas. Caso contrário, use createRequestPermissionResultContract para solicitar essas permissões. Isso mostra a tela de permissões da Conexão Saúde.

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

Como os usuários podem conceder ou revogar permissões a qualquer momento, seu app precisa verificar periodicamente as permissões concedidas e lidar com cenários em que a permissão é perdida.

Fontes de dados

Um MedicalDataSource na Conexão Saúde representa uma fonte de dados voltada ao usuário, como uma organização de saúde, um hospital ou uma API.

Os registros médicos armazenados na Conexão Saúde são organizados em um MedicalDataSource. Isso permite a separação de prontuários do mesmo indivíduo que vêm de diferentes fontes, como APIs ou sistemas de saúde.

Se todos os registros vierem da mesma origem, um app de escrita só precisará criar um MedicalDataSource. Se os registros vierem de várias fontes, um app ainda poderá criar um único MedicalDataSource se esses dados forem reconciliados e todos os registros tiverem uma combinação exclusiva de tipo de recurso e ID de recurso do FHIR. Caso contrário, um MedicalDataSource precisará ser criado para cada fonte de dados.

Todos os registros médicos precisam estar associados a um MedicalDataSource, que precisa ser criado antes de gravar os recursos.

Propriedades de MedicalDataSource:

  • Nome de exibição (obrigatório): nome de exibição voltado ao usuário para a fonte de dados, identificado de forma exclusiva por app de escrita.
  • URI base do FHIR (obrigatório): para dados de um servidor FHIR, esse campo precisa ser o URL base do FHIR (por exemplo, https://example.com/fhir/). Várias fontes de dados podem ser associadas ao mesmo URL base do FHIR.

    Se os dados forem gerados por um app sem um URL FHIR, esse será um URI exclusivo e compreensível definido pelo app (por exemplo, myapp://..) que aponta para a origem dos dados.

    Por exemplo, se um app cliente aceitar links diretos, esse link poderá ser usado como o URI base do FHIR. O comprimento máximo do URI é de 2.000 caracteres.

  • Nome do pacote (preenchido automaticamente): o app que grava os dados.

  • Versão do FHIR (obrigatório): a versão do FHIR. Precisa ser uma versão compatível.

Criar um registro MedicalDataSource

Crie um registro para cada organização ou entidade de saúde a que seu app está vinculado.

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

Excluir um registro MedicalDataSource

O exemplo anterior retorna um id pelo sistema na criação. Se você precisar excluir o registro MedicalDataSource, faça referência ao mesmo id:

// Delete the `MedicalDataSource` that has the specified `id`
healthConnectClient.deleteMedicalDataSourceWithData(medicalDataSource.id)

Recursos médicos

Um MedicalResource no app Conexão Saúde representa um recurso FHIR (que contém um registro médico), além de metadados.

Propriedades de MedicalResource:

  • DataSourceId (obrigatório): fonte de dados conforme descrito para um MedicalDataSource.
  • Versão do FHIR (obrigatório): a versão do FHIR. Precisa ser uma versão compatível.
  • Recurso FHIR (obrigatório): a instância do recurso FHIR codificada em JSON.
  • Tipo de recurso médico (preenchido automaticamente): a categoria voltada ao usuário do recurso, mapeada para permissões voltadas ao usuário.

Preparar recursos FHIR em JSON

Antes de gravar recursos médicos no Conexão Saúde, prepare os registros de recursos FHIR em JSON. Armazene cada JSON em uma variável própria para inserir como um recurso médico.

Se precisar de ajuda com o formato JSON do FHIR, consulte os dados de exemplo fornecidos pela organização HL7.

Inserir ou atualizar registros MedicalResource

Use UpsertMedicalResourceRequest para inserir ou atualizar registros de MedicalResource de um 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
            )
        )
    )

Exemplo de recurso FHIR

No exemplo anterior, a variável medicationJsonToInsert representava uma string JSON FHIR válida.

Confira um exemplo de como esse JSON pode ser, usando AllergyIntolerance como o tipo de recurso FHIR, que seria mapeado para o tipo de recurso médico FHIR_RESOURCE_TYPE_ALLERGY_INTOLERANCE em Prontuários médicos:

{
  "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"
  }
  ...
}

Excluir um registro MedicalResource

Os registros de MedicalResource podem ser excluídos por 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
        )
    }
)

Ou podem ser excluídos por 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)
    )
)