Showing
10 changed files
with
390 additions
and
1 deletions
| ... | @@ -92,8 +92,12 @@ android { | ... | @@ -92,8 +92,12 @@ android { |
| 92 | 92 | ||
| 93 | packagingOptions { | 93 | packagingOptions { |
| 94 | //exclude 'lib/armeabi-v7a/libc++_shared.so' // 过滤该文件 | 94 | //exclude 'lib/armeabi-v7a/libc++_shared.so' // 过滤该文件 |
| 95 | + exclude 'META-INF/DEPENDENCIES' | ||
| 96 | + exclude 'META-INF/LICENSE' | ||
| 97 | + exclude 'META-INF/LICENSE.txt' | ||
| 98 | + exclude 'META-INF/NOTICE' | ||
| 99 | + exclude 'META-INF/NOTICE.txt' | ||
| 95 | } | 100 | } |
| 96 | - | ||
| 97 | } | 101 | } |
| 98 | 102 | ||
| 99 | String getDate() { | 103 | String getDate() { |
| ... | @@ -148,4 +152,7 @@ dependencies { | ... | @@ -148,4 +152,7 @@ dependencies { |
| 148 | compileOnly files('syslibs/framework.jar') | 152 | compileOnly files('syslibs/framework.jar') |
| 149 | 153 | ||
| 150 | // implementation("com.google.android.fhir:engine:1.0.0") | 154 | // implementation("com.google.android.fhir:engine:1.0.0") |
| 155 | +// implementation 'ca.uhn.hapi.fhir:hapi-fhir-structures-dstu3:5.4.0' | ||
| 156 | + implementation 'ca.uhn.hapi.fhir:hapi-fhir-android:5.5.1' | ||
| 157 | + implementation 'ca.uhn.hapi.fhir:hapi-fhir-structures-r4:5.5.1' | ||
| 151 | } | 158 | } | ... | ... |
| 1 | +package com.sw.laryngoscope.model; | ||
| 2 | + | ||
| 3 | +public class PatientAddressModel { | ||
| 4 | + private String city; | ||
| 5 | + private String state; | ||
| 6 | + private String country; | ||
| 7 | + | ||
| 8 | + public PatientAddressModel(String city,String state,String country){ | ||
| 9 | + this.city = city; | ||
| 10 | + this.state = state; | ||
| 11 | + this.country = country; | ||
| 12 | + } | ||
| 13 | + | ||
| 14 | + public String getFullAddress(){ | ||
| 15 | + return city + " City" + "\n" + state + "," + country; | ||
| 16 | + } | ||
| 17 | +} |
| 1 | +package com.sw.laryngoscope.model; | ||
| 2 | + | ||
| 3 | +import android.text.format.DateFormat; | ||
| 4 | + | ||
| 5 | +import com.sw.laryngoscope.model.observation.BloodPressureObservationModel; | ||
| 6 | +import com.sw.laryngoscope.model.observation.ObservationModel; | ||
| 7 | +import com.sw.laryngoscope.model.observation.ObservationType; | ||
| 8 | + | ||
| 9 | +import org.hl7.fhir.r4.model.Enumerations; | ||
| 10 | + | ||
| 11 | +import java.util.ArrayList; | ||
| 12 | +import java.util.Date; | ||
| 13 | +import java.util.HashMap; | ||
| 14 | + | ||
| 15 | +public class PatientModel { | ||
| 16 | + private String patientID; | ||
| 17 | + private String name; | ||
| 18 | + private Date birthDate; | ||
| 19 | + private Enumerations.AdministrativeGender gender; | ||
| 20 | + private PatientAddressModel address; | ||
| 21 | + | ||
| 22 | + private HashMap<ObservationType, ObservationModel> observationReadings; | ||
| 23 | + private HashMap<ObservationType, Boolean> isMonitored; | ||
| 24 | + private ArrayList<BloodPressureObservationModel> latestBPReadings; | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * Constructor | ||
| 28 | + * @param patientID Unique patient ID from the FHIR server | ||
| 29 | + * @param name name of the patient | ||
| 30 | + */ | ||
| 31 | + public PatientModel(String patientID, String name, Date birthDate, Enumerations.AdministrativeGender gender, PatientAddressModel address) { | ||
| 32 | + this.patientID = patientID; | ||
| 33 | + this.name = name; | ||
| 34 | + this.birthDate = birthDate; | ||
| 35 | + this.gender = gender; | ||
| 36 | + this.address = address; | ||
| 37 | + observationReadings = new HashMap<>(); | ||
| 38 | + isMonitored = new HashMap<>(); | ||
| 39 | + latestBPReadings = new ArrayList<>(); | ||
| 40 | + initialiseMonitoredObservations(); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + public String getPatientID() { | ||
| 44 | + return patientID; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + public String getName() { | ||
| 48 | + return name; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + public String getBirthDate() { | ||
| 52 | + return DateFormat.format("yyyy.MM.dd", birthDate).toString(); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + public String getGender() { | ||
| 56 | + return gender.toString(); | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + public PatientAddressModel getAddress() { | ||
| 60 | + return address; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + public void setObservation(ObservationType type, ObservationModel observation) { | ||
| 64 | + observationReadings.put(type, observation); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + public ObservationModel getObservationReading(ObservationType type) { | ||
| 68 | + return observationReadings.get(type); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + public void monitorObservation(ObservationType type, Boolean check) { | ||
| 72 | + isMonitored.put(type, check); | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + public Boolean isObservationMonitored(ObservationType type) { | ||
| 76 | + return isMonitored.get(type); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + private void initialiseMonitoredObservations() { | ||
| 80 | + for (ObservationType type: ObservationType.values()) { | ||
| 81 | + monitorObservation(type, false); | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + public void addLatestBPReadings(ArrayList<BloodPressureObservationModel> readings) { | ||
| 86 | + latestBPReadings = readings; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + public ArrayList<BloodPressureObservationModel> getLatestBPReadings() { | ||
| 90 | + return latestBPReadings; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | +} |
app/src/main/java/com/sw/laryngoscope/model/observation/BloodPressureObservationModel.java
0 → 100644
| 1 | +package com.sw.laryngoscope.model.observation; | ||
| 2 | + | ||
| 3 | +import org.hl7.fhir.r4.model.Observation; | ||
| 4 | + | ||
| 5 | +public class BloodPressureObservationModel extends ObservationModel{ | ||
| 6 | + public BloodPressureObservationModel(Observation observation) { | ||
| 7 | + super(observation); | ||
| 8 | + } | ||
| 9 | + | ||
| 10 | + @Override | ||
| 11 | + public String getValue() { | ||
| 12 | + return observation.getValueQuantity().getValue().toString(); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + public String getSystolic() { return observation.getComponent().get(1).getValueQuantity().getValue().toString(); } | ||
| 16 | + | ||
| 17 | + public String getDiastolic() { return observation.getComponent().get(0).getValueQuantity().getValue().toString(); } | ||
| 18 | + | ||
| 19 | + @Override | ||
| 20 | + public String getUnit() { | ||
| 21 | + return observation.getComponent().get(0).getValueQuantity().getUnit(); | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public String getDateTime() { return observation.getEffectiveDateTimeType().asStringValue(); } | ||
| 26 | +} |
| 1 | +package com.sw.laryngoscope.model.observation; | ||
| 2 | + | ||
| 3 | +import org.hl7.fhir.r4.model.Observation; | ||
| 4 | + | ||
| 5 | +public class CholesterolObservationModel extends ObservationModel{ | ||
| 6 | + public CholesterolObservationModel(Observation observation) { | ||
| 7 | + super(observation); | ||
| 8 | + } | ||
| 9 | + | ||
| 10 | + @Override | ||
| 11 | + public String getValue() { | ||
| 12 | + return observation.getValueQuantity().getValue().toString(); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + @Override | ||
| 16 | + public String getUnit() { | ||
| 17 | + return observation.getValueQuantity().getUnit(); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + @Override | ||
| 21 | + public String getDateTime() { return observation.getEffectiveDateTimeType().asStringValue(); } | ||
| 22 | +} |
| 1 | +package com.sw.laryngoscope.model.observation; | ||
| 2 | + | ||
| 3 | +import org.hl7.fhir.r4.model.Observation; | ||
| 4 | + | ||
| 5 | +public class ObservationModel { | ||
| 6 | + protected Observation observation; | ||
| 7 | + | ||
| 8 | + ObservationModel(Observation observation) { | ||
| 9 | + this.observation = observation; | ||
| 10 | + } | ||
| 11 | + | ||
| 12 | + /** | ||
| 13 | + * Return the Observation value | ||
| 14 | + * @return double | ||
| 15 | + */ | ||
| 16 | + public abstract String getValue(); | ||
| 17 | + | ||
| 18 | + /** | ||
| 19 | + * Get the unit type for the Observation | ||
| 20 | + */ | ||
| 21 | + public abstract String getUnit(); | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * Get the effective DateTime | ||
| 25 | + * @return effective date time | ||
| 26 | + */ | ||
| 27 | + public abstract String getDateTime(); | ||
| 28 | +} |
| 1 | +package com.sw.laryngoscope.model.observation; | ||
| 2 | + | ||
| 3 | +public enum ObservationType { | ||
| 4 | + CHOLESTEROL, BLOOD_PRESSURE; | ||
| 5 | + private String observationCode; | ||
| 6 | + | ||
| 7 | + static { | ||
| 8 | + CHOLESTEROL.observationCode = "2093-3"; | ||
| 9 | + BLOOD_PRESSURE.observationCode = "55284-4"; | ||
| 10 | + } | ||
| 11 | + | ||
| 12 | + public String getObservationCode() { | ||
| 13 | + return observationCode; | ||
| 14 | + } | ||
| 15 | +} |
| 1 | +package com.sw.laryngoscope.service; | ||
| 2 | + | ||
| 3 | +import ca.uhn.fhir.context.FhirContext; | ||
| 4 | +import ca.uhn.fhir.rest.client.api.IGenericClient; | ||
| 5 | + | ||
| 6 | +public class FhirService { | ||
| 7 | + protected IGenericClient client; | ||
| 8 | + | ||
| 9 | + public FhirService(){ | ||
| 10 | + FhirContext ctx = FhirContext.forR4(); | ||
| 11 | + | ||
| 12 | + //Server url | ||
| 13 | + String BASE_URL = "https://hapi.fhir.org/" + "baseR4"; | ||
| 14 | + client = ctx.newRestfulGenericClient(BASE_URL); | ||
| 15 | + // increase timeout | ||
| 16 | + ctx.getRestfulClientFactory().setConnectTimeout(60*1000); | ||
| 17 | + ctx.getRestfulClientFactory().setSocketTimeout(60*1000); | ||
| 18 | + | ||
| 19 | + } | ||
| 20 | +} |
app/src/main/java/com/sw/laryngoscope/service/repository/ObservationRepositoryFactory.java
0 → 100644
| 1 | +package com.sw.laryngoscope.service.repository; | ||
| 2 | + | ||
| 3 | +import com.sw.laryngoscope.model.observation.BloodPressureObservationModel; | ||
| 4 | +import com.sw.laryngoscope.model.observation.CholesterolObservationModel; | ||
| 5 | +import com.sw.laryngoscope.model.observation.ObservationModel; | ||
| 6 | +import com.sw.laryngoscope.model.observation.ObservationType; | ||
| 7 | +import com.sw.laryngoscope.service.FhirService; | ||
| 8 | + | ||
| 9 | +import org.hl7.fhir.r4.model.Bundle; | ||
| 10 | +import org.hl7.fhir.r4.model.Observation; | ||
| 11 | + | ||
| 12 | +import java.util.ArrayList; | ||
| 13 | + | ||
| 14 | +import ca.uhn.fhir.rest.client.api.IGenericClient; | ||
| 15 | + | ||
| 16 | +public class ObservationRepositoryFactory extends FhirService { | ||
| 17 | + private IGenericClient client = super.client; | ||
| 18 | + | ||
| 19 | + private Observation getObservation(String patientId,String code){ | ||
| 20 | + Bundle bundle = client.search() | ||
| 21 | + .forResource(Observation.class) | ||
| 22 | + .where(Observation.PATIENT.hasId(patientId)) | ||
| 23 | + .and(Observation.CODE.exactly().code(code)) | ||
| 24 | + .sort().descending(Observation.DATE) | ||
| 25 | + .returnBundle(Bundle.class) | ||
| 26 | + .execute(); | ||
| 27 | + | ||
| 28 | + return (Observation) (bundle.getEntry().get(0).getResource()); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public ObservationModel getObservationModel(String patientId, ObservationType type){ | ||
| 32 | + switch (type){ | ||
| 33 | + case CHOLESTEROL: | ||
| 34 | + return createCholesterolModel(patientId); | ||
| 35 | + case BLOOD_PRESSURE: | ||
| 36 | + return createBloodPressureModel(patientId); | ||
| 37 | + default: | ||
| 38 | + throw new IllegalArgumentException("Observation type invalid"); | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + private CholesterolObservationModel createCholesterolModel(String patientId){ | ||
| 43 | + return new CholesterolObservationModel(getObservation(patientId, ObservationType.CHOLESTEROL.getObservationCode())); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + private BloodPressureObservationModel createBloodPressureModel(String patientId) { | ||
| 47 | + return new BloodPressureObservationModel(getObservation(patientId, ObservationType.BLOOD_PRESSURE.getObservationCode())); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * Returns an ArrayList of n latest readings | ||
| 52 | + * @param patientId patient id | ||
| 53 | + * @param code observation code | ||
| 54 | + * @param n latest n readings | ||
| 55 | + * @return ArrayList of readings | ||
| 56 | + */ | ||
| 57 | + private ArrayList<Observation> getLatestObservationReadings(String patientId, String code, int n) { | ||
| 58 | + ArrayList<Observation> latestReadings = new ArrayList<>(); | ||
| 59 | + Bundle bundle = client.search() | ||
| 60 | + .forResource(Observation.class) | ||
| 61 | + .where(Observation.PATIENT.hasId(patientId)) | ||
| 62 | + .and(Observation.CODE.exactly().code(code)) | ||
| 63 | + .sort().descending(Observation.DATE) | ||
| 64 | + .returnBundle(Bundle.class) | ||
| 65 | + .execute(); | ||
| 66 | + | ||
| 67 | + for (int i = 0; i < Math.min(n, bundle.getTotal()); i++) { | ||
| 68 | + latestReadings.add((Observation) (bundle.getEntry().get(i)).getResource()); | ||
| 69 | + } | ||
| 70 | + return latestReadings; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + public ArrayList<BloodPressureObservationModel> getLatestBloodPressureReadings(String patientId, int n) { | ||
| 74 | + ArrayList<BloodPressureObservationModel> bpReadings = new ArrayList<>(); | ||
| 75 | + for (Observation observation: getLatestObservationReadings(patientId, ObservationType.BLOOD_PRESSURE.getObservationCode(), n)) { | ||
| 76 | + bpReadings.add(new BloodPressureObservationModel(observation)); | ||
| 77 | + } | ||
| 78 | + return bpReadings; | ||
| 79 | + } | ||
| 80 | +} |
| 1 | +package com.sw.laryngoscope.service.repository; | ||
| 2 | + | ||
| 3 | +import com.sw.laryngoscope.model.PatientAddressModel; | ||
| 4 | +import com.sw.laryngoscope.model.PatientModel; | ||
| 5 | +import com.sw.laryngoscope.service.FhirService; | ||
| 6 | + | ||
| 7 | +import org.hl7.fhir.r4.model.Bundle; | ||
| 8 | +import org.hl7.fhir.r4.model.Encounter; | ||
| 9 | +import org.hl7.fhir.r4.model.Enumerations; | ||
| 10 | +import org.hl7.fhir.r4.model.HumanName; | ||
| 11 | +import org.hl7.fhir.r4.model.Patient; | ||
| 12 | + | ||
| 13 | +import java.util.ArrayList; | ||
| 14 | +import java.util.Date; | ||
| 15 | + | ||
| 16 | +import ca.uhn.fhir.rest.client.api.IGenericClient; | ||
| 17 | +import ca.uhn.fhir.rest.gclient.TokenClientParam; | ||
| 18 | + | ||
| 19 | +public class PatientRepository extends FhirService { | ||
| 20 | + private String practitionerId; | ||
| 21 | + private IGenericClient client = super.client; | ||
| 22 | + | ||
| 23 | + public PatientRepository(String practitionerId) { | ||
| 24 | + this.practitionerId = practitionerId; | ||
| 25 | + } | ||
| 26 | + /** | ||
| 27 | + * Get all patients treated by the practitioner | ||
| 28 | + * @return ArrayList of patients | ||
| 29 | + */ | ||
| 30 | + public ArrayList<PatientModel> getAllPatients() { | ||
| 31 | + // store patient references | ||
| 32 | + ArrayList<String> patientReferences = new ArrayList<>(); | ||
| 33 | + // store patients | ||
| 34 | + ArrayList<PatientModel> patientModels = new ArrayList<>(); | ||
| 35 | + | ||
| 36 | + // search for all encounters with the practitioner identifier | ||
| 37 | + Bundle bundle = client.search().forResource(Encounter.class) | ||
| 38 | + .where(new TokenClientParam("participant.identifier") | ||
| 39 | + .exactly().systemAndCode("http://hl7.org/fhir/sid/us-npi", practitionerId)) | ||
| 40 | + .returnBundle(Bundle.class) | ||
| 41 | + .count(100) // not too many searches to prevent overloading the server | ||
| 42 | + .execute(); | ||
| 43 | + | ||
| 44 | + // get all patient references | ||
| 45 | + bundle.getEntry().forEach((entry) -> patientReferences.add( | ||
| 46 | + (((Encounter) entry.getResource()).getSubject()).getReference())); | ||
| 47 | + | ||
| 48 | + Bundle patientBundle; | ||
| 49 | + | ||
| 50 | + // go through each patient reference and get the patient | ||
| 51 | + for (String id: patientReferences) { | ||
| 52 | + patientBundle = client.search() | ||
| 53 | + .forResource(Patient.class) | ||
| 54 | + .where(Patient.RES_ID.exactly().identifier(id)) | ||
| 55 | + .returnBundle(Bundle.class) | ||
| 56 | + .execute(); | ||
| 57 | + | ||
| 58 | + Patient patient = (Patient) (patientBundle.getEntry().get(0)).getResource(); | ||
| 59 | + | ||
| 60 | + // human name documentation: https://www.hl7.org/fhir/DSTU2/datatypes-definitions.html#HumanName | ||
| 61 | + HumanName humanName = patient.getName().get(0); | ||
| 62 | + // prefix ie. Mr/ Mrs, given name ie. first & middle names, family ie. surname | ||
| 63 | + String patientName = humanName.getPrefixAsSingleString() + " " | ||
| 64 | + + humanName.getGivenAsSingleString() + " " + humanName.getFamily(); | ||
| 65 | + | ||
| 66 | + // get birth date | ||
| 67 | + Date birthDate = patient.getBirthDate(); | ||
| 68 | + | ||
| 69 | + // get gender | ||
| 70 | + Enumerations.AdministrativeGender gender = patient.getGender(); | ||
| 71 | + | ||
| 72 | + // get address | ||
| 73 | + PatientAddressModel patientAddress = new PatientAddressModel(patient.getAddress().get(0).getCity(), | ||
| 74 | + patient.getAddress().get(0).getState(), patient.getAddress().get(0).getCountry()); | ||
| 75 | + | ||
| 76 | + patientModels.add(new PatientModel(id, patientName, birthDate, gender, patientAddress)); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + return patientModels; | ||
| 80 | + } | ||
| 81 | +} |
-
Please register or login to post a comment