Gravar dados médicos

Este guia é compatível com a versão 1.1.0-beta02 do Conexão Saúde.

Para gravar dados médicos usando registros de saúde pessoais (PHRs) na Conexão Saúde, siga estas etapas:

  1. Conferir a disponibilidade dos 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 oferece suporte à PHR na 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 estas permissões no Play Console e no manifesto do app:

<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 ao usuário. Os usuários precisam ter permissão para conceder ou negar permissões a qualquer momento.

Para fazer isso, crie um conjunto de permissões para os tipos de dados necessários. Verifique se as permissões no conjunto foram declaradas no manifesto do Android primeiro.

// 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 conferir se o app já tem as permissões necessárias. Caso contrário, use createRequestPermissionResultContract para solicitar essas permissões. A tela de permissões da Conexão Saúde será exibida.

// 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 processar cenários em que a permissão é perdida.

Fontes de dados

Um MedicalDataSource na Conexão Saúde representa uma origem 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 registros médicos do mesmo indivíduo que vêm de diferentes fontes, como APIs ou sistemas de saúde.

Se todos os registros tiverem a mesma origem, um app de gravação só precisará criar um MedicalDataSource. Se os registros tiverem origem em 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 do FHIR e ID do recurso do FHIR. Caso contrário, uma MedicalDataSource precisa ser criada para cada fonte de dados.

Todos os registros médicos precisam ser 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 para o usuário da fonte de dados, identificado de forma exclusiva por app de gravação.
  • URI base FHIR (obrigatório): para dados provenientes de um servidor FHIR, esse valor precisa ser o URL base FHIR (por exemplo, https://example.com/fhir/). Várias fontes de dados podem ser associadas ao mesmo URL base FHIR.

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

    Por exemplo, se um app cliente aceita links diretos, esse link direto pode 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 com suporte.

Criar um registro MedicalDataSource

Crie um registro para cada organização ou entidade de saúde vinculada ao seu app.

// 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 de MedicalDataSource

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

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

Recursos médicos

Um MedicalResource no 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): a 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 de recurso FHIR codificada em JSON.
  • Tipo de recurso médico (preenchido automaticamente): a categoria de recurso do usuário do recurso, mapeada para permissões do usuário.

Preparar recursos FHIR em JSON

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

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

Inserir ou atualizar registros de MedicalResource

Use UpsertMedicalResourceRequest para inserir novos registros MedicalResource ou atualizar os existentes 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 ficar, usando AllergyIntolerance como o tipo de recurso FHIR, que seria mapeado para o tipo de recurso médico de FHIR_RESOURCE_TYPE_ALLERGY_INTOLERANCE no PHR:

{
  "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 de 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)
    )
)