-
Notifications
You must be signed in to change notification settings - Fork 30
OptiBP Widget
This widget will launch the OptiBP app to read systolic and diastolic BP readings and then populate the results in the specified fields.
Field Attribute | Usage | Required |
---|---|---|
key | Unique of the field | yes |
type | Type of the field | yes |
label | OptiBP widget label | yes |
optibp_button_bg_color | Background color of the OptiBP launch button | no |
optibp_button_text_color | Text-color of the OptiBP launch button | no |
optibp_data | JSON object containing clientid and clientOpenSRPId | yes |
fields_to_use_value | Contains the keys of fields on which BP reading will be populated | yes |
relevance | Holds the rules to show/hide the specific field. This can use rules engine/ the line relevance | no |
calculations | Holds the link to the rules files that has a calculation that affects the field in question | no |
openmrs_entity_parent | Holds the concept id of the parent concept in OpenMRS | yes |
openmrs_entity | Holds the entity type on OpenMRS e.g Person , Address , Concept
|
yes |
openmrs_entity_id | Holds the concept id from OpenMRS | no |
The main class of optibpWidget is called OptiBPWidgetFactory
class in native-form library. If you are using the latest version of native form, this will come as a class in your module.
- JSON configuration. Below shows JSON configs you will need to get it working
{
"key": "record_bp_using_optibp_button",
"openmrs_entity_parent": "",
"openmrs_entity": "concept",
"openmrs_entity_id": "",
"type": "optibp",
"label": "{{anc_physical_exam.step2.record_bp_using_optibp_button.label}}",
"optibp_button_bg_color": "#EB5281",
"optibp_button_text_color": "#FFFFFF",
"read_only": false,
"optibp_data": {
"clientId": "",
"clientOpenSRPId": "",
"calibration": ""
},
"fields_to_use_value": [
"bp_systolic",
"bp_diastolic"
],
"relevance": {
"rules-engine": {
"ex-rules": {
"rules-file": "physical-exam-relevance-rules.yml"
}
}
}
},
optibp_data
--- This field should be populated programmatically before starting the form. It should contain the clientId
and clientOpenSRPId
JSON Object. FormUtils.createOptiBPDataObject(clientId, clientOpenSRPId)
utils method can be used which will return the required object.
fields_to_use_value
--- This field should contain a JSON Array of keys of the fields on which BP readings will be populated. The index 0 should have the key of systolic BP reading field and index 1 should have the diastolic BP reading field key.
"calculation": {
"rules-engine": {
"ex-rules": {
"rules-file": "sample-calculation-rules.yml"
}
}
}
The block above shows the rules engine relevance block.
"relevance": {
"rules-engine": {
"ex-rules": {
"rules-file": "sample-relevance-rules.yml"
}
}
}
The block above shows the rules engine relevance block.
- Class implementation and method. Since native form is form based, you will need to populate data to the key fields above in your application. For example in anc, below is a sample code that populates data to the key mentioned above
if (fieldObject.getString(JsonFormConstants.KEY).equals(ANCJsonFormConstants.KeyConstants.OPTIBP_BUTTON)
|| fieldObject.getString(JsonFormConstants.KEY).equals(ANCJsonFormConstants.KeyConstants.OPTIBP_BUTTON_SECOND)) {
if (fieldObject.has(JsonFormConstants.OptibpConstants.OPTIBP_KEY_DATA)) {
fieldObject.remove(JsonFormConstants.OptibpConstants.OPTIBP_KEY_DATA);
}
String optibpButtonKey = fieldObject.getString(JsonFormConstants.KEY).equals(ANCJsonFormConstants.KeyConstants.OPTIBP_BUTTON) ? ANCJsonFormConstants.KeyConstants.OPTIBP_BUTTON : ANCJsonFormConstants.KeyConstants.OPTIBP_BUTTON_SECOND;
String previousContactBpValue = getMapValue(optibpButtonKey) == null ? "" : getMapValue(optibpButtonKey);
JSONObject optiBPData = FormUtils.createOptiBPDataObject(baseEntityId, womanOpenSRPId, previousContactBpValue);
fieldObject.put(JsonFormConstants.OptibpConstants.OPTIBP_KEY_DATA, optiBPData);
}
- Dependencies The optibp widget depends on a third party application called Biospectal Optibp App. The two communication use intent communication to share data. Below is the sample code that communicates with Biospectal App. The app is launched with a click on a button shown below
Function launched
private Button initLaunchButton(LinearLayout rootLayout, final WidgetArgs widgetArgs, boolean readOnly, final int requestCode) throws JSONException {
final Context context = widgetArgs.getContext();
final JSONObject jsonObject = widgetArgs.getJsonObject();
Button launchButton = rootLayout.findViewById(R.id.optibp_launch_button);
formatButtonWidget(launchButton, widgetArgs.getJsonObject());
launchButton.setOnClickListener(view -> {
try {
Timber.w(" ONCLICK WITH JSON %s", jsonObject);
Intent intent = new Intent(OptibpConstants.OPTIBP_LAUNCH_INTENT);
intent.setType("text/json");
intent.putExtra(Intent.EXTRA_TEXT, getInputJsonString(context, jsonObject, widgetArgs));
((Activity) context).startActivityForResult(Intent.createChooser(intent, ""), requestCode);
} catch (Exception e) {
Timber.e(e);
}
});
if (readOnly) {
launchButton.setBackgroundDrawable(new ColorDrawable(widgetArgs.getContext().getResources()
.getColor(android.R.color.darker_gray)));
launchButton.setClickable(false);
launchButton.setEnabled(false);
launchButton.setFocusable(false);
}
return launchButton;
}
Results are read by the function below
public void setUpOptiBpActivityResultListener(final WidgetArgs widgetArgs, int requestCode, final LinearLayout rootLayout, EditText systolicEditText, final EditText diastolicEditText) {
final Context context = widgetArgs.getContext();
if (context instanceof JsonApi) {
final JsonApi jsonApi = (JsonApi) context;
jsonApi.addOnActivityResultListener(requestCode, (finalRequestCode, resultCode, data) -> {
if (resultCode == Activity.RESULT_OK) {
if (finalRequestCode == OptibpConstants.OPTIBP_REQUEST_CODE ||
finalRequestCode == OptibpConstants.OPTIBP_REPEAT_REQUEST_CODE) {
try {
if (data != null) {
String resultJson = data.getStringExtra(Intent.EXTRA_TEXT);
Timber.d("Resultant OptiBP JSON: %s ", resultJson);
populateBPEditTextValues(resultJson, systolicEditText, diastolicEditText, widgetArgs);
String resultString = getValueString(resultJson);
if (StringUtils.isNotBlank(resultString)) {
writeResult(jsonApi, rootLayout, resultString, widgetArgs);
} else {
Timber.e("JSON Result %s , Result String %s", resultJson, resultString);
Toast.makeText(context, context.getString(R.string.invalid_optibp_data), Toast.LENGTH_SHORT).show();
}
} else
Timber.e("NO RESULT FROM OPTIBP APP finalRequestCode %s, resultCode %s", finalRequestCode, resultCode);
} catch (Exception e) {
Timber.e(e);
}
}
} else {
Timber.e("final Request code: %s, ResultCode : %s , Data from OptiBP: %s ", finalRequestCode, resultCode, data);
Toast.makeText(context, context.getString(R.string.optibp_unable_to_receive), Toast.LENGTH_SHORT).show();
}
});
}
}
Forked from Android Native JSON Form Library. Adapted in love by the OpenSRP Community . Apache License, Version 2.0
Introduction
Core Features
Form
Views