1. Trước khi bắt đầu
Sản phẩm bạn sẽ tạo ra
Trong lớp học lập trình này, bạn sẽ xây dựng một ứng dụng Android bằng Thư viện công cụ FHIR. Ứng dụng của bạn sẽ sử dụng Thư viện công cụ FHIR để tải tài nguyên FHIR xuống từ máy chủ FHIR và tải mọi thay đổi cục bộ lên máy chủ.
Kiến thức bạn sẽ học được
- Cách tạo máy chủ HAPI FHIR cục bộ bằng Docker
- Cách tích hợp Thư viện công cụ FHIR vào ứng dụng Android
- Cách sử dụng API Đồng bộ hoá để thiết lập một công việc định kỳ hoặc một lần để tải xuống và tải lên tài nguyên FHIR
- Cách sử dụng Search API
- Cách sử dụng API truy cập dữ liệu để tạo, đọc, cập nhật và xoá tài nguyên FHIR cục bộ
Bạn cần có
- Docker (tải Docker)
- Phiên bản gần đây của Android Studio (phiên bản 4.1.2 trở lên)
- Trình mô phỏng Android hoặc thiết bị Android thực chạy Android 7.0 Nougat trở lên
- Mã mẫu
- Kiến thức cơ bản về phát triển Android bằng Kotlin
Nếu chưa từng tạo ứng dụng Android, bạn có thể bắt đầu bằng cách tạo ứng dụng đầu tiên.
2. Thiết lập máy chủ HAPI FHIR cục bộ bằng dữ liệu kiểm thử
HAPI FHIR là một máy chủ FHIR nguồn mở phổ biến. Chúng tôi sử dụng máy chủ HAPI FHIR cục bộ trong lớp học lập trình để ứng dụng Android kết nối.
Thiết lập máy chủ HAPI FHIR cục bộ
- Chạy lệnh sau trong một thiết bị đầu cuối để tải hình ảnh mới nhất của HAPI FHIR
docker pull hapiproject/hapi:latest
- Tạo vùng chứa HAPI FHIR bằng cách sử dụng Docker Desktop để chạy hình ảnh
hapiproject/hapi
đã tải xuống trước đó hoặc chạy lệnh sau Tìm hiểu thêm.docker run -p 8080:8080 hapiproject/hapi:latest
- Kiểm tra máy chủ bằng cách mở URL
http://localhost:8080/
trong trình duyệt. Bạn sẽ thấy giao diện web HAPI FHIR.
Điền dữ liệu kiểm thử vào máy chủ HAPI FHIR cục bộ
Để kiểm thử ứng dụng, chúng ta cần có một số dữ liệu kiểm thử trên máy chủ. Chúng ta sẽ sử dụng dữ liệu tổng hợp do Synthea tạo.
- Trước tiên, chúng ta cần tải dữ liệu mẫu xuống từ synthea-samples. Tải xuống và giải nén
synthea_sample_data_fhir_r4_sep2019.zip
. Dữ liệu mẫu chưa giải nén có nhiều tệp.json
, mỗi tệp là một gói giao dịch cho một bệnh nhân riêng lẻ. - Chúng ta sẽ tải dữ liệu kiểm thử cho 3 bệnh nhân lên máy chủ HAPI FHIR cục bộ. Chạy lệnh sau trong thư mục chứa các tệp 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/
- Để tải dữ liệu kiểm thử cho tất cả bệnh nhân lên máy chủ, hãy chạy
Tuy nhiên, việc này có thể mất nhiều thời gian để hoàn tất và không cần thiết cho lớp học lập trình.for f in *.json; do curl -X POST -H "Content-Type: application/json" -d @$f http://localhost:8080/fhir/ ; done
- Xác minh rằng dữ liệu kiểm thử có trên máy chủ bằng cách mở URL
http://localhost:8080/fhir/Patient/
trong trình duyệt. Bạn sẽ thấy văn bảnHTTP 200 OK
và mụcResponse Body
của trang chứa dữ liệu bệnh nhân trong Gói FHIR dưới dạng kết quả tìm kiếm với số lượngtotal
.
3. Thiết lập ứng dụng Android
Tải mã nguồn xuống
Để tải mã cho lớp học lập trình này, hãy sao chép kho lưu trữ SDK Android FHIR: git clone https://github.com/google/android-fhir.git
Dự án khởi động cho lớp học lập trình này nằm trong codelabs/engine
.
Nhập ứng dụng vào Android Studio
Chúng ta bắt đầu bằng cách nhập ứng dụng khởi động vào Android Studio.
Mở Android Studio, chọn Import Project (Gradle, Eclipse ADT, etc.) (Nhập dự án (Gradle, Eclipse ADT, v.v.)) rồi chọn thư mục codelabs/engine/
trong mã nguồn mà bạn đã tải xuống trước đó.
Đồng bộ hoá dự án với các tệp Gradle
Để thuận tiện cho bạn, các phần phụ thuộc Thư viện công cụ FHIR đã được thêm vào dự án. Thao tác này cho phép bạn tích hợp Thư viện công cụ FHIR vào ứng dụng. Hãy quan sát các dòng sau cho đến cuối tệp app/build.gradle.kts
của dự án:
dependencies {
// ...
implementation("com.google.android.fhir:engine:1.1.0")
}
Để đảm bảo rằng ứng dụng của bạn có tất cả các phần phụ thuộc, bạn nên đồng bộ hoá dự án với các tệp gradle tại thời điểm này.
Chọn Sync Project with Gradle Files (Đồng bộ hoá dự án với tệp Gradle) () trên thanh công cụ Android Studio. Bạn cũng có thể chạy lại ứng dụng để kiểm tra xem các phần phụ thuộc có hoạt động đúng cách hay không.
Chạy ứng dụng khởi động
Giờ đây, khi đã nhập dự án vào Android Studio, bạn đã sẵn sàng chạy ứng dụng lần đầu tiên.
Khởi động trình mô phỏng Android Studio rồi nhấp vào biểu tượng Chạy () trong thanh công cụ Android Studio.
4. Tạo thực thể Công cụ FHIR
Để đưa Công cụ FHIR vào ứng dụng Android, bạn cần sử dụng Thư viện công cụ FHIR và khởi tạo một thực thể của Công cụ FHIR. Các bước dưới đây sẽ hướng dẫn bạn thực hiện quy trình này.
- Chuyển đến lớp Ứng dụng (Application), trong ví dụ này là
FhirApplication.kt
, nằm trongapp/src/main/java/com/google/android/fhir/codelabs/engine
. - Bên trong phương thức
onCreate()
, hãy thêm mã sau để khởi chạy Công cụ FHIR: Lưu ý: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
: Bật tính năng mã hoá dữ liệu nếu thiết bị hỗ trợ tính năng này.RECREATE_AT_OPEN
: Xác định chiến lược lỗi cơ sở dữ liệu. Trong trường hợp này, lớp này sẽ tạo lại cơ sở dữ liệu nếu xảy ra lỗi khi mở.baseUrl
trongServerConfiguration
: Đây là URL cơ sở của máy chủ FHIR. Địa chỉ IP10.0.2.2
được cung cấp được dành riêng cho máy chủ cục bộ, có thể truy cập được từ trình mô phỏng Android. Tìm hiểu thêm.
- Trong lớp
FhirApplication
, hãy thêm dòng sau để tạo bản sao động cho Công cụ FHIR: Điều này đảm bảo rằng thực thể FhirEngine chỉ được tạo khi được truy cập lần đầu tiên, chứ không phải ngay khi ứng dụng khởi động.private val fhirEngine: FhirEngine by lazy { FhirEngineProvider.getInstance(this) }
- Thêm phương thức tiện lợi sau đây vào lớp
FhirApplication
để dễ dàng truy cập trong toàn bộ ứng dụng: Phương thức tĩnh này cho phép bạn truy xuất thực thể Công cụ FHIR từ bất kỳ vị trí nào trong ứng dụng bằng cách sử dụng ngữ cảnh.companion object { fun fhirEngine(context: Context) = (context.applicationContext as FhirApplication).fhirEngine }
5. Đồng bộ hoá dữ liệu với máy chủ FHIR
- Tạo một lớp mới
DownloadWorkManagerImpl.kt
. Trong lớp này, bạn sẽ xác định cách ứng dụng tìm nạp tài nguyên tiếp theo từ danh sách để tải xuống.: Lớp này có một hàng đợi các loại tài nguyên mà nó muốn tải xuống. Phương thức này xử lý các phản hồi và trích xuất tài nguyên từ gói được trả về, được lưu vào cơ sở dữ liệu cục bộ.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 } }
- Tạo một lớp mới
AppFhirSyncWorker.kt
Lớp này xác định cách ứng dụng sẽ đồng bộ hoá với máy chủ FHIR từ xa bằng một worker trong nền. Ở đây, chúng ta đã xác định trình quản lý tải xuống, trình phân giải xung đột và thực thể công cụ FHIR sẽ sử dụng để đồng bộ hoá.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, ) }
- Trong ViewModel,
PatientListViewModel.kt
, bạn sẽ thiết lập cơ chế đồng bộ hoá một lần. Tìm và thêm mã này vào hàmtriggerOneTimeSync()
: Coroutine này bắt đầu quá trình đồng bộ hoá một lần với máy chủ FHIR bằng cách sử dụng AppFhirSyncWorker mà chúng ta đã xác định trước đó. Sau đó, ứng dụng sẽ cập nhật giao diện người dùng dựa trên trạng thái của quá trình đồng bộ hoá.viewModelScope.launch { Sync.oneTimeSync<AppFhirSyncWorker>(getApplication()) .shareIn(this, SharingStarted.Eagerly, 10) .collect { _pollState.emit(it) } }
- Trong tệp
PatientListFragment.kt
, hãy cập nhật phần nội dung của hàmhandleSyncJobStatus
: Ở đây, khi quá trình đồng bộ hoá kết thúc, một thông báo ngắn sẽ hiển thị để thông báo cho người dùng, sau đó ứng dụng sẽ hiển thị tất cả bệnh nhân bằng cách gọi một lượt tìm kiếm có tên trống.when (syncJobStatus) { is SyncJobStatus.Finished -> { Toast.makeText(requireContext(), "Sync Finished", Toast.LENGTH_SHORT).show() viewModel.searchPatientsByName("") } else -> {} }
Giờ thì mọi thứ đã sẵn sàng, hãy chạy ứng dụng. Nhấp vào nút Sync
trong trình đơn. Nếu mọi thứ hoạt động đúng cách, bạn sẽ thấy các bệnh nhân từ máy chủ FHIR cục bộ được tải xuống và hiển thị trong ứng dụng.
6. Sửa đổi và tải dữ liệu bệnh nhân lên
Trong phần này, chúng tôi sẽ hướng dẫn bạn quy trình sửa đổi dữ liệu bệnh nhân dựa trên các tiêu chí cụ thể và tải dữ liệu đã cập nhật lên máy chủ FHIR. Cụ thể, chúng ta sẽ hoán đổi thành phố địa chỉ cho những bệnh nhân cư trú ở Wakefield
và Taunton
.
Bước 1: Thiết lập Logic sửa đổi trong PatientListViewModel
Mã trong phần này được thêm vào hàm triggerUpdate
trong PatientListViewModel
- Truy cập vào Công cụ FHIR:Bắt đầu bằng cách tham chiếu đến công cụ FHIR trong
PatientListViewModel.kt
. Mã này khởi chạy một coroutine trong phạm vi của ViewModel và khởi chạy công cụ FHIR.viewModelScope.launch { val fhirEngine = FhirApplication.fhirEngine(getApplication())
- Tìm bệnh nhân ở Wakefield:Sử dụng công cụ FHIR để tìm bệnh nhân có thành phố địa chỉ là
Wakefield
. Ở đây, chúng ta đang sử dụng phương thứcval patientsFromWakefield = fhirEngine.search<Patient> { filter( Patient.ADDRESS_CITY, { modifier = StringFilterModifier.MATCHES_EXACTLY value = "Wakefield" } ) }
search
của công cụ FHIR để lọc bệnh nhân dựa trên thành phố địa chỉ của họ. Kết quả sẽ là danh sách bệnh nhân ở Wakefield. - Tìm kiếm bệnh nhân ở Taunton:Tương tự, hãy tìm kiếm bệnh nhân có thành phố địa chỉ là
Taunton
. Chúng ta hiện có hai danh sách bệnh nhân – một danh sách từ Wakefield và một danh sách từ Taunton.val patientsFromTaunton = fhirEngine.search<Patient> { filter( Patient.ADDRESS_CITY, { modifier = StringFilterModifier.MATCHES_EXACTLY value = "Taunton" } ) }
- Sửa đổi địa chỉ của bệnh nhân:Xem xét từng bệnh nhân trong danh sách
patientsFromWakefield
, thay đổi thành phố của họ thànhTaunton
và cập nhật trong công cụ FHIR. Tương tự, hãy cập nhật từng bệnh nhân trong danh sáchpatientsFromWakefield.forEach { it.resource.address.first().city = "Taunton" fhirEngine.update(it.resource) }
patientsFromTaunton
để thay đổi thành phố của họ thànhWakefield
.patientsFromTaunton.forEach { it.resource.address.first().city = "Wakefield" fhirEngine.update(it.resource) }
- Bắt đầu đồng bộ hoá:Sau khi sửa đổi dữ liệu cục bộ, hãy kích hoạt một lần đồng bộ hoá để đảm bảo dữ liệu được cập nhật trên máy chủ FHIR.
Dấu ngoặc nhọn đóngtriggerOneTimeSync() }
}
biểu thị sự kết thúc của coroutine được khởi chạy ở đầu.
Bước 2: Kiểm thử chức năng
- Kiểm thử giao diện người dùng:Chạy ứng dụng. Nhấp vào nút
Update
trong trình đơn. Bạn sẽ thấy các thành phố trong địa chỉ của bệnh nhânAaron697
vàAbby752
được hoán đổi. - Xác minh máy chủ:Mở trình duyệt và chuyển đến
http://localhost:8080/fhir/Patient/
. Xác minh rằng thành phố địa chỉ của bệnh nhânAaron697
vàAbby752
đã được cập nhật trên máy chủ FHIR cục bộ.
Bằng cách làm theo các bước này, bạn đã triển khai thành công một cơ chế để sửa đổi dữ liệu bệnh nhân và đồng bộ hoá các thay đổi với máy chủ FHIR.
7. Tìm bệnh nhân theo tên
Việc tìm kiếm bệnh nhân theo tên có thể là một cách truy xuất thông tin thân thiện với người dùng. Tại đây, chúng tôi sẽ hướng dẫn bạn quy trình triển khai tính năng này trong ứng dụng.
Bước 1: Cập nhật chữ ký hàm
Chuyển đến tệp PatientListViewModel.kt
và tìm hàm có tên searchPatientsByName
. Chúng ta sẽ thêm mã vào hàm này.
Để lọc kết quả dựa trên cụm từ tìm kiếm tên được cung cấp và phát kết quả để giao diện người dùng cập nhật, hãy kết hợp khối mã có điều kiện sau:
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 }
}
}
Tại đây, nếu nameQuery
không trống, hàm tìm kiếm sẽ lọc kết quả để chỉ bao gồm những bệnh nhân có tên chứa cụm từ tìm kiếm đã chỉ định.
Bước 2: Kiểm thử chức năng Tìm kiếm mới
- Chạy lại ứng dụng:Sau khi thực hiện các thay đổi này, hãy tạo lại và chạy ứng dụng.
- Tìm bệnh nhân: Trên màn hình danh sách bệnh nhân, hãy sử dụng chức năng tìm kiếm. Giờ đây, bạn có thể nhập tên (hoặc một phần tên) để lọc danh sách bệnh nhân cho phù hợp.
Sau khi hoàn tất các bước này, bạn đã cải thiện ứng dụng của mình bằng cách cung cấp cho người dùng khả năng tìm kiếm bệnh nhân theo tên một cách hiệu quả. Điều này có thể cải thiện đáng kể trải nghiệm người dùng và hiệu quả truy xuất dữ liệu.
8. Xin chúc mừng!
Bạn đã sử dụng Thư viện công cụ FHIR để quản lý tài nguyên FHIR trong ứng dụng:
- Sử dụng API Đồng bộ hoá để đồng bộ hoá tài nguyên FHIR với máy chủ FHIR
- Sử dụng API truy cập dữ liệu để tạo, đọc, cập nhật và xoá tài nguyên FHIR cục bộ
- Sử dụng API Tìm kiếm để tìm kiếm tài nguyên FHIR cục bộ
Nội dung đã đề cập
- Cách thiết lập máy chủ HAPI FHIR cục bộ
- Cách tải dữ liệu kiểm thử lên Máy chủ HAPI FHIR cục bộ
- Cách tạo ứng dụng Android bằng Thư viện công cụ FHIR
- Cách sử dụng API đồng bộ hoá, API truy cập dữ liệu và API tìm kiếm trong Thư viện công cụ FHIR
Các bước tiếp theo
- Khám phá tài liệu về Thư viện công cụ FHIR
- Khám phá các tính năng nâng cao của Search API
- Áp dụng Thư viện công cụ FHIR trong ứng dụng Android của riêng bạn