Android फ़्रेमवर्क एपीआई पर पीएचआर का इस्तेमाल शुरू करना

सेहत के निजी रिकॉर्ड (पीएचआर) के लिए Android फ़्रेमवर्क एपीआई का इस्तेमाल करने के लिए, आपको:

  1. Android Studio का इस्तेमाल करके, एनवायरमेंट कॉन्फ़िगर करना
  2. HealthConnectManager को इंस्टैंशिएट करना
  3. अनुमतियां मैनेज करना
  4. डेटा सोर्स बनाना

Android Studio का इस्तेमाल करके, एनवायरमेंट कॉन्फ़िगर करना

नए एपीआई का ऐक्सेस पाने के लिए, आपके पास काम के नए टूल का ऐक्सेस भी होना चाहिए:

  • Android Studio का नया वर्शन इंस्टॉल करें.
  • Android Studio में, टूल > SDK मैनेजर पर जाएं.
    • SDK टूल के प्लैटफ़ॉर्म टैब में, Android Baklava चुनें.
    • इस वर्शन में एपीआई लेवल 36 और पीएचआर एपीआई शामिल हैं.
    • SDK टूल टैब में, उपलब्ध सबसे नया Android SDK Build-Tools चुनें.
    • SDK टूल इंस्टॉल करने के लिए, 'ठीक है' पर क्लिक करें.
  • Android Gradle प्लग इन के सबसे नए वर्शन का इस्तेमाल करें.

एपीआई लेवल की जानकारी देना

पीएचआर एपीआई को ऐक्सेस करने के लिए, आपको Android के सही वर्शन को टारगेट करना होगा. ऐसा करने के लिए, app/build.gradle में एपीआई लेवल की जानकारी दें.

...
compileSdk = 36

defaultConfig {
  targetSdk = 36
...

uses-sdk-element और Android 16 SDK टूल सेट अप करना दस्तावेज़ में, एपीआई लेवल कॉन्फ़िगर करने के बारे में ज़्यादा जानें.

अनुमतियों का एलान करना

AndroidManifest.xml में, पीएचआर से जुड़ी नई अनुमतियां जोड़ें. सिर्फ़ उन डेटा टाइप के लिए अनुमतियां दें जिनका इस्तेमाल आपको अपने ऐप्लिकेशन में करना है. चिकित्सा से जुड़ी अनुमतियों की पूरी सूची, कोड ब्लॉक में दिखती है. Health Connect के लिए, पीएचआर से जुड़ी अनुमतियां शामिल नहीं हैं.

...
  <!--  Medical permissions -->
  <uses-permission android:name="android.permission.health.WRITE_MEDICAL_DATA"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_ALLERGIES_INTOLERANCES"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_CONDITIONS"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_IMMUNIZATIONS"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_LABORATORY_RESULTS"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_MEDICATIONS"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_PERSONAL_DETAILS"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_PRACTITIONER_DETAILS"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_PREGNANCY"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_PROCEDURES"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_SOCIAL_HISTORY"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_VISITS"/>
  <uses-permission android:name="android.permission.health.READ_MEDICAL_DATA_VITAL_SIGNS"/>
...

अगर कोई ऐप्लिकेशन किसी ऐसे एपीआई का इस्तेमाल करने की कोशिश करता है जिसके लिए अनुमति की ज़रूरत होती है और ऐप्लिकेशन के मेनिफ़ेस्ट में उस अनुमति का एलान नहीं किया गया है, तो SecurityException को दिखाया जाएगा.

SecurityException टाइप के अपवाद के लिए, exception.localizedMessage में गड़बड़ी का एक काम का मैसेज उपलब्ध होगा.

HealthConnectManager को इंस्टैंशिएट करना

HealthConnectManager वह क्लास है जो अनुमतियों के इंटरैक्शन को मैनेज करने के साथ-साथ, Health Connect के स्थानीय डेटा रिपॉज़िटरी को पढ़ती और उसमें डेटा सेव करती है. हम अगले सेक्शन में HealthConnectManager के इंस्टेंस के तरीकों के बारे में जानेंगे. HealthConnectManager, सिस्टम सेवा को एक्सपोज़ करता है. इसलिए, इस क्लास को सीधे तौर पर इंस्टैंशिएट नहीं किया जा सकता. इसके लिए, आपको getSystemService का इस्तेमाल करना होगा. खास तौर पर, ध्यान दें कि सिस्टम सेवा, उस कॉन्टेक्स्ट के साथ ज़्यादा से ज़्यादा जुड़ी होती है जिसके लिए उसे इंस्टैंशिएट किया जाता है. साथ ही, उसे उस कॉन्टेक्स्ट से बाहर ऐक्सेस नहीं किया जाना चाहिए.

import android.health.connect.HealthConnectManager
...
val healthConnectManager: HealthConnectManager = requireNotNull(applicationContext.getSystemService(HealthConnectManager::class.java))

अनुमतियां मैनेज करना

आपके ऐप्लिकेशन के उपयोगकर्ता को, ऐप्लिकेशन को Health Connect का डेटा ऐक्सेस करने की अनुमति देनी होगी. इसके लिए, बताई गई अनुमतियों के साथ एक नई गतिविधि लॉन्च करें और अनुमतियों की सूची का इस्तेमाल करें. नई गतिविधि के यूज़र इंटरफ़ेस (यूआई) की मदद से, उपयोगकर्ता उन अनुमतियों को चुन सकता है जो उसे आपके ऐप्लिकेशन को देनी हैं. सिर्फ़ उन डेटा टाइप के लिए अनुमतियों का अनुरोध करें जिनका इस्तेमाल आपके ऐप्लिकेशन को करना है.

val MEDICAL_PERMISSIONS = arrayOf(
            "android.permission.health.READ_MEDICAL_DATA_ALLERGIES_INTOLERANCES",
            "android.permission.health.READ_MEDICAL_DATA_CONDITIONS",
            "android.permission.health.READ_MEDICAL_DATA_IMMUNIZATIONS",
            "android.permission.health.READ_MEDICAL_DATA_LABORATORY_RESULTS",
            "android.permission.health.READ_MEDICAL_DATA_MEDICATIONS",
            "android.permission.health.READ_MEDICAL_DATA_PERSONAL_DETAILS",
            "android.permission.health.READ_MEDICAL_DATA_PRACTITIONER_DETAILS",
            "android.permission.health.READ_MEDICAL_DATA_PREGNANCY",
            "android.permission.health.READ_MEDICAL_DATA_PROCEDURES",
            "android.permission.health.READ_MEDICAL_DATA_SOCIAL_HISTORY",
            "android.permission.health.READ_MEDICAL_DATA_VISITS",
            "android.permission.health.READ_MEDICAL_DATA_VITAL_SIGNS",
            "android.permission.health.WRITE_MEDICAL_DATA",
        )
...
private lateinit var mRequestPermissionLauncher: ActivityResultLauncher<Array<String>>
...
mRequestPermissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
            permissionMap: Map<String, Boolean> ->
            requestPermissionResultHandler(permissionMap)
        }
}
...
private fun requestPermissionResultHandler(permissionMap: Map<String, Boolean>) {
    // Evaluate permissionMap and handle any missing permissions
}
...
mRequestPermissionLauncher.launch(MEDICAL_PERMISSIONS)

