Android Capture and SMS

hi @jaime.bosque and @Jaime -

I’m wondering if there is a feature that I have misunderstood or am not aware of. Is it possible to collect data via the Android Capture app and transmit it via SMS? That would require the Android app to read the configured parsers, parse and transform the locally stored data, and transmit it via SMS via the gateway to DHIS2.

The use case is a large implementation using the Android app, but in some remote location there is only reliable sms, not cellular data.

Please let me know if I need to clarify my question or add more detail.

Edit: I think I’ve found what I was looking for in SMS Sync, however, I cannot find the up to date link in Github to review it’s current state. I’ve only found this deprecated document. SMS Sync (deprecated) - Google Docs

Getting closer…SMS module - DHIS2 Documentation

2 Likes

Hi @chase.freeman

Thanks for your question. Please note that some documentation very technical might be placed here: Overview | DHIS2 Developer Portal which is where you could find the documents you were looking for. Unfortunately we migrated this a while ago and didn’t update that page (just request the update), in any case, the final documents can still by found (RAW) here: dhis2-android-docs/content/tech-guides at main · dhis2/dhis2-android-docs · GitHub

Now, answering your question. Android Capture App supports transmitting data (aggregate and tracker) via SMS and this is transparent to the App and would be proposed as a sync method when no wireless or data is available and a SIM/telephone services exist. When I am saying this is transparent I mean it, as the App will rely on your server (or middleware) to take care of an possible SMS scrambling/reassembling etc which might be needed depending on your SMS provider and if you are transmitting information that requires more than one SMS (usual case with tracker data).

You will need an SMS gateway, this gateway is what you will usually get from providers like clickatel, bulksms, etc and which sends an API call to your DHIS2 server. If your SMS are not arriving properly you will need this gateway to reassamble/reoder/recode (which some providers will allow you to do, or you might need to code some functions -i.e in a serverless implementation-). This is what the guide: dhis2-android-docs/SMS-Sync.md at main · dhis2/dhis2-android-docs · GitHub aims to explain and even provide functions that you could try.

A while ago I heavily tested something similar: https://docs.google.com/document/d/1zL9zlVXyMaWCCQ5u2hDAAWV1b7I8lNJOtCGVTAVioMU/edit# and you might find that doc interesting. Please note that in order to have all this SMS working you will be heavily dependant on how SMS are treated at server provider, in the example above, we found out that the provider was performing a character translation and this might vary from country to country.

Good luck and let us know if you need more help. Either @Jaime or @zubair can probably help as well.

1 Like

Thanks @jaime.bosque - overall your information is good news and I understand. I will review the docs today.

Some initial thoughts/questions (Sorry if they are in the docs, I want to ask before I forget):

Does the sync send a single dataValueSet (per OU/period,etc) per message and does it send a single event or tei? That would seem pretty specific and inefficient when dealing with messaging rates.

My guess is that it sends a ALL dataValues and ALL events & TEIs since the last sync which is why it needs to be handled with middleware.

I think a serverless approach will be really helpful in this case.

The gateway is the part I understand well at this point and using the right platform will help transmit to the “unscrambling” serverless middleware. We’re thinking telerivet at this point but I will look at others, too. Their platform offers many services and it is easy to test, debug, etc.

Do you or anyone on your team have an example payload of a sync that gets split? It would really help me in architecting the solution before getting into testing an approach.

Thanks again for all your help.

Hi @chase.freeman .

AFAIK the App uses a compression library (GitHub - dhis2/sms-compression: DHIS2 sms compression library) in order to reduce as much as possible the SMS being sent. @Jasper_Timm, @jaime.bosque and @zubair can probably confirm what I am saying. But I think all the efforts were already made there and there is nothing to be done.

Regarding the examples I cannot give you much because I did some tests and did not suffer from it (because I was using a European carrier and Android SMS app recomposed the emails properly using the information coming from the metadata). This is pretty much the tricky part and it might not be straight forward if the telephony company does something awkward with the messages or the tagging. If I recall correctly, @Calle_Hedberg suffered from some providers not sending the metadata information (so messages could not be recompose easily) and a translation of specific characters in the SMS.

What I want to say with the last part is that it is going to be very likely dependent on your phone provider, and even if you go to country X, it might vary if you use provider A or B.

