Gravar dados médicos

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

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

  1. Verificar a disponibilidade dos recursos
  2. Solicitar permissões de gravação
  3. Criar uma fonte de dados (MedicalDataSource)
  4. Gravar 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 app da 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, bem como 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 aos usuários. Eles precisam concedê-las ou negá-las 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 verificar se o app já tem as permissões necessárias concedidas. Caso contrário, use createRequestPermissionResultContract para solicitá-las. 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 as permissões sempre antes de usá-las e lidar com situações em que elas são perdidas.

Fontes de dados

Um MedicalDataSource no app da 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 históricos médicos armazenados na Conexão Saúde são organizados em um MedicalDataSource. Isso permite separar os históricos médicos de uma mesma pessoa que vêm de fontes diferentes, como APIs ou sistemas de saúde.

Considere o seguinte ao criar registros MedicalDataSource:

  • Se todos os registros forem da mesma origem, crie um MedicalDataSource.
  • Se os registros vierem de várias origens, você poderá criar um único MedicalDataSource se:
    • Os dados são reconciliados.
    • Todos os registros têm uma combinação exclusiva de tipo e ID de recurso FHIR. Em um MedicalDataSource, só pode haver um registro de um tipo de recurso FHIR com qualquer ID de recurso FHIR.
  • Caso contrário, para evitar IDs duplicados, crie um MedicalDataSource para cada fonte de dados.

Todos os históricos médicos precisam estar associados a um MedicalDataSource. Portanto, ele precisa ser criado antes de gravar os recursos.

Propriedades de MedicalDataSource:

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

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

    Por exemplo, se um app cliente for compatível com links diretos, esse link poderá ser usado como o URI de base do FHIR. O tamanho máximo do URI é de 2.000 caracteres.

  • Nome do pacote (preenchido automaticamente): o app que está gravando os dados.

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

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 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 da 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 aceita.
  • 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, que é mapeada para as permissões voltadas ao usuário.

Preparar recursos FHIR em JSON

Antes de gravar recursos médicos na Conexão Saúde, prepare os registros de recursos FHIR em JSON. Armazene cada JSON em uma variável própria para inserção 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 de MedicalResource

Use UpsertMedicalResourceRequest para inserir novos registros MedicalResource ou atualizar os atuais para 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)
    )
)