۱. قبل از شروع
آنچه خواهید ساخت
در این آزمایشگاه کد، شما یک برنامه اندروید با استفاده از کتابخانه موتور FHIR خواهید ساخت. برنامه شما از کتابخانه موتور FHIR برای دانلود منابع FHIR از یک سرور FHIR و آپلود هرگونه تغییرات محلی به سرور استفاده خواهد کرد.
آنچه یاد خواهید گرفت
- نحوه ایجاد یک سرور محلی HAPI FHIR با استفاده از Docker
- نحوه ادغام کتابخانه موتور FHIR در برنامه اندروید شما
- نحوه استفاده از API همگامسازی برای تنظیم یک کار یکباره یا دورهای برای دانلود و آپلود منابع FHIR
- نحوه استفاده از API جستجو
- نحوه استفاده از API های دسترسی به داده برای ایجاد، خواندن، بهروزرسانی و حذف منابع FHIR به صورت محلی
آنچه نیاز دارید
- داکر ( دریافت داکر )
- نسخه جدید اندروید استودیو (نسخه ۴.۱.۲ به بالا)
- شبیهساز اندروید یا یک دستگاه اندروید فیزیکی که اندروید ۷.۰ نوقا یا بالاتر را اجرا میکند
- کد نمونه
- آشنایی اولیه با توسعه اندروید با زبان کاتلین
اگر قبلاً برنامههای اندروید نساختهاید، میتوانید با ساخت اولین برنامه خود شروع کنید.
۲. یک سرور محلی HAPI FHIR با دادههای آزمایشی راهاندازی کنید
HAPI FHIR یک سرور FHIR متنباز محبوب است. ما از یک سرور محلی HAPI FHIR در آزمایشگاه کد خود برای اتصال برنامه اندروید استفاده میکنیم.
سرور محلی HAPI FHIR را راهاندازی کنید
- برای دریافت آخرین ایمیج HAPI FHIR، دستور زیر را در ترمینال اجرا کنید.
docker pull hapiproject/hapi:latest - با استفاده از Docker Desktop برای اجرای تصویر
hapiproject/hapiکه قبلاً دانلود کردهاید، یا با اجرای دستور زیر، یک کانتینر HAPI FHIR ایجاد کنید. بیشتر بدانید.docker run -p 8080:8080 hapiproject/hapi:latest - با باز کردن آدرس
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 - با باز کردن آدرس اینترنتی
http://localhost:8080/fhir/Patient/در مرورگر، تأیید کنید که دادههای آزمایشی روی سرور موجود است. باید متنHTTP 200 OKو بخشResponse Bodyصفحه حاوی دادههای بیمار در یک FHIR Bundle را به عنوان نتیجه جستجو به همراه تعدادtotalمشاهده کنید.
۳. برنامه اندروید را تنظیم کنید
کد را دانلود کنید
برای دانلود کد این آزمایشگاه کد، مخزن Android FHIR SDK را کلون کنید: git clone https://github.com/google/android-fhir.git
پروژه اولیه این codelab در codelabs/engine قرار دارد.
وارد کردن برنامه به اندروید استودیو
ما با وارد کردن برنامه اولیه به اندروید استودیو شروع میکنیم.
اندروید استودیو را باز کنید، گزینهی Import Project (Gradle، Eclipse ADT و غیره) را انتخاب کنید و پوشهی codelabs/engine/ را از کد منبعی که قبلاً دانلود کردهاید، انتخاب کنید.