ज़रूरी अनुमति के बिना पढ़ने या लिखने की कोशिश करने पर, आपको HealthConnectException दिखेगा.

HealthConnectException टाइप के अपवाद के लिए, exception.localizedMessage में गड़बड़ी का एक काम का मैसेज उपलब्ध होगा.

डेटा सोर्स बनाना

Health Connect में स्वास्थ्य से जुड़ा डेटा डालने के लिए, आपके ऐप्लिकेशन को जानकारी सेव करने के लिए पहले एक डेटा सोर्स बनाना होगा. आम तौर पर, डेटा सोर्स किसी खास एपीआई या मेडिकल सिस्टम को दिखाता है.

उदाहरण में, हमने My Hospital नाम का डेटा सोर्स बनाया है और FHIR वर्शन तय किया है.

import android.health.connect.CreateMedicalDataSourceRequest
import android.health.connect.HealthConnectManager
import android.health.connect.datatypes.FhirVersion
import android.health.connect.datatypes.MedicalDataSource
import android.net.Uri
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.os.asOutcomeReceiver
import kotlinx.coroutines.suspendCancellableCoroutine
...
private suspend fun createMedicalDataSource(
    fhirBaseUri: Uri,
    displayName: String,
    fhirVersion: FhirVersion,
): String {
    val dataSource =
        suspendCancellableCoroutine<MedicalDataSource> { continuation ->
            healthConnectManager.createMedicalDataSource(
                CreateMedicalDataSourceRequest.Builder(fhirBaseUri,
                                                       displayName,
                                                       fhirVersion).build(),
                Runnable::run,
                continuation.asOutcomeReceiver(),
            )
        }
    Log.d("CREATE_DATA_SOURCE", "Created source: $dataSource")
    return "Created data source: $displayName"
}
...
createMedicalDataSource(
    Uri.parse("example.fhir.com/R4/123"),
    "My Hospital",
    FhirVersion.parseFhirVersion("4.0.1"),
)

रिकॉर्ड लिखना

JSON में FHIR रिकॉर्ड का उदाहरण तैयार करें. वेब पर FHIR फ़ॉर्मैट में डेटा के उदाहरण देने वाले कई सोर्स मौजूद हैं.

