1. לפני שמתחילים
מה תפַתחו
ב-Codelab הזה בונים אפליקציה ל-Android באמצעות ספריית המנוע של FHIR. האפליקציה שלך תשתמש בספריית FHIR Engine כדי להוריד משאבי FHIR משרת FHIR ולהעלות את השינויים המקומיים לשרת.
מה תלמדו
- איך יוצרים שרת HAPI FHIR מקומי באמצעות Docker
- איך לשלב את FHIR Engine Library באפליקציה ל-Android
- איך להשתמש ב-Sync API כדי להגדיר משימה חד-פעמית או תקופתית כדי להוריד ולהעלות משאבי FHIR
- איך משתמשים ב-Search API
- איך משתמשים בממשקי Data Access API כדי ליצור, לקרוא, לעדכן ולמחוק משאבי FHIR באופן מקומי
למה תזדקק?
- Docker (get Docker)
- גרסה עדכנית של Android Studio (גרסה 4.1.2 ואילך)
- Android Emulator או מכשיר Android פיזי עם Android 7.0 Nougat ואילך
- הקוד לדוגמה
- ידע בסיסי בפיתוח Android ב-Kotlin
אם עוד לא יצרתם אפליקציות ל-Android, תוכלו להתחיל בפיתוח האפליקציה הראשונה שלכם.
2. הגדרה של שרת HAPI FHIR מקומי עם נתוני בדיקה
HAPI FHIR הוא שרת FHIR פופולרי בקוד פתוח. אנחנו משתמשים בשרת HAPI FHIR מקומי ב-Codelab שלנו כדי שהאפליקציה ל-Android תוכל להתחבר אליו.
הגדרה של שרת HAPI FHIR המקומי
- צריך להריץ את הפקודה הבאה בטרמינל כדי לקבל את התמונה העדכנית ביותר של HAPI FHIR
docker pull hapiproject/hapi:latest
- יוצרים קונטיינר HAPI FHIR באמצעות Docker Desktop כדי להריץ את קובץ האימג' שהורד קודם לכן
hapiproject/hapi
, או באמצעות הפקודה הבאה
למידע נוסףdocker run -p 8080:8080 hapiproject/hapi:latest
- כדי לבדוק את השרת, פותחים את כתובת ה-URL
http://localhost:8080/
בדפדפן. אתם אמורים לראות את ממשק האינטרנט HAPI FHIR.
אכלוס את נתוני הבדיקה בשרת HAPI FHIR המקומי
כדי לבדוק את האפליקציה שלנו, נזדקק לנתוני בדיקה בשרת. נשתמש בנתונים סינתטיים שנוצרו על ידי Synthea.
- תחילה עלינו להוריד נתונים לדוגמה מ-synthea-Sample. מורידים ומחלצים את
synthea_sample_data_fhir_r4_sep2019.zip
. נתוני הדגימה לאחר חילוץ מכילים מספר קבצים של.json
, שכל אחד מהם הוא חבילת עסקאות למטופל בודד. - אנחנו נעלה את נתוני הבדיקה של שלושה מטופלים לשרת HAPI FHIR המקומי. מריצים את הפקודה הבאה בספרייה שמכילה את קובצי JSON
curl -X POST -H "Content-Type: application/json" -d @./Aaron697_Brekke496_2fa15bc7-8866-461a-9000-f739e425860a.json http://localhost:8080/fhir/ curl -X POST -H "Content-Type: application/json" -d @./Aaron697_Stiedemann542_41166989-975d-4d17-b9de-17f94cb3eec1.json http://localhost:8080/fhir/ curl -X POST -H "Content-Type: application/json" -d @./Abby752_Kuvalis369_2b083021-e93f-4991-bf49-fd4f20060ef8.json http://localhost:8080/fhir/
- כדי להעלות לשרת את נתוני הבדיקות של כל המטופלים, יש להריץ את הפקודה
עם זאת, התהליך עשוי להימשך זמן רב והוא לא הכרחי ב-Codelab.for f in *.json; do curl -X POST -H "Content-Type: application/json" -d @$f http://localhost:8080/fhir/ ; done
- כדי לוודא שנתוני הבדיקה זמינים בשרת, פותחים את כתובת ה-URL
http://localhost:8080/fhir/Patient/
בדפדפן. אתם אמורים לראות את הטקסטHTTP 200 OK
ואת הקטעResponse Body
בדף שמכילים נתוני מטופלים בחבילת FHIR כתוצאת החיפוש עם ספירה שלtotal
.
3. הגדרת האפליקציה ל-Android
הורדת הקוד
כדי להוריד את הקוד של ה-Codelab הזה, צריך לשכפל את מאגר ה-Android FHIR SDK: git clone https://github.com/google/android-fhir.git
הפרויקט לתחילת הפעולה ב-Codelab הזה נמצא ב-codelabs/engine
.
ייבוא האפליקציה ל-Android Studio
כדי להתחיל, נייבא את האפליקציה לתחילת הפעולה אל Android Studio.
פותחים את Android Studio, בוחרים באפשרות ייבוא פרויקט (Gradle, Eclipse ADT וכו') ובוחרים את התיקייה codelabs/engine/
מקוד המקור שהורדתם קודם.
סנכרון הפרויקט עם קובצי Gradle
לנוחותך, כבר נוספו לפרויקט יחסי התלות של ספריית FHIR Engine. כך ניתן לשלב את ספריית המנוע של FHIR באפליקציה שלך. בודקים את השורות הבאות בסוף הקובץ app/build.gradle.kts
של הפרויקט:
dependencies {
// ...
implementation("com.google.android.fhir:engine:0.1.0-beta05")
}
כדי לוודא שכל יחסי התלות זמינים לאפליקציה שלכם, צריך לסנכרן את הפרויקט עם קובצי GRid בשלב הזה.
בסרגל הכלים של Android Studio, בוחרים באפשרות Sync Project with Gradle Files (). צריך גם להריץ את האפליקציה שוב כדי לבדוק שיחסי התלות פועלים כראוי.
הפעלת האפליקציה לתחילת פעולה
אחרי שייבאת את הפרויקט אל Android Studio, אפשר להפעיל את האפליקציה בפעם הראשונה.
מפעילים את האמולטור של Android Studio ולוחצים על 'הפעלה' () בסרגל הכלים של Android Studio.
4. יצירת מכונת FHIR Engine
כדי לשלב את FHIR Engine באפליקציה ל-Android, צריך להשתמש בספריית FHIR Engine וליצור מכונה של FHIR Engine. השלבים המפורטים בהמשך ינחו אותך לאורך התהליך.
- עוברים למחלקה של האפליקציה, שבדוגמה הזו היא
FhirApplication.kt
, שנמצאת ב-app/src/main/java/com/google/android/fhir/codelabs/engine
. - בתוך method
onCreate()
, מוסיפים את הקוד הבא כדי לאתחל את FHIR Engine:
הערות:FhirEngineProvider.init( FhirEngineConfiguration( enableEncryptionIfSupported = true, RECREATE_AT_OPEN, ServerConfiguration( baseUrl = "http://10.0.2.2:8080/fhir/", httpLogger = HttpLogger( HttpLogger.Configuration( if (BuildConfig.DEBUG) HttpLogger.Level.BODY else HttpLogger.Level.BASIC, ), ) { Log.d("App-HttpLog", it) }, ), ), )
enableEncryptionIfSupported
: הפעלה של הצפנת נתונים אם המכשיר תומך בה.RECREATE_AT_OPEN
: קובע את אסטרטגיית השגיאות של מסד הנתונים. במקרה הזה, הוא יוצר מחדש את מסד הנתונים אם מתרחשת שגיאה בעת הפתיחה.baseUrl
ב-ServerConfiguration
: זו כתובת ה-URL הבסיסית של שרת ה-FHIR. כתובת ה-IP שסופקה,10.0.2.2
, שמורה במיוחד ל-localhost, וניתן לגשת אליה מהאמולטור של Android. מידע נוסף.
- בכיתה
FhirApplication
, מוסיפים את השורה הבאה כדי ליצור באופן מדורג את מנוע FHIR:
זה מבטיח שמכונת FhirEngine תיווצר רק כשניגשים אליה בפעם הראשונה, ולא מיד כשהאפליקציה מופעלת.private val fhirEngine: FhirEngine by lazy { FhirEngineProvider.getInstance(this) }
- אפשר להוסיף את שיטת הנוחות הבאה במחלקה
FhirApplication
כדי לגשת בקלות לכל האפליקציות:
השיטה הסטטית הזו מאפשרת לאחזר את המכונה של FHIR Engine מכל מקום באפליקציה בעזרת ההקשר.companion object { fun fhirEngine(context: Context) = (context.applicationContext as FhirApplication).fhirEngine }
5. סנכרון נתונים עם שרת FHIR
- יצירת כיתה חדשה
DownloadWorkManagerImpl.kt
. בכיתה הזו צריך להגדיר איך האפליקציה מאחזרת את המשאב הבא מהרשימה לצורך הורדה:
לכיתה הזו יש תור של סוגי משאבים שהיא רוצה להוריד. המערכת מעבדת תשובות ושולפת את המשאבים מהחבילה שמוחזרת, שנשמרת במסד הנתונים המקומי.class DownloadWorkManagerImpl : DownloadWorkManager { private val urls = LinkedList(listOf("Patient")) override suspend fun getNextRequest(): DownloadRequest? { val url = urls.poll() ?: return null return DownloadRequest.of(url) } override suspend fun getSummaryRequestUrls() = mapOf<ResourceType, String>() override suspend fun processResponse(response: Resource): Collection<Resource> { var bundleCollection: Collection<Resource> = mutableListOf() if (response is Bundle && response.type == Bundle.BundleType.SEARCHSET) { bundleCollection = response.entry.map { it.resource } } return bundleCollection } }
- יצירת כיתה חדשה
AppFhirSyncWorker.kt
הכיתה הזו קובעת איך האפליקציה תסתנכרן עם שרת FHIR המרוחק באמצעות worker ברקע.
כאן הגדרנו באיזה מנהל הורדות, מפענח התנגשויות ומופע של מנוע FHIR שישמשו לסנכרון.class AppFhirSyncWorker(appContext: Context, workerParams: WorkerParameters) : FhirSyncWorker(appContext, workerParams) { override fun getDownloadWorkManager() = DownloadWorkManagerImpl() override fun getConflictResolver() = AcceptLocalConflictResolver override fun getFhirEngine() = FhirApplication.fhirEngine(applicationContext) }
- ב-ViewModel,
PatientListViewModel.kt
, תגדיר מנגנון סנכרון חד-פעמי. מאתרים את הקוד הבא ומוסיפים אותו לפונקציהtriggerOneTimeSync()
:
הקואוטין הזו מפעילה סנכרון חד-פעמי עם שרת FHIR באמצעות AppFhirSyncWorker שהגדרנו קודם. לאחר מכן המערכת תעדכן את ממשק המשתמש בהתאם למצב של תהליך הסנכרון.viewModelScope.launch { Sync.oneTimeSync<AppFhirSyncWorker>(getApplication()) .shareIn(this, SharingStarted.Eagerly, 10) .collect { _pollState.emit(it) } }
- בקובץ
PatientListFragment.kt
, מעדכנים את גוף הפונקציהhandleSyncJobStatus
:
כאן, כשתהליך הסנכרון יסתיים, תוצג למשתמש הודעה על כך, והאפליקציה תציג את כל המטופלים על ידי הפעלת חיפוש עם שם ריק.when (syncJobStatus) { is SyncJobStatus.Finished -> { Toast.makeText(requireContext(), "Sync Finished", Toast.LENGTH_SHORT).show() viewModel.searchPatientsByName("") } else -> {} }
עכשיו, אחרי שהכול מוכן, אפשר להפעיל את האפליקציה. לוחצים על הלחצן Sync
בתפריט. אם הכול פועל באופן תקין, אתם אמורים לראות הורדה והצגה של המטופלים משרת ה-FHIR המקומי באפליקציה.
6. שינוי והעלאה של נתוני מטופלים
בקטע הזה נדריך אתכם בתהליך השינוי של נתוני המטופלים על סמך קריטריונים ספציפיים והעלאת הנתונים המעודכנים לשרת ה-FHIR שלכם. באופן ספציפי, נחליף את ערים הכתובות למטופלים שמתגוררים בWakefield
ובTaunton
.
שלב 1: מגדירים את לוגיקת השינוי ב-PatientListViewModel
הקוד בקטע הזה יתווסף לפונקציה triggerUpdate
בפונקציה PatientListViewModel
- גישה למנוע FHIR:בתור התחלה, מקבלים הפניה למנוע FHIR ב
PatientListViewModel.kt
.
הקוד הזה מפעיל קורוטין בתוך ההיקף של ViewModel ומאתחל את מנוע FHIR.viewModelScope.launch { val fhirEngine = FhirApplication.fhirEngine(getApplication())
- חיפוש מטופלים מווייקפילד:אפשר להשתמש במנוע FHIR כדי לחפש מטופלים שהכתובת שלהם היא
Wakefield
.
כאן אנחנו משתמשים בשיטהval patientsFromWakefield = fhirEngine.search<Patient> { filter( Patient.ADDRESS_CITY, { modifier = StringFilterModifier.MATCHES_EXACTLY value = "Wakefield" } ) }
search
של מנוע ה-FHIR כדי לסנן מטופלים לפי העיר בכתובת שלהם. התוצאה תהיה רשימה של מטופלים מווייקפילד. - חיפוש מטופלים של טאונטון:באופן דומה, צריך לחפש מטופלים שהכתובת שלהם היא
Taunton
.
עכשיו יש לנו שתי רשימות של מטופלים: אחת מוויקפילד והשנייה טאונטון.val patientsFromTaunton = fhirEngine.search<Patient> { filter( Patient.ADDRESS_CITY, { modifier = StringFilterModifier.MATCHES_EXACTLY value = "Taunton" } ) }
- שינוי הכתובות של מטופלים:עוברים על כל מטופלים ברשימה
patientsFromWakefield
, משנים את עיר המגורים שלהם ל-Taunton
ומעדכנים אותם במנוע FHIR.
באופן דומה, צריך לעדכן כל מטופלים ברשימהpatientsFromWakefield.forEach { it.resource.address.first().city = "Taunton" fhirEngine.update(it.resource) }
patientsFromTaunton
לשינוי העיר לWakefield
.patientsFromTaunton.forEach { it.resource.address.first().city = "Wakefield" fhirEngine.update(it.resource) }
- הפעלת הסנכרון:אחרי שמשנים את הנתונים באופן מקומי, מפעילים סנכרון חד-פעמי כדי לוודא שהנתונים מתעדכנים בשרת ה-FHIR.
התו הסוגרtriggerOneTimeSync() }
}
מציין שהסתיים ה"קורוטין" שהתחיל בהתחלה.
שלב 2: בדיקת הפונקציונליות
- בדיקת ממשק משתמש:הפעלת האפליקציה. לוחצים על הלחצן
Update
בתפריט. אמורה להופיע החלפת ערים בכתובות של המטופליםAaron697
ו-Abby752
. - אימות השרת:פותחים דפדפן ומנווטים אל
http://localhost:8080/fhir/Patient/
. צריך לוודא שעיר הכתובת של המטופליםAaron697
ו-Abby752
מעודכנת בשרת ה-FHIR המקומי.
בעזרת השלבים הבאים הטמעתם בהצלחה מנגנון לשינוי נתוני המטופלים ולסנכרון השינויים עם שרת ה-FHIR.
7. חיפוש מטופלים לפי שם
חיפוש מטופלים לפי שמות שלהם יכול לספק דרך ידידותית למשתמש לאחזר מידע. כאן נדריך אותך בתהליך ההטמעה של התכונה הזו באפליקציה.
שלב 1: עדכון חתימת הפונקציה
עוברים לקובץ PatientListViewModel.kt
ומוצאים את הפונקציה searchPatientsByName
. אנחנו נוסיף קוד לפונקציה הזו.
כדי לסנן את התוצאות על סמך שאילתת השם שסופקה ולהוציא את התוצאות לצורך עדכון של ממשק המשתמש, צריך לשלב את בלוק הקוד המותנה הבא:
viewModelScope.launch {
val fhirEngine = FhirApplication.fhirEngine(getApplication())
if (nameQuery.isNotEmpty()) {
val searchResult = fhirEngine.search<Patient> {
filter(
Patient.NAME,
{
modifier = StringFilterModifier.CONTAINS
value = nameQuery
},
)
}
liveSearchedPatients.value = searchResult.map { it.resource }
}
}
כאן, אם השדה nameQuery
לא ריק, פונקציית החיפוש תסנן את התוצאות כך שיכללו רק מטופלים שהשמות שלהם מכילים את השאילתה שצוינה.
שלב 2: בודקים את פונקציונליות החיפוש החדשה
- להפעיל מחדש את האפליקציה:אחרי שמבצעים את השינויים האלה, צריך לבנות מחדש את האפליקציה ולהפעיל אותה.
- חיפוש מטופלים: במסך של רשימת המטופלים, משתמשים בפונקציית החיפוש. עכשיו אמורה להיות אפשרות להזין שם (או חלק משם) כדי לסנן את רשימת המטופלים בהתאם.
בעקבות השלמת השלבים האלה, שיפרת את האפליקציה בכך שהיא מאפשרת למשתמשים לחפש ביעילות מטופלים לפי שמותיהם. זה יכול לשפר משמעותית את חוויית המשתמש ואת היעילות באחזור הנתונים.
8. מעולה!
השתמשת בספריית המנוע של FHIR כדי לנהל משאבי FHIR באפליקציה שלך:
- שימוש ב-Sync API לסנכרון משאבי FHIR עם שרת FHIR
- אפשר להשתמש ב-Data Access API כדי ליצור, לקרוא, לעדכן ולמחוק משאבי FHIR מקומיים
- שימוש ב-Search API לחיפוש משאבי FHIR מקומיים
הנושאים שטיפלנו בהם
- איך להגדיר שרת HAPI FHIR מקומי
- איך להעלות את נתוני הבדיקה לשרת HAPI FHIR המקומי
- איך בונים אפליקציה ל-Android באמצעות ספריית המנוע של FHIR
- איך להשתמש ב-Sync API, ב-Data Access API וב-Search API בספריית המנוע של FHIR
השלבים הבאים
- מסמכי התיעוד של ספריית המנוע של FHIR
- כדאי להכיר את התכונות המתקדמות של Search API
- החלת ספריית FHIR Engine באפליקציה שלכם ל-Android