Git Product home page Git Product logo

google / android-fhir Goto Github PK

View Code? Open in Web Editor NEW
453.0 36.0 232.0 101.92 MB

The Android FHIR SDK is a set of Kotlin libraries for building offline-capable, mobile-first healthcare applications using the HL7® FHIR® standard on Android.

Home Page: https://google.github.io/android-fhir/

License: Apache License 2.0

Shell 0.19% Kotlin 99.78% Java 0.03%
android-fhir-sdk fhir fhir-client kotlin kotlin-android kotlin-library structured-data-capture sqlite sqlite-database sqlite-android

android-fhir's Introduction

Android FHIR SDK

master codecov License project chat

The Android FHIR SDK is a set of Kotlin libraries for building offline-capable, mobile-first healthcare applications using the HL7® FHIR® standard on Android. It aims to accelerate the adoption of FHIR by making it easy to incorporate FHIR into new and existing mobile applications.

Libraries

The SDK contains the following libraries:

Library Latest release Code Wiki Min SDK Summary
Data Capture Library Google Maven code wiki Android 7.0 (API level 24) Collect, validate, and process healthcare data on Android
FHIR Engine Library Google Maven code wiki Android 7.0 (API level 24) Store and manage FHIR resources locally on Android and synchronize with FHIR server
Workflow Library Google Maven code wiki Android 7.0 (API level 24) Provide decision support and analytics in clinical workflow on Android including implementation of specific FHIR operations ($measure_evaluate and $apply)

Demo apps

This repository also contains the following demo apps:

Demo app Code Wiki
FHIR Engine Demo App code wiki
Structured Data Capture Catalog App code wiki

These applications are provided for demo purposes only. Do NOT use in production.

Contributing

The development of the SDK began as a collaborative effort between Google, The World Health Organization, and Ona. Since then, a consortium of application developers have been contributing to the project.

To contribute to the project, please see Contributing to get started.

Feedback and getting help

You can create a GitHub issue for bugs and feature requests.

In case you find any security bug, please do NOT create a GitHub issue. Instead, email us at [email protected].

If you want to provide any feedback or discuss use cases you can:

Disclaimer

This product is not intended to be a medical device.

HL7®, and FHIR® are the registered trademarks of Health Level Seven International and their use of these trademarks does not constitute an endorsement by HL7.

android-fhir's People

Contributors

aditya-07 avatar ana2k avatar anchita-g avatar andati avatar deepankarb avatar dependabot[bot] avatar ekigamba avatar epicadk avatar fikrimilano avatar florina-muntenescu avatar jingtang10 avatar joiskash avatar kevinmost avatar ktarasenko avatar kunjan8794 avatar maanuanubhav999 avatar maimoonak avatar muhammadsalman-7214 avatar nsabale7 avatar omarismail94 avatar pallaviganorkar avatar pankajkatoch avatar pld avatar s-ayush2903 avatar santosh-pingle avatar shoaibmushtaq25 avatar vitorpamplona avatar vorburger avatar williamito avatar yigit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

android-fhir's Issues

Making Fhir engine a singleton per process per db name

Following discussions between @yigit @florina-muntenescu @jingtang10, we decided to make fhir engine a singleton per process + db name to avoid racing conditions when updating the db

  • Modify FhirEngine's API so that it's impossible to create another instance if there is already one (i.e. caching). At the moment in the referende app this is ensured by the initialization code in FhirApplication.kt using by lazy. But we want to be in the engine itself
  • Mark the inMemory() API as internal since we're only using it in tests and definitly don't want users to actually create in-memory db
  • Simplify the initialization code and remove the db name option (it's not used anywhere anyway)

Kotlin migration

We want to remove all java code in the codebase and move fully to kotlin.

Establish the API level

We need to establish the min API level for the SDK.

  1. testing on at least emulators to see if the sdk works on lower API levels
  2. document this in the README file

FHIR R4 Time Zone format requires Android API 24 or higher

The timezone format currently supported by FHIR Search, FHIRPath etc. currently is a subset of ISO8601:

yyyy-mm-ddThh:mm:ss[Z|(+|-)hh:mm]

In Android SimpleDateFormat shows 'X' pattern for ISO 8601 only be supported in API Level 24+ (Nougat+) only.

This is required for Sync implementation to work correctly. Otherwise in API 21 it throws exception java.lang.IllegalArgumentException: Unknown pattern character 'X' while using
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.US)