{
  "resourceType": "Immunization",
  "id": "immunization-1",
  "status": "completed",
  "vaccineCode": {
    "coding": [
      {
        "system": "http://hl7.org/fhir/sid/cvx",
        "code": "115"
      },
      {
        "system": "http://hl7.org/fhir/sid/ndc",
        "code": "58160-842-11"
      }
    ],
    "text": "Tdap"
  },
  "patient": {
    "reference": "Patient/patient_1",
    "display": "Example, Anne"
  },
  "encounter": {
    "reference": "Encounter/encounter_unk",
    "display": "GP Visit"
  },
  "occurrenceDateTime": "2018-05-21",
  "primarySource": true,
  "manufacturer": {
    "display": "Sanofi Pasteur"
  },
  "lotNumber": "1",
  "site": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActSite",
        "code": "LA",
        "display": "Left Arm"
      }
    ],
    "text": "Left Arm"
  },
  "route": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-RouteOfAdministration",
        "code": "IM",
        "display": "Injection, intramuscular"
      }
    ],
    "text": "Injection, intramuscular"
  },
  "doseQuantity": {
    "value": 0.5,
    "unit": "mL"
  },
  "performer": [
    {
      "function": {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/v2-0443",
            "code": "AP",
            "display": "Administering Provider"
          }
        ],
        "text": "Administering Provider"
      },
      "actor": {
        "reference": "Practitioner/practitioner_1",
        "type": "Practitioner",
        "display": "Dr Maria Hernandez"
      }
    }
  ]
}

डेटा डालें:

import android.health.connect.UpsertMedicalResourceRequest
import android.health.connect.datatypes.MedicalResource
...
private suspend fun loadJSONFromAsset(assetName: String): String {
...
private suspend fun upsertMedicalResources(
    requests: List<UpsertMedicalResourceRequest>
): List<MedicalResource> {
    Log.d("UPSERT_RESOURCES", "Writing ${requests.size} resources")
    val resources =
        suspendCancellableCoroutine<List<MedicalResource>> { continuation ->
            healthConnectManager.upsertMedicalResources(
                requests,
                Runnable::run,
                continuation.asOutcomeReceiver(),
            )
        }
    Log.d("UPSERT_RESOURCES", "Wrote ${resources.size} resources")
    return resources
}
...
private suspend fun insertResource(insertedDataSourceId: String, resource: String): String {
    val insertedResources =
        upsertMedicalResources(
            listOf(
                UpsertMedicalResourceRequest.Builder(
                        insertedDataSourceId,
                        FhirVersion.parseFhirVersion("4.0.1"),
                        resource,
                    )
                    .build()
            )
        )
    return insertedResources.joinToString(
        separator = "\n",
        transform = MedicalResource::toString,
    )
}
...
val immunizationResource =
    loadJSONFromAsset("immunization_1.json")
insertResource(dataSource.id, immunizationResource)

upsertMedicalResources, आर्ग्युमेंट के तौर पर UpsertMedicalResourceRequest की सूची लेता है. अगर कॉल में पास किए गए किसी UpsertMedicalResourceRequest को डालने में समस्या आती है, तो UpsertMedicalResourceRequest की पूरी सूची को रिपॉज़िटरी में डाला नहीं जाएगा.

अगर किसी अनुरोध में अमान्य MedicalDataSource आईडी शामिल हैं, तो एपीआई एक IllegalArgumentException दिखाएगा. अगर किसी और वजह से कोई अनुरोध अमान्य माना जाता है, तो कॉल करने वाले को HealthConnectException मिलेगा.

किसी खास अनुरोध के लिए यूनीक कुंजी, डेटा सोर्स आईडी, FHIR रिसॉर्स टाइप, और FHIR रिसॉर्स आईडी का कॉम्बिनेशन होती है. अगर किसी अनुरोध में ये तीन आइटम, किसी मौजूदा रिकॉर्ड से मैच करते हैं, तो अपडेट ट्रिगर हो जाता है. ऐसा न होने पर, एक नया रिकॉर्ड बन जाता है.

रिकॉर्ड पढ़ना

रिकॉर्ड को टाइप के हिसाब से पढ़ें. इसके बाद, अपने हिसाब से नतीजों को मैनेज करें.

import android.health.connect.ReadMedicalResourcesInitialRequest
import android.health.connect.ReadMedicalResourcesResponse
import android.health.connect.datatypes.MedicalResource.MEDICAL_RESOURCE_TYPE_IMMUNIZATIONS
...
private suspend fun readImmunization(): List<MedicalResource> {

    var receiver: OutcomeReceiver<ReadMedicalResourcesResponse, HealthConnectException>
    val request: ReadMedicalResourcesInitialRequest =
        ReadMedicalResourcesInitialRequest.Builder(MEDICAL_RESOURCE_TYPE_IMMUNIZATIONS).build()
    val resources =
        suspendCancellableCoroutine<ReadMedicalResourcesResponse> { continuation ->
                receiver = continuation.asOutcomeReceiver()
                healthConnectManager.readMedicalResources(request, Runnable::run, receiver)
            }
            .medicalResources
    Log.d("READ_MEDICAL_RESOURCES", "Read ${resources.size} resources")
    return resources
}