1. Hinweis
Aufgaben
In diesem Codelab erstellen Sie eine Android-App mit der FHIR-Engine-Bibliothek. Ihre Anwendung verwendet die FHIR-Engine-Bibliothek, um FHIR-Ressourcen von einem FHIR-Server herunterzuladen und alle lokalen Änderungen auf den Server hochzuladen.
Lerninhalte
- Lokalen HAPI-FHIR-Server mit Docker erstellen
- So integrieren Sie die FHIR-Engine-Bibliothek in Ihre Android-Anwendung
- Mit der Sync API einen einmaligen oder regelmäßigen Job zum Herunterladen und Hochladen von FHIR-Ressourcen einrichten
- So verwenden Sie die Search API
- Wie Sie die Data Access APIs verwenden, um FHIR-Ressourcen lokal zu erstellen, zu lesen, zu aktualisieren und zu löschen
Voraussetzungen
- Docker (Docker abrufen)
- Eine aktuelle Version von Android Studio (ab Version 4.1.2)
- Android-Emulator oder ein physisches Android-Gerät mit Android 7.0 Nougat oder höher
- Der Beispielcode
- Grundkenntnisse der Android-Entwicklung in Kotlin
Wenn Sie noch keine Android-Apps entwickelt haben, können Sie damit beginnen, Ihre erste App zu erstellen.
2. Lokalen HAPI-FHIR-Server mit Testdaten einrichten
HAPI FHIR ist ein beliebter Open-Source-FHIR-Server. Wir verwenden in unserem Codelab einen lokalen HAPI-FHIR-Server, zu dem die Android-App eine Verbindung herstellen kann.
Lokalen HAPI-FHIR-Server einrichten
- Führen Sie den folgenden Befehl in einem Terminal aus, um das neueste Image von HAPI FHIR abzurufen
docker pull hapiproject/hapi:latest
- Erstellen Sie einen HAPI-FHIR-Container. Verwenden Sie dazu entweder Docker Desktop, um das zuvor heruntergeladene Image
hapiproject/hapi
auszuführen, oder führen Sie den folgenden Befehl aus:
Weitere Informationendocker run -p 8080:8080 hapiproject/hapi:latest
- Prüfen Sie den Server, indem Sie die URL
http://localhost:8080/
in einem Browser öffnen. Sie sollten die HAPI FHIR-Weboberfläche sehen.
Lokalen HAPI-FHIR-Server mit Testdaten füllen
Zum Testen unserer Anwendung benötigen wir einige Testdaten auf dem Server. Wir verwenden synthetische Daten, die von Synthea generiert wurden.
- Zuerst müssen wir Beispieldaten von synthea-sample herunterladen. Laden Sie
synthea_sample_data_fhir_r4_sep2019.zip
herunter und extrahieren Sie es. Die entpackten Beispieldaten enthalten zahlreiche.json
-Dateien, von denen jede ein Transaktions-Bundle für einen einzelnen Patienten ist. - Wir laden Testdaten für drei Patienten auf den lokalen HAPI FHIR-Server hoch. Führen Sie den folgenden Befehl in dem Verzeichnis aus, das die JSON-Dateien enthält:
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/
- Führen Sie
aus, um Testdaten für alle Patienten auf den Server hochzuladen. Das kann jedoch lange dauern und ist für das Codelab nicht erforderlich.for f in *.json; do curl -X POST -H "Content-Type: application/json" -d @$f http://localhost:8080/fhir/ ; done
- Prüfen Sie, ob die Testdaten auf dem Server verfügbar sind, indem Sie die URL
http://localhost:8080/fhir/Patient/
in einem Browser öffnen. Der TextHTTP 200 OK
und der AbschnittResponse Body
der Seite mit Patientendaten in einem FHIR-Bundle sollten als Suchergebnis mit einer Anzahl vontotal
angezeigt werden.
3. Android-App einrichten
Code herunterladen
Klonen Sie das Android FHIR SDK-Repository, um den Code für dieses Codelab herunterzuladen: git clone https://github.com/google/android-fhir.git
Das Startprojekt für dieses Codelab befindet sich in codelabs/engine
.
App in Android Studio importieren
Zunächst importieren wir die Starter-App in Android Studio.
Öffnen Sie Android Studio, wählen Sie Projekt importieren (Gradle, Eclipse ADT usw.) und dann den Ordner codelabs/engine/
aus dem Quellcode aus, den Sie zuvor heruntergeladen haben.
Projekt mit Gradle-Dateien synchronisieren
Die Abhängigkeiten der FHIR-Engine-Bibliothek wurden dem Projekt bereits hinzugefügt. Auf diese Weise können Sie die FHIR-Engine-Bibliothek in Ihre Anwendung integrieren. Sehen Sie sich die folgenden Zeilen am Ende der Datei app/build.gradle.kts
Ihres Projekts an:
dependencies {
// ...
implementation("com.google.android.fhir:engine:0.1.0-beta05")
}
Damit alle Abhängigkeiten für Ihre App verfügbar sind, sollten Sie Ihr Projekt jetzt mit Gradle-Dateien synchronisieren.
Wählen Sie in der Android Studio-Symbolleiste Sync Project with Gradle Files () aus. Außerdem führen Sie die Anwendung noch einmal aus, um zu prüfen, ob die Abhängigkeiten korrekt funktionieren.
Start-App ausführen
Nachdem Sie das Projekt in Android Studio importiert haben, können Sie die App zum ersten Mal ausführen.
Starten Sie den Android Studio-Emulator und klicken Sie in der Android Studio-Symbolleiste auf Run ().
4. FHIR-Engine-Instanz erstellen
Um die FHIR-Engine in Ihre Android-App einzubinden, müssen Sie die FHIR-Engine-Bibliothek verwenden und eine Instanz der FHIR-Engine initiieren. Die unten beschriebenen Schritte führen Sie durch den Prozess.
- Rufen Sie Ihre Anwendungsklasse auf, in diesem Beispiel
FhirApplication.kt
. Sie befindet sich inapp/src/main/java/com/google/android/fhir/codelabs/engine
. - Fügen Sie in der Methode
onCreate()
den folgenden Code hinzu, um die FHIR-Engine zu initialisieren:
Hinweise: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
: Aktiviert die Datenverschlüsselung, sofern das Gerät dies unterstützt.RECREATE_AT_OPEN
: Bestimmt die Datenbankfehlerstrategie. In diesem Fall wird die Datenbank neu erstellt, wenn beim Öffnen ein Fehler auftritt.baseUrl
inServerConfiguration
: Dies ist die Basis-URL des FHIR-Servers. Die angegebene IP-Adresse10.0.2.2
ist speziell für localhost reserviert und kann über den Android-Emulator aufgerufen werden. Weitere Informationen
- Fügen Sie in der Klasse
FhirApplication
die folgende Zeile hinzu, um die FHIR-Engine verzögert zu instanziieren:
Dadurch wird sichergestellt, dass die FhirEngine-Instanz nur erstellt wird, wenn zum ersten Mal darauf zugegriffen wird, und nicht sofort beim Start der Anwendung.private val fhirEngine: FhirEngine by lazy { FhirEngineProvider.getInstance(this) }
- Fügen Sie der
FhirApplication
-Klasse die folgende praktische Methode hinzu, um in der gesamten Anwendung leichter darauf zugreifen zu können:
Mit dieser statischen Methode können Sie die FHIR Engine-Instanz mithilfe des Kontexts von jeder beliebigen Stelle in der Anwendung abrufen.companion object { fun fhirEngine(context: Context) = (context.applicationContext as FhirApplication).fhirEngine }
5. Daten mit FHIR-Server synchronisieren
- Erstelle einen neuen
DownloadWorkManagerImpl.kt
-Kurs. In dieser Klasse definieren Sie, wie die Anwendung die nächste Ressource aus der Liste zum Herunterladen abruft:
Diese Klasse hat eine Warteschlange mit Ressourcentypen, die heruntergeladen werden soll. Er verarbeitet Antworten und extrahiert die Ressourcen aus dem zurückgegebenen Bundle, das in der lokalen Datenbank gespeichert wird.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 } }
- Neue Klasse erstellen
AppFhirSyncWorker.kt
Diese Klasse definiert, wie die App mithilfe eines Hintergrund-Workers mit dem Remote-FHIR-Server synchronisiert wird.
Hier haben wir definiert, welcher Download-Manager, welcher Konfliktlöser und welche FHIR-Engine-Instanz für die Synchronisierung verwendet werden sollen.class AppFhirSyncWorker(appContext: Context, workerParams: WorkerParameters) : FhirSyncWorker(appContext, workerParams) { override fun getDownloadWorkManager() = DownloadWorkManagerImpl() override fun getConflictResolver() = AcceptLocalConflictResolver override fun getFhirEngine() = FhirApplication.fhirEngine(applicationContext) }
- In ViewModel (
PatientListViewModel.kt
) richten Sie einen Mechanismus zur einmaligen Synchronisierung ein. Suchen Sie den folgenden Code und fügen Sie ihn dertriggerOneTimeSync()
-Funktion hinzu:
Diese Koroutine initiiert eine einmalige Synchronisierung mit dem FHIR-Server mithilfe des zuvor definierten AppFhirSyncWorker. Anschließend wird die Benutzeroberfläche entsprechend dem Status des Synchronisierungsvorgangs aktualisiert.viewModelScope.launch { Sync.oneTimeSync<AppFhirSyncWorker>(getApplication()) .shareIn(this, SharingStarted.Eagerly, 10) .collect { _pollState.emit(it) } }
- Aktualisieren Sie in der Datei
PatientListFragment.kt
den Hauptteil der FunktionhandleSyncJobStatus
:
Wenn die Synchronisierung abgeschlossen ist, wird der Nutzer in einer Toast-Nachricht darüber informiert. Die App zeigt dann alle Patienten an, indem sie eine Suche mit einem leeren Namen aufruft.when (syncJobStatus) { is SyncJobStatus.Finished -> { Toast.makeText(requireContext(), "Sync Finished", Toast.LENGTH_SHORT).show() viewModel.searchPatientsByName("") } else -> {} }
Nachdem nun alles eingerichtet ist, führen Sie Ihre App aus. Klicken Sie im Menü auf die Schaltfläche Sync
. Wenn alles ordnungsgemäß funktioniert, sollten Sie sehen, dass die Patienten von Ihrem lokalen FHIR-Server heruntergeladen und in der Anwendung angezeigt werden.
6. Patientendaten ändern und hochladen
In diesem Abschnitt erfahren Sie, wie Sie Patientendaten anhand bestimmter Kriterien ändern und die aktualisierten Daten auf Ihren FHIR-Server hochladen. Konkret werden wir die Städte der Adresse für Patienten mit Wohnsitz in Wakefield
und Taunton
austauschen.
Schritt 1: Änderungslogik in PatientListViewModel einrichten
Der Code in diesem Abschnitt wird der Funktion triggerUpdate
in PatientListViewModel
hinzugefügt.
- Auf die FHIR-Engine zugreifen: Rufen Sie zuerst einen Verweis auf die FHIR-Engine in der
PatientListViewModel.kt
ab.
Dieser Code startet eine Koroutine im Bereich von ViewModel und initialisiert die FHIR-Engine.viewModelScope.launch { val fhirEngine = FhirApplication.fhirEngine(getApplication())
- Nach Patienten aus Wakefield suchen: Verwenden Sie die FHIR-Engine, um nach Patienten mit der Adressstadt
Wakefield
zu suchen.
Hier verwenden wir dieval patientsFromWakefield = fhirEngine.search<Patient> { filter( Patient.ADDRESS_CITY, { modifier = StringFilterModifier.MATCHES_EXACTLY value = "Wakefield" } ) }
search
-Methode der FHIR-Engine, um Patienten nach ihrem Adressort zu filtern. Das Ergebnis ist eine Liste von Patienten aus Wakefield. - Nach Patienten in Taunton suchen:Suchen Sie auf ähnliche Weise nach Patienten mit der Adresse
Taunton
.
Wir haben jetzt zwei Listen mit Patienten: eine von Wakefield und eine von Taunton.val patientsFromTaunton = fhirEngine.search<Patient> { filter( Patient.ADDRESS_CITY, { modifier = StringFilterModifier.MATCHES_EXACTLY value = "Taunton" } ) }
- Patientenadressen ändern: Gehen Sie jeden Patienten in der
patientsFromWakefield
-Liste durch, ändern Sie seinen Ort inTaunton
und aktualisieren Sie ihn in der FHIR-Engine.
Aktualisieren Sie analog dazu jeden Patienten in derpatientsFromWakefield.forEach { it.resource.address.first().city = "Taunton" fhirEngine.update(it.resource) }
patientsFromTaunton
-Liste, um den Ort inWakefield
zu ändern.patientsFromTaunton.forEach { it.resource.address.first().city = "Wakefield" fhirEngine.update(it.resource) }
- Synchronisierung initiieren: Nachdem Sie die Daten lokal geändert haben, lösen Sie eine einmalige Synchronisierung aus, um sicherzustellen, dass die Daten auf dem FHIR-Server aktualisiert werden.
Die schließende KlammertriggerOneTimeSync() }
}
gibt das Ende der Koroutine an, die am Anfang gestartet wurde.
Schritt 2: Funktion testen
- UI-Test:Führen Sie Ihre App aus. Klicken Sie im Menü auf die Schaltfläche
Update
. Die Städte für die Adressen des PatientenAaron697
undAbby752
sollten vertauscht werden. - Serverbestätigung:Öffnen Sie einen Browser und rufen Sie
http://localhost:8080/fhir/Patient/
auf. Prüfen Sie, ob der Ort der Adresse für die PatientenAaron697
undAbby752
auf dem lokalen FHIR-Server aktualisiert wurde.
Mit diesen Schritten haben Sie erfolgreich einen Mechanismus implementiert, um Patientendaten zu ändern und die Änderungen mit Ihrem FHIR-Server zu synchronisieren.
7. Patienten anhand des Namens suchen
Die Suche nach Patienten anhand des Namens kann eine nutzerfreundliche Methode sein, Informationen abzurufen. Hier führen wir Sie durch den Prozess zur Implementierung dieser Funktion in Ihrer Anwendung.
Schritt 1: Funktionssignatur aktualisieren
Gehen Sie zur Datei PatientListViewModel.kt
und suchen Sie die Funktion searchPatientsByName
. Wir fügen dieser Funktion Code hinzu.
Binden Sie den folgenden bedingten Codeblock ein, um die Ergebnisse anhand der angegebenen Namensabfrage zu filtern und die Ergebnisse für die Aktualisierung der Benutzeroberfläche auszugeben:
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 }
}
}
Wenn hier nameQuery
nicht leer ist, filtert die Suchfunktion die Ergebnisse so, dass nur Patienten aufgeführt werden, deren Namen die angegebene Suchanfrage enthalten.
Schritt 2: Neue Suchfunktionen testen
- App neu starten:Nachdem Sie diese Änderungen vorgenommen haben, erstellen Sie Ihre App neu und führen Sie sie aus.
- Nach Patienten suchen: Verwenden Sie die Suchfunktion auf dem Bildschirm mit der Patientenliste. Sie sollten jetzt einen Namen (oder einen Teil eines Namens) eingeben können, um die Liste der behandelten Personen entsprechend zu filtern.
Nachdem Sie diese Schritte ausgeführt haben, haben Sie Ihre Anwendung optimiert, indem Sie Nutzern die Möglichkeit geben, Patienten effizient anhand ihres Namens zu suchen. Dies kann die Nutzererfahrung und die Effizienz beim Datenabruf erheblich verbessern.
8. Glückwunsch!
Sie haben die FHIR-Engine-Bibliothek zum Verwalten von FHIR-Ressourcen in Ihrer Anwendung verwendet:
- Sync API verwenden, um FHIR-Ressourcen mit einem FHIR-Server zu synchronisieren
- Mit der Data Access API lokale FHIR-Ressourcen erstellen, lesen, aktualisieren und löschen
- Search API verwenden, um lokale FHIR-Ressourcen zu suchen
Behandelte Themen
- Lokalen HAPI-FHIR-Server einrichten
- Testdaten auf den lokalen HAPI FHIR-Server hochladen
- So erstellen Sie eine Android-App mit der FHIR-Engine-Bibliothek
- So verwenden Sie die Sync API, die Data Access API und die Search API in der FHIR-Engine-Bibliothek
Nächste Schritte
- Dokumentation zur FHIR-Engine-Bibliothek ansehen
- Erweiterte Funktionen der Search API
- Wenden Sie die FHIR-Engine-Bibliothek in Ihrer eigenen Android-App an