使用结构化数据捕获库捕获和处理健康数据

1. 准备工作

构建内容

在此 Codelab 中,您将学习如何使用结构化数据捕获库构建 Android 应用。您的应用将使用结构化数据捕获库来呈现和处理 FHIR 问卷和回答。

学习内容

  • 如何将结构化数据捕获库集成到 Android 应用中
  • 如何显示问卷
  • 如何以 QuestionnaireResponse 的身份获取答案
  • 如何从 QuestionnaireResponse 中提取 FHIR 资源

所需条件

本 Codelab 主要介绍结构化数据捕获库。对于不相关的概念,我们仅会略作介绍,但是会提供相应代码块供您复制和粘贴。如果您之前没有构建过 Android 应用,可以先构建首个应用

2. 进行设置

下载代码

如需下载此 Codelab 的代码,请克隆 Android FHIR SDK 代码库:git clone https://github.com/google/android-fhir.git

此 Codelab 的起始项目位于 codelabs/datacapture 中。

将应用导入 Android Studio

首先,将起始应用导入 Android Studio。

打开 Android Studio,选择 Import Project (Gradle, Eclipse ADT, etc.),然后从之前下载的源代码中选择 codelabs/datacapture 文件夹。

Android Studio 启动界面

运行起始应用

现在,您已将项目导入 Android Studio,可以首次运行该应用了。

通过 USB 将 Android 设备连接到主机,或启动 Android Studio 模拟器,然后点击 Android Studio 工具栏中的“运行”图标 (“Run”按钮)。

Hello World 应用

如您所见,这里还没有太多内容,因此我们直接开始在应用中显示问卷!

3. 将结构化数据捕获库添加到项目中

添加了结构化数据捕获库的依赖项

结构化数据捕获库依赖项可让您在应用中集成结构化数据捕获库。请将以下代码行添加到项目的 app/build.gradle.kts 文件末尾:

dependencies {
    // ...

    implementation("com.google.android.fhir:data-capture:1.2.0")
    implementation("androidx.fragment:fragment-ktx:1.6.0")
}

将项目与 Gradle 文件同步

为确保您的应用拥有所有依赖项,此时您应该将项目与 Gradle 文件同步。

在 Android Studio 工具栏中选择 Sync Project with Gradle Files 图标 (Gradle 同步按钮)。您还可以再次运行应用,以检查依赖项是否正常工作。

4. 显示调查问卷

在此步骤中,您将向起始应用添加功能,以在 FragmentContainerView 中呈现问卷。

在此过程中,Android Studio 将提示您添加必要的导入:

  • androidx.core.os.bundleOf
  • androidx.fragment.app.add
  • androidx.fragment.app.commit
  • android.util.Log
  • com.google.android.fhir.datacapture.QuestionnaireFragment

第 1 步:添加 FragmentContainerView

向应用的布局添加 FragmentContainerView。您稍后创建的 QuestionnaireFragment 将显示在此处。

  1. 打开 activity_main.xml (res > layout > activity_main.xml)。
  2. 在布局编辑器的右上角,找到“代码”“拆分”和“设计”视图选项。
  3. 选择“代码”视图。布局视图选项
  4. 您不需要 TextView,因此请将其删除。请务必删除从 <TextView 到结束标记 /> 之间的所有内容。
  5. ConstraintLayout 内添加 FragmentContainerView。您的 activity_main.xml 文件应类似于以下内容:
    <?xml version="1.0" encoding="utf-8" ?>
    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
    >
    
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toTopOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

第 2 步:配置 QuestionnaireFragment

QuestionnaireFragment 需要 JSON 编码的 FHIR 问卷才能进行渲染。由于问卷很小(<512 KB),您将把它作为 String 包含在将用于创建 fragment 的 Bundle 实参中。出于性能考虑,较大的问卷应以 URI 形式提供。

您可以查看 questionnaire.json 文件,但结构化数据捕获库的一大优势在于,您无需了解 FHIR 问卷的结构(或任何与 FHIR 相关的信息),即可让该库呈现问卷!您将在本 Codelab 的后面部分仔细查看此文件。

使用构建器创建 QuestionnaireFragment,并使用 setter 函数设置问卷。如需在布局容器中显示 QuestionnaireFragment,请使用 FragmentManager 创建 FragmentTransaction

打开 MainActivity.kt,并将以下代码添加到 MainActivity 类:

// Step 2: Configure a QuestionnaireFragment
questionnaireJsonString = getStringFromAssets("questionnaire.json")

val questionnaireFragment =
  QuestionnaireFragment.builder().setQuestionnaire(questionnaireJsonString!!).build()

第 3 步:将 QuestionnaireFragment 添加到 FragmentContainerView

如需在布局容器中显示 QuestionnaireFragment,请使用 FragmentManager 创建 FragmentTransactionFragmentManager 使用之前创建的 questionnaireParams 处理实例化。

将以下代码添加到 MainActivity 类中:

// Step 3: Add the QuestionnaireFragment to the FragmentContainerView
if (savedInstanceState == null) {
  supportFragmentManager.commit {
    setReorderingAllowed(true)
    add(R.id.fragment_container_view, questionnaireFragment)
  }
}
// Submit button callback
supportFragmentManager.setFragmentResultListener(
  QuestionnaireFragment.SUBMIT_REQUEST_KEY,
  this,
) { _, _ ->
  submitQuestionnaire()
}

