1. Прежде чем начать
Что ты построишь
В этой лаборатории кода вы создадите приложение для Android с использованием библиотеки FHIR Engine. Ваше приложение будет использовать библиотеку FHIR Engine для загрузки ресурсов FHIR с сервера FHIR и загрузки любых локальных изменений на сервер.
Что вы узнаете
- Как создать локальный сервер HAPI FHIR с помощью Docker
- Как интегрировать библиотеку FHIR Engine в ваше приложение для Android
- Как использовать API синхронизации для настройки однократного или периодического задания по загрузке и отправке ресурсов FHIR.
- Как использовать API поиска
- Как использовать API-интерфейсы доступа к данным для локального создания, чтения, обновления и удаления ресурсов FHIR.
Что вам понадобится
- Докер ( получить Докер )
- Последняя версия Android Studio (v4.1.2+).
- Эмулятор Android или физическое устройство Android под управлением Android 7.0 Nougat или более поздней версии.
- Пример кода
- Базовые знания разработки Android на Kotlin.
Если вы раньше не создавали приложения для Android, вы можете начать с создания своего первого приложения .
2. Настройте локальный сервер HAPI FHIR с тестовыми данными.
HAPI FHIR — популярный сервер FHIR с открытым исходным кодом. В нашей лаборатории кода мы используем локальный сервер HAPI FHIR, к которому может подключаться приложение 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-samples . Загрузите и распакуйте
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/
- Чтобы загрузить данные тестов для всех пациентов на сервер, запустите
Однако это может занять много времени и не является обязательным для лаборатории кода.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/
в браузере. В качестве результата поиска сtotal
количеством вы должны увидеть текстHTTP 200 OK
и разделResponse Body
на странице, содержащей данные пациента в пакете FHIR.
3. Установите приложение для Android.
Загрузите код
Чтобы загрузить код для этой лаборатории, клонируйте репозиторий Android FHIR SDK: git clone https://github.com/google/android-fhir.git
Стартовый проект для этой лаборатории находится в codelabs/engine
.
Импортируйте приложение в Android Studio.
Начнем с импорта стартового приложения в Android Studio.
Откройте Android Studio, выберите «Импортировать проект» (Gradle, Eclipse ADT и т. д.) и выберите папку codelabs/engine/
из исходного кода, который вы загрузили ранее.
Синхронизируйте свой проект с файлами Gradle.
Для вашего удобства в проект уже добавлены зависимости библиотеки FHIR Engine. Это позволяет вам интегрировать библиотеку FHIR Engine в ваше приложение. Обратите внимание на следующие строки в конце файла app/build.gradle.kts
вашего проекта:
dependencies {
// ...
implementation("com.google.android.fhir:engine:1.1.0")
}
Чтобы быть уверенным, что все зависимости доступны для вашего приложения, на этом этапе вам следует синхронизировать свой проект с файлами Gradle.
Выберите «Синхронизировать проект с файлами Gradle» ( ) на панели инструментов Android Studio. Вы также можете снова запустить приложение, чтобы проверить правильность работы зависимостей.
Запустите стартовое приложение
Теперь, когда вы импортировали проект в 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
. - Внутри метода
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
специально зарезервирован для локального хоста, доступного из эмулятора 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 с использованием фонового рабочего процесса. Здесь мы определили, какой диспетчер загрузки, средство разрешения конфликтов и экземпляр механизма FHIR использовать для синхронизации.class AppFhirSyncWorker(appContext: Context, workerParams: WorkerParameters) : FhirSyncWorker(appContext, workerParams) { override fun getDownloadWorkManager() = DownloadWorkManagerImpl() override fun getConflictResolver() = AcceptLocalConflictResolver override fun getFhirEngine() = FhirApplication.fhirEngine(applicationContext) override fun getUploadStrategy() = UploadStrategy.forBundleRequest( methodForCreate = HttpCreateMethod.PUT, methodForUpdate = HttpUpdateMethod.PATCH, squash = true, bundleSize = 500, ) }
- В вашей 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 Engine для управления ресурсами FHIR в своем приложении:
- Используйте API синхронизации для синхронизации ресурсов FHIR с сервером FHIR.
- Используйте API доступа к данным для создания, чтения, обновления и удаления локальных ресурсов FHIR.
- Используйте API поиска для поиска местных ресурсов FHIR.
Что мы рассмотрели
- Как настроить локальный сервер HAPI FHIR
- Как загрузить тестовые данные на локальный сервер HAPI FHIR
- Как создать приложение для Android с помощью библиотеки FHIR Engine
- Как использовать API синхронизации, API доступа к данным и API поиска в библиотеке FHIR Engine.
Следующие шаги
- Изучите документацию по библиотеке FHIR Engine.
- Ознакомьтесь с расширенными функциями API поиска.
- Примените библиотеку FHIR Engine в своем собственном приложении для Android.