כתיבת נתונים רפואיים

המדריך הזה תואם לגרסה 1.1.0-beta02 של Health Connect ואילך.

כדי לכתוב נתונים רפואיים באמצעות התיק הרפואי ב-Health Connect:

  1. בדיקת הזמינות של התכונה
  2. בקשת הרשאות כתיבה
  3. יצירת מקור נתונים (MedicalDataSource)
  4. כתיבת משאב רפואי (MedicalResource)

זמינות התכונה

כדי לדעת אם המכשיר של המשתמש מאפשר להשתמש בתיקים רפואיים ב-Health Connect, צריך לבדוק את הזמינות של 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 כדי לבקש את ההרשאות האלה. הפעולה הזו תציג את מסך ההרשאות של 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)
  }
}

המשתמשים יכולים לתת או לבטל הרשאות בכל שלב, ולכן האפליקציה צריכה לבדוק אם ההרשאות ניתנו בכל פעם לפני שהיא משתמשת בהן, ולטפל במקרים שבהם הרשאה כלשהי בוטלה.

מקורות נתונים

MedicalDataSource ב-Health Connect מייצג מקור נתונים שגלוי למשתמשים, כמו ארגון בריאות, בית חולים או API.

התיקים הרפואיים שמאוחסנים ב-Health Connect מאורגנים בMedicalDataSource. כך אפשר להפריד בין תיקים רפואיים של אותו אדם שמגיעים ממקורות שונים, כמו ממשקי API או מערכות בריאות.

כשיוצרים רשומות MedicalDataSource, כדאי לשים לב לנקודות הבאות:

  • אם כל הרשומות מגיעות מאותו מקור, יוצרים MedicalDataSource אחד.
  • אם הרשומות מגיעות מכמה מקורות, אתם יכולים ליצור MedicalDataSource אחד אם:
    • הנתונים מותאמים.
    • לכל הרשומות יש שילוב ייחודי של סוג משאב FHIR ומזהה משאב FHIR. בתוך MedicalDataSource, יכולה להיות רק רשומה אחת של סוג משאב FHIR עם מזהה משאב FHIR כלשהו.
  • אחרת, כדי למנוע מזהים כפולים, צריך ליצור MedicalDataSource לכל מקור נתונים.

כל התיקים הרפואיים חייבים להיות משויכים ל-MedicalDataSource, ולכן צריך ליצור אותו לפני שכותבים את המשאבים.

המאפיינים של MedicalDataSource:

  • שם לתצוגה (חובה) – השם לתצוגה של מקור הנתונים שגלוי למשתמשים, שמזוהה באופן ייחודי בכל אפליקציה לכתיבה.
  • ‫FHIR Base URI (חובה) – בנתונים שמגיעים משרת FHIR, צריך להזין את כתובת ה-URL הבסיסית של FHIR (לדוגמה, https://example.com/fhir/). אפשר לשייך כמה מקורות נתונים לאותה כתובת URL בסיסית של FHIR.

    אם הנתונים נוצרים על ידי אפליקציה ללא כתובת URL של FHIR, זה צריך להיות URI ייחודי ומובן שמוגדר על ידי האפליקציה (לדוגמה, myapp://..) שמצביע על מקור הנתונים.

    לדוגמה, אם אפליקציית לקוח תומכת בקישורי עומק, אפשר להשתמש בקישור העומק הזה בתור ה-URI הבסיסי של FHIR. האורך המקסימלי של ה-URI הוא 2,000 תווים.

  • שם החבילה (מאוכלס באופן אוטומטי) – האפליקציה שכותבת את הנתונים.

  • גרסת 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 ב-Health Connect מייצג משאב FHIR (שמכיל תיק רפואי), יחד עם מטא-נתונים.

מאפיינים של MedicalResource:

  • ‫DataSourceId (חובה) – מקור הנתונים כפי שמתואר ב-MedicalDataSource.
  • גרסת FHIR (חובה) – גרסת ה-FHIR. חייבת להיות גרסה נתמכת.
  • משאב FHIR (חובה) המופע של משאב FHIR בקידוד JSON.
  • סוג המשאב הרפואי (מאוכלס באופן אוטומטי) – הקטגוריה הגלויה למשתמשים של המשאב, שממופה להרשאות שגלויות למשתמשים.

הכנת משאבי FHIR ב-JSON

לפני שכותבים משאבים רפואיים ב-Health Connect, צריך להכין את רשומות המשאבים של 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)
    )
)