详细了解如何使用 fragment

点击 Android Studio 工具栏中的“运行”(“Run”按钮),运行此 Codelab。您应该会看到如下所示的内容:

在模拟器中呈现的调查问卷

浏览问卷,尝试输入一些答案。系统使用了几种不同的回答 widget,包括布尔值、文本和日期,这些 widget 会根据原始 FHIR 问卷中的底层类型自动呈现。

从技术上来说,这就是呈现问卷所需执行的所有操作!恭喜!

不过,如果您无法查看用户输入的答案,问卷调查就没什么用处了。接下来,我们继续执行获取问卷回答的下一步!

5. 获取问卷回答

在之前的步骤中,您在应用中呈现了 FHIR 问卷。

在此部分中,您将从问卷调查中获取答案,并将其作为 QuestionnaireResponse。

找到 submitQuestionnaire() 方法并添加以下代码:

// Get a questionnaire response
val fragment = supportFragmentManager.findFragmentById(R.id.fragment_container_view)
        as QuestionnaireFragment
val questionnaireResponse = fragment.getQuestionnaireResponse()

// Print the response to the log
val jsonParser = FhirContext.forCached(FhirVersionEnum.R4).newJsonParser()
val questionnaireResponseString =
    jsonParser.encodeResourceToString(questionnaireResponse)
Log.d("response", questionnaireResponseString)

如需获取调查问卷回答,请检索之前创建的调查问卷片段,然后使用 getQuestionnaireResponse() 方法。这会返回一个 HAPI FHIR QuestionnaireResponse,您可以直接使用该对象,也可以将其与 Android FHIR SDK 的其他部分搭配使用。此 Codelab 使用其他 HAPI FHIR 库将其转换为 JSON 字符串,以便在日志中查看。

再次运行应用,以使用最新更改重新构建应用。运行后,在调查问卷中输入一些信息,然后点按提交。在日志中,您应该会看到一条包含 QuestionnaireResponse(以 JSON 格式表示)的消息。

D/response: {"resourceType":"QuestionnaireResponse","item":[{"linkId":"PR","text":"Patient information","item":[{"linkId":"PR-name","text":"Name","item":[{"linkId":"PR-name-given","text":"First Name","answer":[{"valueString":"Dani"}]},{"linkId":"PR-name-family","text":"Family Name","answer":[{"valueString":"Lee"}]}]},{"linkId":"PR-birthdate","text":"Date of Birth","answer":[{"valueDate":"1990-02-14"}]},{"linkId":"PR-id","text":"Identifying information","item":[{"linkId":"PR-name-id-url"},{"linkId":"PR-name-id","text":"Patient Id","answer":[{"valueString":"12345"}]}]}]}]}

6. 从 QuestionnaireResponse 中提取 FHIR 资源

初始项目随附的问卷调查适用于简单的患者登记流程,因此您最终可能希望使用问卷调查回答来创建 FHIR 患者资源。将问卷回答转换为 FHIR 资源的过程称为数据提取。我们可以使用结构化数据捕获库的 ResourceMapper 类来实现此目的。

如需执行数据提取,您必须在问卷中添加有关如何执行数据提取的信息。幸运的是,示例问卷已针对基于定义的提取进行了设置。

找到 submitQuestionnaire() 方法并添加以下代码:

lifecycleScope.launch {
  val questionnaire =
    jsonParser.parseResource(questionnaireJsonString) as Questionnaire
  val bundle = ResourceMapper.extract(questionnaire, questionnaireResponse)
  Log.d("extraction result", jsonParser.encodeResourceToString(bundle))
}

ResourceMapper.extract() 需要 HAPI FHIR 问卷,您可以通过解析之前的问卷 JSON 字符串来创建该问卷,还需要 QuestionnaireResponse,我们之前已经获取了该参数。它会返回一个包含一个或多个提取资源的 HAPI FHIR 事务 Bundle,在本例中是一个 Patient 资源。

再次运行应用,以使用最新更改重新构建应用。运行后,输入一些信息,然后点按提交。在日志中,您现在应该会看到一条消息 extraction result,其中包含提取的 FHIR Bundle 的 JSON 表示法。

D/extraction result: {"resourceType":"Bundle","type":"transaction","entry":[{"resource":{"resourceType":"Patient","identifier":[{"value":"12345"}],"name":[{"family":"Lee","given":["Dani"]}],"birthDate":"1990-02-14"}}]}

7. 恭喜!

您已使用结构化数据捕获库在应用中处理 FHIR 问卷和回答:

  • 显示调查问卷
  • 获取问卷回答
  • QuestionnaireResponse 中提取 FHIR 资源

它现在可以立即运行并使用了!

随着您不断深入,您可能会希望在整个应用中以更多方式使用 FHIR 资源。您可以查看 Android FHIR SDK 的 FHIR Engine 库,了解如何在应用中本地存储和管理 FHIR 资源,以及如何与远程 FHIR 服务器同步数据。

所学内容

  • 如何将结构化数据捕获库添加到 Android 应用
  • 如何使用 QuestionnaireFragmentResourceMapper 处理 FHIR 问卷

后续步骤

  • 探索结构化数据捕获库的文档
  • 自定义呈现的问卷的外观和风格
  • 在您自己的 Android 应用中应用 Structured Data Capture Library

了解详情