Let us know how this goes and/or if you need further help. I would be very interesting in learning of a big use case where SMS syncing is being used.

Thanks @jaime.bosque that is valuable information. I am hoping to implement with a global provider that will hopefully re-compose the SMS into the correct order like you describe. I think the small premium it costs to use them will offset the development, maintenance, and troubleshooting a custom “re-configuration” of the SMS :smile:

:crossed_fingers: With a little luck I’ll report back with good news in a few weeks.

1 Like

I am using the “two device” approach to this in order to get a proof of concept working. I have Tablet A using DHIS2 Android Capture and Tablet B with the DHIS2 SMS Gateway (configured to point at my target server).

@jaime.bosque - two things I’m having trouble with when getting started testing on this:

  1. How do I configure the SMS gateway in DHIS2 to work with the Android gateway app? Is there documentation on the configuration template, etc?
    2.) How do I enable the “Sync SMS” button on the android settings menu (on the device). I’m using 2.6.

Hi @chase.freeman .

  1. AFAIK the DHIS2 Android SMS Gateway can only be used in one direction (@Jaime , can you confirm that?) so it means that there is no need to set up the gateway on DHIS2 server as confirmation messages will not be delivered.
  2. SMS is always used as last resource in the Android App. This means that by disabling any other connection (WiFi, Mobile Data) the Android will detect there is no connectivity and attempt to sync via SMS. Please, remember that for this the SMS Gateway number needs to be set up in the App, either manually under configuration or centrally via the Android Settings Web App.

Please, let us know once you finish your proof of concept (or write a post in the CoP about it if you don’t mind) so we are aware of real use cases of SMS. :slight_smile:

2 Likes

@jaime.bosque and @Jaime - I’m stuck on this because I can’t find how to enable the “SMS Settings” in the Android app :man_shrugging:. Specifically - how to "enable SMS submission For example see the bottom of the image here: dhis2-android-docs/android-sms-settings.png at main · dhis2/dhis2-android-docs · GitHub

All the generic documentation has broken links and when I navigate to the sections manually there is very little helpful information that continues to point me to the SMS configuration app. However, the SMS config app doesn’t seem to apply to SMS sync…

Do I need to configure one of the parsers for SMS sync from Android to function? I am using the DHIS2 gateway app on a secondary device and have used android settings to use the phone number of that device.

I have also turned off WIFI and mobile data/Internet usage on my devices after syncing thinking that maybe that would bring up the SMS settings … it did not.

Any guidance on how I can access these settings would be much appreciated. I assume the Android Settings Web App would be the central location to configure these options but I do not have the options available that are in the screenshot (from docs) I linked above. All I can do is specify “SMS Gateway phone number” in the “General” section of the android settings.

Hahah – I figured it out. There is a separate APK! I remember reading about some issues with the Play Store and verification of the APK with SMS capabilities.

I’m going to leave all my comments above in case anyone searches for similar questions. :grin:

I’m sure I’ll be in touch again soon…

1 Like

Ok - I’m back with an error after initiating the SMS sync as can be seen in the attached screenshot.
I’m new to troubleshooting the Android app. What is the best way to inspect these types of errors more in depth? Do I need to setup Android Studio and debug (Is Debugging enabled?)? Are there other tools your team uses?

I disabled wifi and mobile data on this device so I know the server logs won’t show anything. The DHIS2 Sync Logs under settings do not seem to show anything either (though I do have some metadata issues for some reason – FK Missing OrganisationUnit <UID> from CategoryOptionOrganisationUnitLink)

Answered my own question again after a bit of digging

How to debug android app: Debugging - DHIS2 Documentation

@jaime.bosque is “Flipper” still the recommended Debugging platform other than android studio? Is it worth setting up?

I’m going to keep this thread going for others (or myself) in the future.

Is there anyone available to speak with on a call about how to setup Flipper to debug the APK or must I modify the source code and build from scratch? I see that some flipper dependencies are included in the build.gradle but then the other required steps (creating the new class) as outlined in the docs are not.

I have got my device setup for debugging/logs using android studio using the training APK. Regarding config error I received above, the larger error log is below and appears independently of the SMS Module’s actions