Related to Issue #110

Duplicated patients from syncing with the server

When syncing from the hapi test server, we use the id field from the patient object, it is of the form "baseurl/patient/id/history/historyid". What this means is that when there's a new version of patient we will treat it as a new (duplicated) patient in the db.

The fix is to use the actual patient id (which is a number on hapi test server) rather than the URL. In the hapi structures lib it's patient.getIdElement().getIdPart() (java).

swap auto-value w/ kotlin data class if we go w/ kotlin

we've not made the call yet but it would greatly simplify the code + ide experience.

the room PR already uses room but it is tiny so easy to move to java if we decide against kotlin.

lets keep the auto-value cleanup as a separate PR so that we can just revert.

HAPI FHIR structure lib cannot be used on Android SDK version 19 (kitkat)

See issue #49.

While running master on API level 19, there's this error:

05-15 12:09:05.044 3357-3357/com.google.fhirengine.example E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.google.fhirengine.example, PID: 3357
java.lang.VerifyError: org/apache/log4j/config/PropertySetter
at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:805)
at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:768)
at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:648)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:514)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:580)
at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:526)
at org.apache.log4j.LogManager.(LogManager.java:127)
at org.slf4j.impl.Log4jLoggerFactory.(Log4jLoggerFactory.java:66)
at org.slf4j.impl.StaticLoggerBinder.(StaticLoggerBinder.java:72)
at org.slf4j.impl.StaticLoggerBinder.(StaticLoggerBinder.java:45)
at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at ca.uhn.fhir.context.FhirContext.(FhirContext.java:80)
at com.google.fhirengine.resource.ResourceModule.getFhirContext(ResourceModule.java:29)
at com.google.fhirengine.resource.ResourceModule_GetFhirContextFactory.proxyGetFhirContext(ResourceModule_GetFhirContextFactory.java:27)
at com.google.fhirengine.DaggerFhirEngineComponent.getIParser(DaggerFhirEngineComponent.java:34)
at com.google.fhirengine.DaggerFhirEngineComponent.getDatabaseImpl(DaggerFhirEngineComponent.java:38)
at com.google.fhirengine.DaggerFhirEngineComponent.getFhirEngineImpl(DaggerFhirEngineComponent.java:62)
at com.google.fhirengine.DaggerFhirEngineComponent.getFhirEngine(DaggerFhirEngineComponent.java:75)
at com.google.fhirengine.example.MainActivity.onCreate(MainActivity.java:95)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)

which is an issue due to missing java libraries on Android which are used by HAPI FHIR.

Potentially investigate: https://stackoverflow.com/questions/30185857/apache-log4j-in-android-gives-exception-java-lang-verifyerror-org-apache-log4j

FHIR R4 Time Zone format requires Android API 24 or later

The timezone format currently supported by FHIR Search, FHIRPath etc. currently is a subset of ISO8601:

yyyy-mm-ddThh:mm:ss[Z|(+|-)hh:mm]

In Android SimpleDateFormat shows 'X' pattern for ISO 8601 only be supported in API Level 24+ (Nougat+) only.

This is required for Sync implementation to work correctly. Otherwise in API 21 it throws exception java.lang.IllegalArgumentException: Unknown pattern character 'X' while using
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.US)

Related to Issue #110

`Observation.effective` not available in Date Index

We need to implement mapping of Search Parameters to the underlying data type of the property. Currently, we are assuming the accessors are named getXXElement for date and getXX for all other SearchParamDefinition types. For example Patient.birthDate has getBirthDateElement(). However, this is not universally true in HAPI FHIR. E.g. Observation.effective does not have a getEffectiveElement method.

need to generate API files

we need some tool to generate the API files so that if API changes, we can track what has changed.

We use metalava in AndroidX but it is probably useless by itself. I can check what is used in dropbox/store and just copy that one probably.

move to room

what title says, lets replace the custom cursor implementation w/ room.

consider moving to instrumentation tests for android dependant stuff

robolectric runs tests on main thread which becomes a problem w/ room.

The official recommendation for Room is to actually test on a device since different SQLite versions on devices have different issues and we probably need to support really old devices.

