1. قبل از شروع
چیزی که خواهی ساخت
در این کد لبه، شما با استفاده از FHIR Engine Library، یک برنامه اندرویدی خواهید ساخت. برنامه شما از کتابخانه موتور FHIR برای دانلود منابع FHIR از سرور FHIR و آپلود هرگونه تغییر محلی در سرور استفاده می کند.
چیزی که یاد خواهید گرفت
- نحوه ایجاد یک سرور محلی HAPI FHIR با استفاده از Docker
- چگونه کتابخانه موتور FHIR را در برنامه اندروید خود ادغام کنید
- نحوه استفاده از Sync API برای تنظیم یک کار یک بار یا دوره ای برای دانلود و آپلود منابع FHIR
- نحوه استفاده از Search API
- نحوه استفاده از API های دسترسی به داده برای ایجاد، خواندن، به روز رسانی و حذف منابع FHIR به صورت محلی
آنچه شما نیاز دارید
- Docker ( دریافت Docker )
- نسخه اخیر Android Studio (نسخه 4.1.2 و بالاتر)
- شبیه ساز Android یا یک دستگاه فیزیکی اندرویدی که دارای Android 7.0 Nougat یا جدیدتر است
- کد نمونه
- دانش اولیه توسعه اندروید در Kotlin
اگر قبلاً برنامههای Android ساخته نشدهاید، میتوانید با ساخت اولین برنامه خود شروع کنید.
2. یک سرور محلی HAPI FHIR با داده های آزمایشی راه اندازی کنید
HAPI FHIR یک سرور منبع باز محبوب FHIR است. ما از یک سرور محلی HAPI FHIR در لبه کد خود برای اتصال برنامه Android استفاده می کنیم.
سرور محلی HAPI FHIR را راه اندازی کنید
- دستور زیر را در ترمینال اجرا کنید تا آخرین تصویر HAPI FHIR را دریافت کنید
docker pull hapiproject/hapi:latest
- با استفاده از Docker Desktop برای اجرای تصویر دانلود شده
hapiproject/hapi
یا اجرای دستور زیر، یک کانتینر HAPI FHIR ایجاد کنید.
بیشتر بدانید.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/
- برای آپلود داده های آزمایش برای همه بیماران در سرور، اجرا کنید
با این حال، تکمیل این کار میتواند زمان زیادی طول بکشد و برای 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 FHIR SDK را کلون کنید: git clone https://github.com/google/android-fhir.git
پروژه شروع برای این کد لبه در codelabs/engine
قرار دارد.
برنامه را به اندروید استودیو وارد کنید
ما با وارد کردن برنامه شروع به Android Studio شروع می کنیم.
Android Studio را باز کنید، Import Project (Gradle، Eclipse ADT، و غیره) را انتخاب کنید و پوشه codelabs/engine/
از کد منبعی که قبلا دانلود کرده اید انتخاب کنید.
پروژه خود را با فایل های Gradle همگام سازی کنید
برای راحتی شما، وابستگی های کتابخانه موتور FHIR قبلاً به پروژه اضافه شده است. این به شما امکان می دهد کتابخانه موتور FHIR را در برنامه خود ادغام کنید. خطوط زیر را تا انتهای فایل app/build.gradle.kts
پروژه خود رعایت کنید:
dependencies {
// ...
implementation("com.google.android.fhir:engine:0.1.0-beta05")
}
برای اطمینان از اینکه همه وابستگی ها برای برنامه شما در دسترس هستند، باید پروژه خود را با فایل های gradle در این مرحله همگام کنید.
انتخاب پروژه همگام سازی با فایل های Gradle ( )از نوار ابزار Android Studio. همچنین میتوانید برنامه را دوباره اجرا کنید تا بررسی کنید وابستگیها درست کار میکنند.
برنامه استارتر را اجرا کنید
اکنون که پروژه را به اندروید استودیو وارد کرده اید، برای اولین بار آماده اجرای برنامه هستید.
شبیه ساز Android Studio را راه اندازی کنید و روی Run کلیک کنید ( ) در نوار ابزار Android Studio.
4. نمونه FHIR Engine را ایجاد کنید
برای ادغام FHIR Engine در برنامه Android خود، باید از FHIR Engine Library استفاده کنید و نمونه ای از FHIR Engine را راه اندازی کنید. مراحل ذکر شده در زیر شما را از طریق این فرآیند راهنمایی می کند.
- به کلاس Application خود بروید، که در این مثال
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
: این نشانی اینترنتی اصلی سرور FHIR است. آدرس IP ارائه شده10.0.2.2
به طور ویژه برای میزبان محلی رزرو شده است که از شبیه ساز اندروید قابل دسترسی است. بیشتر بدانید.
-
- در کلاس
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) }
- در ViewModel خود،
PatientListViewModel.kt
، یک مکانیسم همگامسازی یکباره راهاندازی میکنید. این کد را به تابعtriggerOneTimeSync()
بیابید و اضافه کنید:
این برنامه با استفاده از AppFhirSyncWorker که قبلاً تعریف کردیم، یک همگام سازی یکباره با سرور FHIR را آغاز می کند. سپس UI را بر اساس وضعیت فرآیند همگام سازی به روز می کند.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
شروع کنید.
این کد یک coroutine را در محدوده ViewModel راه اندازی می کند و موتور FHIR را مقداردهی اولیه می کند.viewModelScope.launch { val fhirEngine = FhirApplication.fhirEngine(getApplication())
- جستجوی بیماران از Wakefield : از موتور FHIR برای جستجوی بیماران با آدرس شهر
Wakefield
استفاده کنید.
در اینجا، ما از روشval patientsFromWakefield = fhirEngine.search<Patient> { filter( Patient.ADDRESS_CITY, { modifier = StringFilterModifier.MATCHES_EXACTLY value = "Wakefield" } ) }
search
موتور FHIR برای فیلتر کردن بیماران بر اساس شهر آدرس آنها استفاده می کنیم. نتیجه لیستی از بیماران از Wakefield خواهد بود. - جستجوی بیماران از Taunton : به طور مشابه، بیماران را با آدرس شهر
Taunton
جستجو کنید.
ما اکنون دو لیست از بیماران داریم - یکی از Wakefield و دیگری از 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
- چگونه با استفاده از کتابخانه موتور FHIR یک برنامه اندروید بسازیم
- نحوه استفاده از Sync API، Data Access API و Search API در کتابخانه موتور FHIR
مراحل بعدی
- اسناد کتابخانه موتور FHIR را کاوش کنید
- ویژگی های پیشرفته Search API را کاوش کنید
- کتابخانه موتور FHIR را در برنامه اندروید خود اعمال کنید