2022-06-02 11:00:49.606 4545-12679/com.dhis2.debug W/ForeignKeyCleanerImpl: An object was not persisted on CategoryOptionOrganisationUnitLink table to avoid Foreign Key constraint error. Target not found on OrganisationUnit table. ForeignKeyViolation{id=null, fromTable=CategoryOptionOrganisationUnitLink, fromColumn=organisationUnit, toTable=OrganisationUnit, toColumn=uid, notFoundValue=UPaS3CI2FD2, fromObjectUid=null, fromObjectRow=_id: 110492, categoryOption: tD9zq8aECNp, organisationUnit: UPaS3CI2FD2, restriction: RESTRICTED, created=Thu Jun 02 11:00:49 EDT 2022}

The error I received when syncing tracker data via sms sync on my server as well as Play 2.37 is (I’ll report to Jira with steps to reproduce):
2022-06-02 11:09:00.462 4545-17092/com.dhis2.debug E/SmsSendingService: java.lang.Exception: This convertTask is not supported
at org.dhis2.utils.granularsync.GranularSyncPresenterImpl.initSMSSync(GranularSyncPresenterImpl.kt:242)
at org.dhis2.utils.granularsync.SyncStatusDialog.syncSMS(SyncStatusDialog.kt:392)
at org.dhis2.utils.granularsync.SyncStatusDialog.onRequestPermissionsResult(SyncStatusDialog.kt:623)
at androidx.fragment.app.FragmentManager$11.onActivityResult(FragmentManager.java:2967)
at androidx.fragment.app.FragmentManager$11.onActivityResult(FragmentManager.java:2939)
at androidx.activity.result.ActivityResultRegistry.doDispatch(ActivityResultRegistry.java:392)
at androidx.activity.result.ActivityResultRegistry.dispatchResult(ActivityResultRegistry.java:351)
at androidx.activity.ComponentActivity.onRequestPermissionsResult(ComponentActivity.java:658)
at androidx.fragment.app.FragmentActivity.onRequestPermissionsResult(FragmentActivity.java:636)
at org.dhis2.usescases.general.ActivityGlobalAbstract.onRequestPermissionsResult(ActivityGlobalAbstract.java:203)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:8733)
at android.app.Activity.dispatchActivityResult(Activity.java:8554)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5583)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5631)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
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:2336)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8653)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

@jaime.bosque - can someone on your team help to verify the issue?: Log in - DHIS 2 JIRA

I don’t know how to proceed from here.

Hi @chase.freeman . I usually use Flipper to inspect both the logs and the network calls. As SMS is not network I am not sure it is going to be there but I am going to check.

I could be available for a short call if you need. Although I think our timezones differ. Please PM to see if we can coordinate.

(I will also be replying to other questions here as soon as I can, but wanted to send this first in case we can coordinate quicker).

Thanks for the feedback @jaime.bosque - I have other needs to get Flipper setup beyond the SMS config – The Android Capture app is growing in use and I need to have troubleshooting tools available to assist clients. I’ll send you a PM.

Hi @chase.freeman . Indeed there seems to be an error with the App, I wrote that on Friday on JIRA but forgot to mention here… I hope you got the notification in any case. I/we will be following up there as from now on :slight_smile:

@chase.freeman I never had time to respond above due to being snowed under, but I would really like to have a chat with you about what you have done/discovered when looking into this SMS channel. My colleagues in Sierra Leone keeps on telling me they cannot make it work, but their arguments / line of reasoning do not make sense to me. So I would really like to know if you made it work, and if so HOW you have set it up (and I am also very interested in whether you have discovered any hard limits to the size of any data set or tracker/event program using the SMS channel)

1 Like

@Jaime & @jaime.bosque

I’ve got the connection working from the Android device (A) sending the SMS to the Gateway on another device (B) which has both SMS and Wifi enabled. It is working, I get an encoded SMS on device B each time I sync a TEI’s record on device A.

However, the transmission breaks down somewhere along the way as the data never reaches the server. To me, it is apparent that is with the gateway on Device B. I confirmed credentials and that it is connected via Wifi. I’ve confirmed I’m receiving an SMS on the device. However, I’m not seeing anything in the Logs section of the app nor is there anything else that could obviously be helpful.

My main concern is the “listening” URL. I assume it is using my devices IPv6 address based on the format but then it has %dummy0:8000 where I assume it is trying to use port 8000 and “dummy” should be an actual value.

Am I missing something here?