Cómo escribir datos médicos

Esta guía es compatible con la versión 1.1.0-beta02 o posterior de Health Connect.

Para escribir datos médicos con las historias clínicas de Health Connect, sigue estos pasos:

  1. Cómo comprobar la disponibilidad de las funciones
  2. Solicita permisos de escritura
  3. Crea una fuente de datos (MedicalDataSource)
  4. Escribe un recurso médico (MedicalResource)

Disponibilidad de funciones

Para determinar si el dispositivo de un usuario admite las historias clínicas en Health Connect, verifica la disponibilidad de FEATURE_PERSONAL_HEALTH_RECORD en el cliente:

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

  // Feature is available
} else {
  // Feature isn't available
}
Consulta Cómo verificar la disponibilidad de funciones para obtener más información.

Permisos necesarios

La escritura de datos médicos está protegida por el siguiente permiso:

  • android.permission.health.WRITE_MEDICAL_DATA

Declara estos permisos en Play Console para tu app, así como en el manifiesto de la app:

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

Eres responsable de declarar todos los permisos adecuados que quieras usar en tus dispositivos y apps. También debes verificar que el usuario haya otorgado cada permiso antes de usarlo.

Solicita permisos al usuario

Después de crear una instancia de cliente, tu app debe solicitarle permisos al usuario. Los usuarios deben poder otorgar o rechazar permisos en cualquier momento.

Para hacerlo, crea un conjunto de permisos para los tipos de datos necesarios. Primero, asegúrate de que los permisos del conjunto se declaren en tu manifiesto de 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
)

Usa getGrantedPermissions para ver si tu app ya tiene otorgados los permisos necesarios. De lo contrario, usa createRequestPermissionResultContract para solicitarlos. Se mostrará la pantalla de permisos de Health Connect.

// 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 los usuarios pueden otorgar o revocar permisos en cualquier momento, tu app debe verificar los permisos cada vez que los use y controlar las situaciones en las que se pierda el permiso.

Fuentes de datos

Un MedicalDataSource en Health Connect representa una fuente de datos para el usuario, como una organización de atención médica, un hospital o una API.

Las historias clínicas almacenadas en Health Connect se organizan en un MedicalDataSource. Esto permite separar las historias clínicas de una misma persona que provienen de diferentes fuentes, como APIs o sistemas de atención médica.

Ten en cuenta lo siguiente cuando crees registros MedicalDataSource:

  • Si todos los registros se originan en la misma fuente, crea un MedicalDataSource.
  • Si los registros se originan en varias fuentes, puedes crear un solo MedicalDataSource si se cumplen las siguientes condiciones:
    • Se concilian los datos.
    • Todos los registros tienen una combinación única de tipo de recurso de FHIR y de ID de recurso de FHIR. Dentro de un MedicalDataSource, solo puede haber un registro de un tipo de recurso de FHIR con cualquier ID de recurso de FHIR.
  • De lo contrario, para evitar IDs duplicados, crea un MedicalDataSource para cada fuente de datos.

Todas las historias clínicas deben estar asociadas a un MedicalDataSource, por lo que este debe crearse antes de escribir los recursos.

Propiedades de MedicalDataSource:

  • Nombre visible (obligatorio): Es el nombre visible para el usuario de la fuente de datos, que se identifica de forma única por app de escritura.
  • URI base de FHIR (obligatorio): Para los datos que provienen de un servidor de FHIR, debe ser la URL base de FHIR (por ejemplo, https://example.com/fhir/). Se pueden asociar varias fuentes de datos con la misma URL base de FHIR.

    Si los datos los genera una app sin una URL de FHIR, este debe ser un URI único y comprensible definido por la app (por ejemplo, myapp://..) que apunte a la fuente de los datos.

    Por ejemplo, si una app cliente admite la vinculación directa, este vínculo directo se podría usar como el URI base de FHIR. La longitud máxima del URI es de 2,000 caracteres.

  • Nombre del paquete (se completa automáticamente): Es la app que escribe los datos.

  • Versión de FHIR (obligatorio): Es la versión de FHIR. Debe ser una versión compatible.

Cómo crear un registro de MedicalDataSource

Crea un registro para cada organización o entidad de atención médica a la que esté vinculada tu 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)
        )
    )

Borra un registro de MedicalDataSource

En el ejemplo anterior, el sistema devuelve un id en el momento de la creación. Si necesitas borrar el registro MedicalDataSource, haz referencia a ese mismo id:

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

Recursos médicos

Un MedicalResource en Health Connect representa un recurso de FHIR (que contiene una historia clínica), junto con metadatos.

Propiedades de MedicalResource:

  • DataSourceId (obligatorio): Es la fuente de datos como se describe para un MedicalDataSource.
  • Versión de FHIR (obligatorio): Es la versión de FHIR. Debe ser una versión compatible.
  • Recurso de FHIR (obligatorio): Es la instancia del recurso de FHIR codificada en JSON.
  • Tipo de recurso médico (se completa automáticamente): Es la categoría para el usuario del recurso, que se asigna a los permisos para el usuario.

Prepara recursos de FHIR en JSON

Antes de escribir recursos médicos en Health Connect, prepara tus registros de recursos de FHIR en JSON. Almacena cada JSON en su propia variable para insertarlo como un recurso médico.

Si necesitas ayuda con el formato JSON de FHIR, consulta los datos de ejemplo que proporciona la organización HL7.

Inserta o actualiza registros de MedicalResource

Usa UpsertMedicalResourceRequest para insertar registros nuevos o actualizar los existentes de MedicalResource para un 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
            )
        )
    )

Ejemplo de recurso de FHIR

En el ejemplo anterior, la variable medicationJsonToInsert representaba una cadena JSON de FHIR válida.

Este es un ejemplo de cómo se vería ese JSON, con AllergyIntolerance como el tipo de recurso de FHIR, que se asignaría al tipo de recurso médico de FHIR_RESOURCE_TYPE_ALLERGY_INTOLERANCE en las historias clínicas:

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

Borra un registro de MedicalResource

Es posible que se borren MedicalResource registros 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
        )
    }
)

O bien, medicalResourceType puede borrarlos de la siguiente manera:

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