Until then, we'll need to allow main thread queries in room. If we decide to keep it, we should at least make it a test only option.

Integration test out of memory for API 29

In recent github action runs for PRs, tests for API 29 consistently failed due to out of memory issue. e.g:

com.google.fhirengine.db.impl.DatabaseImplTest > select_invalidResourceType_shouldThrowIllegalArgumentException[test(AVD) - 10] FAILED
java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw an exception; no stack trace available

See trace: https://github.com/google/android-fhir/runs/824594488

Note this doesn't happen for API 24 or 27, nor does this happen locally.

Add indexing for missing types: URI, number, quantity, date

we have some entities (StringIndex, ReferenceIndex) that seem to have the same structure that is driven from a generic structure in FHIR engine.
it might make sense to merge them into one so that wen can add any type of index easily.

I'm not fully sure why it is this way right now so just keeping this issue as a note. we may or may not want to do this.

java.lang.NoSuchMethodError: No static method

When you try to launch MainActivity on master branch.

2020-07-28 12:30:33.190 8863-8863/com.google.fhirengine.example E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.google.fhirengine.example, PID: 8863
java.lang.NoSuchMethodError: No static method create(Lcom/google/fhirengine/db/Database;)Lcom/google/fhirengine/cql/FhirEngineDataProvider; in class Lcom/google/fhirengine/cql/FhirEngineDataProvider$Factory; or its super classes (declaration of 'com.google.fhirengine.cql.FhirEngineDataProvider$Factory' appears in /data/app/com.google.fhirengine.example-uoheiqp6VCcDKfyR9_GnEg==/base.apk!classes6.dex)
at com.google.fhirengine.FhirServices$Builder.build(FhirServices.kt:63)
at com.google.fhirengine.FhirEngineBuilder.build(FhirEngineBuilder.kt:50)
at com.google.fhirengine.example.FhirApplication.constructFhirEngine(FhirApplication.kt:46)
at com.google.fhirengine.example.FhirApplication.access$constructFhirEngine(FhirApplication.kt:33)
at com.google.fhirengine.example.FhirApplication$fhirEngine$2.invoke(FhirApplication.kt:36)
at com.google.fhirengine.example.FhirApplication$fhirEngine$2.invoke(FhirApplication.kt:33)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at com.google.fhirengine.example.FhirApplication.getFhirEngine(Unknown Source:2)
at com.google.fhirengine.example.FhirApplication.access$getFhirEngine$p(FhirApplication.kt:33)
at com.google.fhirengine.example.FhirApplication$Companion.fhirEngine(FhirApplication.kt:52)
at com.google.fhirengine.example.FhirApplication.fhirEngine(Unknown Source:2)
at com.google.fhirengine.example.MainActivity.onCreate(MainActivity.java:62)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

Rewrite existing Java code in Kotlin

This tasks is not top priority and would probably be the best if those who are not super familiar with Kotlin can contribute. Simply state what you're working on and send a PR and link it to this issue. Thanks all!

Update path splitting logic in FhirIndexerImpl

We index search parameters in FhirIndexerImpl.kt by type. We extract the object instances by splitting the path in the SearchParamDefinition and walking the Resource members depth-first. With splitting the path by dot notation, e.g. Observation.code.value we are missing out on Search params which do not conform to this pattern. E.g. SP_PHONE in Patient is Patient.telecom.where(system='phone').

We should try out the HAPI FHIR splitting logic:

@Override
	public String[] split(String thePaths) {
		if (getContext().getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.R4)) {
			if (!thePaths.contains("|")) {
				return new String[]{thePaths};
			}
			return SPLIT_R4.split(thePaths);
		} else {
			if (!thePaths.contains("|") && !thePaths.contains(" or ")) {
				return new String[]{thePaths};
			}
			return SPLIT.split(thePaths);
		}
	}

Sample App improvements to showcase local Fhir resources

  • Show search results for Observations referred by a given Patient
  • When no objects available from sync, import json bundle as local Fhir resources [Removed]
  • Use the sync button in the toolbar to actually sync results from external Fhir Resources
  • Remove dependence on CqlLoader for firing the sync.
  • Remove SamplePatients.kt if it's no longer needed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.