diff --git a/content/en/apps/features/integrations/android.md b/content/en/apps/features/integrations/android.md index 84aa8bf43..d80693c37 100644 --- a/content/en/apps/features/integrations/android.md +++ b/content/en/apps/features/integrations/android.md @@ -5,17 +5,19 @@ description: > Launch the Android App with a link or from another app relatedContent: > apps/reference/app-settings/token_login + apps/reference/app-settings/assetlinks --- The [CHT Android application](https://github.com/medic/cht-android) can be launched by clicking on a link or invoking an intent in another Android app. This is useful for enabling login by SMS, directing a user to a specific page, and integrating between Android applications. ## Sending a URL -{{< figure src="android-prompt.png" link="android-prompt.png" class="right col-8 col-lg-4" >}} +{{< figure src="../../../guides/android/branding/android-12-prompt.png" link="../../../guides/android/branding/android-12-prompt.png" class="right col-6 col-md-4 col-lg-2" >}} +{{< figure src="android-prompt.png" link="android-prompt.png" class="right col-4 col-lg-3" >}} When the user clicks on a link to a CHT instance from an SMS, email, WhatsApp, or any other app, Android will prompt the user to choose whether to open the URL in the Android app or the browser. If a CHT app is not installed then the URL will be opened in the browser. -Users can choose "Always" to skip this prompt in future. The prompt may look different depending on the version of Android being used. +The prompt may look different depending on the version of Android being used. Up to Android 11, users can choose "Always" to skip this prompt in the future. Starting with Android 12, users will be promped to associate the CHT instance's domain with the Android app. Alternatively, a CHT instance can be configured to have its links automatically verified for the associated Android App (with no user action required). See the docs on [Android App Links verification]({{< ref "apps/guides/android/branding#android-app-links-verification" >}}) for more information. ## Using an intent @@ -27,9 +29,3 @@ Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); startActivity(i); ``` - -## Version notes - -|Feature|CHT Core version| -|---|---| -|Released |3.10.0| diff --git a/content/en/apps/guides/android/branding.md b/content/en/apps/guides/android/branding.md index 732545245..b3d142bdc 100644 --- a/content/en/apps/guides/android/branding.md +++ b/content/en/apps/guides/android/branding.md @@ -6,6 +6,8 @@ description: > Branding the CHT Android applications aliases: > /core/guides/android/branding +relatedContent: > + apps/reference/app-settings/assetlinks --- {{% pageinfo %}} @@ -235,3 +237,82 @@ Releasing a new flavor requires the following steps: ### 6. Publish the app The last step is to publish it in the Play Store, or whatever option best suit your needs. Checkout the [Publishing]({{< ref "apps/guides/android/publishing" >}}) page to see all the options available and instructions. + +## Android App Links verification +*Supported for CHT Core 4.7.0+ and CHT Android 1.3.0+* + +Starting with Android 12, Android supports associating an app with a domain and automatically verifying this association. This allows deep links to immediately open content in the app. To get this working, you need to host a Digital Asset Links JSON file at `https:///.well-known/assetlinks.json` containing some information about your app to associate it with your domain. More information is available on the [official Android docs](https://developer.android.com/training/app-links/verify-android-applinks). + +### Hosting `assetlinks.json` with the CHT + +Since CHT Core version 4.7.0, the CHT supports serving `assetlinks.json` by adding it to your app settings. +All you have to do to make the CHT serve your assetlinks at `/.well-known/assetlinks.json` is to: +1. Ensure your flavor of cht-android [has a valid keystore]({{< ref "#3-generate-a-new-keystore" >}}). +2. Use the `keytool` utility (included with your Java SDK) to get your app's cert fingerprint: + ``` + keytool -list -v -keystore ./path/to/release-key.keystore + # or alternatively: + keytool -printcert -jarfile ./path/to/project.apk + ``` +3. Set the cert fingerprint in the [`assetlinks` configuration]({{< ref "apps/reference/app-settings/assetlinks" >}}) for your CHT instance and deploy it to your server with cht-conf. + +### Verifying it works + +There are different ways to verify your setup works and we'll go through a few of them in the next steps. + +#### Using Android Debug Bridge `adb` + +1. To install the `adb` command, follow the instructions under the [Development Environment > Debug tool adb]({{< ref "contribute/code/android/development-setup#debug-tool-adb" >}}) section. +2. With the phone connected to your computer, open a command line session and write the following command: `adb shell pm get-app-links ` where `` is your application ID. + +The output of this command should look like this: +``` +: + ID: 01234567-89ab-cdef-0123-456789abcdef + Signatures: ["62:BF:C1:78:24:D8:4D:5C:B4:E1:8B:66:98:EA:14:16:57:6F:A4:E5:96:CD:93:81:B2:65:19:71:A7:80:EA:4D"] + Domain verification state: + mobile.webapp.medicmobile.org: verified +``` + +The domain verification state for your CHT instance's domain should show `verified`. + +#### Manually testing on the device + +{{< figure src="android-12-prompt.png" link="android-12-prompt.png" class="right col-6 col-md-4 col-lg-2" >}} + +Another way of verifying your Android app has been properly associated to your CHT instance's domain is by opening +the Android app on a device. You can run this test on a real device or with the emulator in Android Studio. + +Opening the app for the first time should take you straight to the login page __without__ prompting you to link a domain to the app as shown in the following screenshot: + +Additionally, clicking a link to your CHT instance should open the app immediately instead of opening the CHT instance in the default browser. + +### Use case - a single Android app for many CHT instances + +For specific large deployment scenarios, you might publish a single Android app to serve multiple CHT instances. +In this case, each CHT instance's app settings will need to be configured with the same `assetlinks.json` because +they share the same Android app and hence the same `package_name` and `sha256_cert_fingerprints` properties. + +When building your Android app, you will need to ensure the app's manifest has `` +with each CHT instance's domain listed in it like so: + +```xml + + + + + + + + + + + + + + + + + + +``` diff --git a/content/en/apps/guides/android/branding/android-12-prompt.png b/content/en/apps/guides/android/branding/android-12-prompt.png new file mode 100644 index 000000000..4103ce478 Binary files /dev/null and b/content/en/apps/guides/android/branding/android-12-prompt.png differ diff --git a/content/en/apps/reference/app-settings/_index.md b/content/en/apps/reference/app-settings/_index.md index d33e692bb..72f8ebea8 100644 --- a/content/en/apps/reference/app-settings/_index.md +++ b/content/en/apps/reference/app-settings/_index.md @@ -9,7 +9,13 @@ keywords: settings The settings which control CHT apps are defined in the `app_settings.json` file, and stored in the `settings` doc in the database. Some settings can be modified in the [**App Management**]({{% ref "apps/features/admin" %}}) app, which updates the same settings file in the database. -The settings get compiled into the `app_settings.json` file with the `compile-app-settings` action in the `cht-conf` tool. Manually configurable settings are added to the `app_settings` folder at the root of the config folder. The `app_settings/base_settings.json` file can be manually edited to modify individual settings. [`forms`]({{% ref "apps/reference/app-settings/forms" %}}) and [`schedules`]({{% ref "apps/reference/app-settings/schedules" %}}) sections can be defined in separate files named `app_settings/forms.json` and `app_settings/schedules.json` respectively with the settings in the files overriding what might be already present in the `app_settings/base_settings.json` or `app_settings.json` files. +The settings get compiled into the `app_settings.json` file with the `compile-app-settings` action in the `cht-conf` tool. +Manually configurable settings are added to the `app_settings` folder at the root of the config folder. +The `app_settings/base_settings.json` file can be manually edited to modify individual settings. +[`forms`]({{% ref "apps/reference/app-settings/forms" %}}), [`schedules`]({{% ref "apps/reference/app-settings/schedules" %}}), +and [`assetlinks`]({{% ref "apps/reference/app-settings/assetlinks" %}}) sections can be defined in separate files named +`app_settings/forms.json`, `app_settings/schedules.json`, and `app_settings/assetlinks.json` respectively with the settings +in the files overriding what might be already present in the `app_settings/base_settings.json` or `app_settings.json` files. Most sections are described on their own in the [Reference Documentation]({{< ref "apps/reference" >}}). @@ -29,20 +35,21 @@ The following settings do not need to be specified. They should only be defined ### `app_settings.json` | Setting | Description | Default | Version | -|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|---------| -| phone_validation |
  • "full": full validation of a phone number for a region using length and prefix information.
  • "partial": quickly guesses whether a number is a possible phone number by using only the length information, much faster than a full validation.
  • "none": allows almost any values but still fails for any phone that contains a-z chars.
| "full" | 3.1.0 | +|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|---------| +| phone_validation |
  • "full": full validation of a phone number for a region using length and prefix information.
  • "partial": quickly guesses whether a number is a possible phone number by using only the length information, much faster than a full validation.
  • "none": allows almost any values but still fails for any phone that contains a-z chars.
| "full" | 3.1.0 | | uhc.contacts_default_sort |
  • "alpha": Sort contacts alphanumerically
  • "last_visited_date": sort contacts by the date they were most recently visited.
| "alpha" | 2.18.0 | -| uhc.visit_count.month_start_date | The date of each month when the visit count is reset to 0. | 1 | 2.18.0 | -| uhc.visit_count.visit_count_goal | The monthly visit count goal. | 0 | 2.18.0 | -| outgoing_deny_list | All outgoing messages will be denied (unsent) if the recipient phone number starts with an entry in this list. A comma delimited list. (eg. `outgoing_deny_list="253,ORANGE"` will deny all messages sent to `253 543 4448` and `ORANGE NET`) | "" | | -| outgoing_deny_shorter_than | Deny all messages to recipient phone numbers which are shorter than this value. Intended to avoid [message loops]({{% ref "apps/guides/messaging/message-loops" %}}) with short codes used by gateways (eg. `60396`). An integer. | 6 | 3.3.0 | -| outgoing_deny_with_alphas | When `true`, deny all messages to recipient phone numbers containing letters (eg. `Safaricom`). Intended to avoid [message loops]({{% ref "apps/guides/messaging/message-loops" %}}) with non-numeric senders used by gateways. A boolean. | true | 3.3.0 | -| outgoing_deny_with_alphas | When `true`, deny all messages to recipient phone numbers containing letters (eg. `Safaricom`). Intended to avoid [message loops]({{% ref "apps/guides/messaging/message-loops" %}}) with non-numeric senders used by gateways. A boolean. | true | 3.3.0 | -| task_day_limit | The number of days before a task is due to show the due date. | 4 | 3.9.0 | -| app_url | The URL of the app, eg: "https://demo.app.medicmobile.org" | | 3.10.0 | -| task_days_overdue | Display number of overdue days in tasks list | false | 3.13.0 | -| languages | Array of objects with `locale` and `enabled` properties representing respectively the 2 or 3 letter language code and whether that language should be enabled.
If unset it falls back to the previous behavior of relying on the `enabled` property of each translation document `messages-XX.properties`. This fallback behavior is now deprecated and will be removed in the next major version (5.0). This `languages` configuration property will be required for CHT 5.0+. | | 4.2.0 | -| place_hierarchy_types | Array of contact types' IDs, should match the ones defined in `contact_types`. This is used to define the Place Filter's options in Reports tab. | | 2.15.0 | +| uhc.visit_count.month_start_date | The date of each month when the visit count is reset to 0. | 1 | 2.18.0 | +| uhc.visit_count.visit_count_goal | The monthly visit count goal. | 0 | 2.18.0 | +| outgoing_deny_list | All outgoing messages will be denied (unsent) if the recipient phone number starts with an entry in this list. A comma delimited list. (eg. `outgoing_deny_list="253,ORANGE"` will deny all messages sent to `253 543 4448` and `ORANGE NET`) | "" | | +| outgoing_deny_shorter_than | Deny all messages to recipient phone numbers which are shorter than this value. Intended to avoid [message loops]({{% ref "apps/guides/messaging/message-loops" %}}) with short codes used by gateways (eg. `60396`). An integer. | 6 | 3.3.0 | +| outgoing_deny_with_alphas | When `true`, deny all messages to recipient phone numbers containing letters (eg. `Safaricom`). Intended to avoid [message loops]({{% ref "apps/guides/messaging/message-loops" %}}) with non-numeric senders used by gateways. A boolean. | true | 3.3.0 | +| outgoing_deny_with_alphas | When `true`, deny all messages to recipient phone numbers containing letters (eg. `Safaricom`). Intended to avoid [message loops]({{% ref "apps/guides/messaging/message-loops" %}}) with non-numeric senders used by gateways. A boolean. | true | 3.3.0 | +| task_day_limit | The number of days before a task is due to show the due date. | 4 | 3.9.0 | +| app_url | The URL of the app, eg: "https://demo.app.medicmobile.org" | | 3.10.0 | +| task_days_overdue | Display number of overdue days in tasks list | false | 3.13.0 | +| languages | Array of objects with `locale` and `enabled` properties representing respectively the 2 or 3 letter language code and whether that language should be enabled.
If unset it falls back to the previous behavior of relying on the `enabled` property of each translation document `messages-XX.properties`. This fallback behavior is now deprecated and will be removed in the next major version (5.0). This `languages` configuration property will be required for CHT 5.0+. | | 4.2.0 | +| place_hierarchy_types | Array of contact types' IDs, should match the ones defined in `contact_types`. This is used to define the Place Filter's options in Reports tab. | | 2.15.0 | +| assetlinks | Array of [Digital Asset Links]({{< relref "assetlinks" >}}) definitions. This is used to associate your CHT instance's domain to your Android app to verify app links. | | 4.7.0 | ## SMS Workflows diff --git a/content/en/apps/reference/app-settings/assetlinks.md b/content/en/apps/reference/app-settings/assetlinks.md new file mode 100644 index 000000000..a6985db13 --- /dev/null +++ b/content/en/apps/reference/app-settings/assetlinks.md @@ -0,0 +1,44 @@ +--- +title: ".assetlinks" +linkTitle: ".assetlinks" +weight: 5 +description: > + **Assetlinks**: Defining the Digital Asset Links JSON file associating your domain with your Android app. +relatedContent: > + apps/features/integrations/android + apps/guides/android/branding +keywords: android assetlinks +--- + +*Requires CHT Core 4.7.0+, CHT Conf 3.22.0+, and CHT Android 1.3.0+* + +When using a [custom flavor of cht-android]({{< ref "apps/guides/android/branding" >}}) to connect to your CHT instance, the ecosystem supports using [deep links]({{< ref "apps/features/integrations/android#sending-a-url" >}}) to open specific content in the app. (E.g. [token login links]({{< ref "apps/concepts/access#magic-links-for-logging-in-token-login" >}})). Security measures in Android require these deep links [be verified](https://developer.android.com/training/app-links/verify-android-applinks) either automatically or manually. This `assetlinks` configuration enables auto-verification for your CHT links in your Android app. The provided JSON file will be served at `https:///.well-known/assetlinks.json`. If you do not provide this configuration, users will be prompted to manually associate the CHT domain with your app. + +For more information, see the [docs for building a new CHT Android flavor]({{< ref "apps/guides/android/branding#android-app-links-verification" >}}). + +Specify your digital asset links in the `app_settings/assetlinks.json` file. The `compile-app-settings` action in the `cht-conf` will automatically include this configuration in your `app_settings.json` file. Then, running the `upload-app-settings` action will deploy it to the server. + +## `app_settings.json .assetlinks[]` + +| property | type | description | required | +|-----------------------------------|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------| +| `relation[]` | `Array` | The array should contain only one element: the string `delegate_permission/common.handle_all_urls`. | yes | +| `target` | `object` | Contains fields to identify associated apps. | yes | +| `target.namespace` | `string` | Must be set to `android_app`. | yes | +| `target.package_name` | `string` | The [application ID]({{< ref "apps/guides/android/branding#2-new-brand" >}}) declared in the app's `build.gradle` file. | yes | +| `target.sha256_cert_fingerprints` | `Array` | The SHA256 fingerprints of your app’s signing certificate. You can get it with the Java utility `keytool`, see how exactly in our [Android guide]({{< ref "apps/guides/android/branding#hosting-assetlinksjson-with-the-cht" >}}). | yes | + +## Code Sample + +This sample associates the Android app `org.medicmobile.webapp.mobile` to a CHT instance and grants it link-opening rights to the Android app: + +```json +[{ + "relation": ["delegate_permission/common.handle_all_urls"], + "target": { + "namespace": "android_app", + "package_name": "org.medicmobile.webapp.mobile", + "sha256_cert_fingerprints": ["62:BF:C1:78:24:D8:4D:5C:B4:E1:8B:66:98:EA:14:16:57:6F:A4:E5:96:CD:93:81:B2:65:19:71:A7:80:EA:4D"] + } +}] +```