پروژه خود را با فایلهای Gradle همگامسازی کنید
برای راحتی شما، وابستگیهای کتابخانه موتور FHIR از قبل به پروژه اضافه شدهاند. این به شما امکان میدهد کتابخانه موتور FHIR را در برنامه خود ادغام کنید. خطوط زیر را در انتهای فایل app/build.gradle.kts پروژه خود مشاهده کنید:
dependencies {
// ...
implementation("com.google.android.fhir:engine:1.1.0")
}
برای اطمینان از اینکه همه وابستگیها برای برنامه شما در دسترس هستند، باید پروژه خود را در این مرحله با فایلهای gradle همگامسازی کنید.
پروژه همگامسازی با فایلهای Gradle را انتخاب کنید (
) از نوار ابزار اندروید استودیو. همچنین میتوانید برنامه را دوباره اجرا کنید تا بررسی کنید که وابستگیها به درستی کار میکنند.
برنامه شروع کننده را اجرا کنید
حالا که پروژه را به اندروید استودیو وارد کردهاید، آمادهاید تا برای اولین بار برنامه را اجرا کنید.
شبیهساز اندروید استودیو را اجرا کنید و روی Run (اجرا) کلیک کنید.
) در نوار ابزار اندروید استودیو.

۴. ایجاد نمونه موتور FHIR
برای گنجاندن موتور FHIR در برنامه اندروید خود، باید از کتابخانه موتور FHIR استفاده کنید و یک نمونه از موتور FHIR را راهاندازی کنید. مراحل ذکر شده در زیر شما را در این فرآیند راهنمایی میکند.
- به کلاس Application خود بروید که در این مثال
FhirApplication.ktاست و در مسیرapp/src/main/java/com/google/android/fhir/codelabs/engineقرار دارد. - درون متد
onCreate()، کد زیر را برای مقداردهی اولیه موتور FHIR اضافه کنید: یادداشتها: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 رزرو شده است که از شبیه ساز اندروید قابل دسترسی است. اطلاعات بیشتر .
-
- در کلاس
FhirApplication، خط زیر را برای نمونهسازی تنبل از موتور FHIR اضافه کنید: این تضمین میکند که نمونه FhirEngine فقط زمانی ایجاد میشود که برای اولین بار به آن دسترسی پیدا میشود، نه بلافاصله پس از شروع برنامه.private val fhirEngine: FhirEngine by lazy { FhirEngineProvider.getInstance(this) } - برای دسترسی آسانتر در سراسر برنامه، متد راحتی زیر را در کلاس
FhirApplicationاضافه کنید: این متد استاتیک به شما امکان میدهد نمونه موتور FHIR را از هر کجای برنامه با استفاده از context بازیابی کنید.companion object { fun fhirEngine(context: Context) = (context.applicationContext as FhirApplication).fhirEngine }
۵. همگامسازی دادهها با سرور 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) override fun getUploadStrategy() = UploadStrategy.forBundleRequest( methodForCreate = HttpCreateMethod.PUT, methodForUpdate = HttpUpdateMethod.PATCH, squash = true, bundleSize = 500, ) } - در ViewModel خود،
PatientListViewModel.kt، یک مکانیزم همگامسازی یکباره راهاندازی خواهید کرد. این کد را پیدا کرده و به تابعtriggerOneTimeSync()اضافه کنید: این کوروتین با استفاده از AppFhirSyncWorker که قبلاً تعریف کردیم، یک همگامسازی یکباره با سرور FHIR آغاز میکند. سپس رابط کاربری را بر اساس وضعیت فرآیند همگامسازی بهروزرسانی میکند.viewModelScope.launch { Sync.oneTimeSync<AppFhirSyncWorker>(getApplication()) .shareIn(this, SharingStarted.Eagerly, 10) .collect { _pollState.emit(it) } } - در فایل
PatientListFragment.kt، بدنهی تابعhandleSyncJobStatusرا بهروزرسانی کنید: در اینجا، هنگامی که فرآیند همگامسازی به پایان میرسد، یک پیام Toast به کاربر اطلاع میدهد و سپس برنامه با فراخوانی جستجو با نام خالی، تمام بیماران را نمایش میدهد.when (syncJobStatus) { is SyncJobStatus.Finished -> { Toast.makeText(requireContext(), "Sync Finished", Toast.LENGTH_SHORT).show() viewModel.searchPatientsByName("") } else -> {} }
حالا که همه چیز تنظیم شده است، برنامه خود را اجرا کنید. روی دکمه Sync در منو کلیک کنید. اگر همه چیز به درستی کار کند، باید ببینید که بیماران از سرور محلی FHIR شما دانلود شده و در برنامه نمایش داده میشوند.

۶. اصلاح و بارگذاری اطلاعات بیمار
در این بخش، شما را در فرآیند اصلاح دادههای بیمار بر اساس معیارهای خاص و آپلود دادههای بهروز شده در سرور 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() }}نشاندهندهی پایان کوروتینی است که در ابتدا اجرا شده است.
مرحله ۲ : تست عملکرد
- تست رابط کاربری : برنامه خود را اجرا کنید. روی دکمه
Updateدر منو کلیک کنید. باید ببینید که آدرس شهرهای بیمارAaron697وAbby752با هم عوض شده است. - تأیید سرور : یک مرورگر باز کنید و به آدرس
http://localhost:8080/fhir/Patient/بروید. تأیید کنید که آدرس شهر برای بیمارانAaron697وAbby752در سرور محلی FHIR بهروز شده باشد.
با دنبال کردن این مراحل، شما با موفقیت مکانیزمی را برای تغییر دادههای بیمار و همگامسازی تغییرات با سرور FHIR خود پیادهسازی کردهاید.
۷. جستجوی بیماران بر اساس نام
جستجوی بیماران بر اساس نام آنها میتواند روشی کاربرپسند برای بازیابی اطلاعات فراهم کند. در اینجا، شما را در فرآیند پیادهسازی این ویژگی در برنامهتان راهنمایی خواهیم کرد.
مرحله ۱ : بهروزرسانی امضای تابع
به فایل 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 خالی نباشد، تابع جستجو نتایج را فیلتر میکند تا فقط بیمارانی را شامل شود که نام آنها شامل عبارت جستجوی مشخص شده باشد.
مرحله ۲ : عملکرد جستجوی جدید را آزمایش کنید
- برنامه را دوباره اجرا کنید : پس از انجام این تغییرات، برنامه خود را دوباره بسازید و اجرا کنید.
- جستجوی بیماران : در صفحه لیست بیماران، از قابلیت جستجو استفاده کنید. اکنون باید بتوانید یک نام (یا بخشی از نام) را وارد کنید تا لیست بیماران بر اساس آن فیلتر شود.
با تکمیل این مراحل، شما با فراهم کردن امکان جستجوی کارآمد بیماران بر اساس نامشان برای کاربران، برنامه خود را ارتقا دادهاید. این امر میتواند به طور قابل توجهی تجربه کاربری و کارایی در بازیابی دادهها را بهبود بخشد.
۸. تبریک میگویم!
شما از کتابخانه موتور FHIR برای مدیریت منابع FHIR در برنامه خود استفاده کردهاید:
- استفاده از API همگامسازی برای همگامسازی منابع FHIR با یک سرور FHIR
- استفاده از API دسترسی به داده برای ایجاد، خواندن، بهروزرسانی و حذف منابع محلی FHIR
- استفاده از API جستجو برای جستجوی منابع محلی FHIR
آنچه ما پوشش دادهایم
- نحوه راه اندازی یک سرور محلی HAPI FHIR
- نحوه آپلود دادههای آزمایشی به سرور محلی HAPI FHIR
- نحوه ساخت یک برنامه اندروید با استفاده از کتابخانه موتور FHIR
- نحوه استفاده از API همگامسازی، API دسترسی به داده و API جستجو در کتابخانه موتور FHIR
مراحل بعدی
- مستندات کتابخانه موتور FHIR را بررسی کنید
- ویژگیهای پیشرفتهی Search API را بررسی کنید
- کتابخانه موتور FHIR را در برنامه اندروید خود اعمال کنید