Cordova in-app update demo app

Cordova In-App Update plugin demo

Demo app for testing the cordova-plugin-in-app-updates, which allows to check for and install updates from Play Store using the native in-app updates library. Source code available in GitHub.

Apache Cordova logo phonegap

Prerequisites

  1. Android 5.0 or higher
  2. Google Play Store active
  3. Google Play Services active

Screenshots

Methods

This is a summary of the demo app’s methods. Refer to plugin’s README for details

getUpdateAvailability

Invokes the AppUpdateManager to check for updates available in Play Store and return one of the updateAvailability codes as string:

Return values

  • UPDATE_AVAILABLE
  • UPDATE_NOT_AVAILABLE
  • DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS
  • UNKNOWN

When this method returns UPDATE_AVAILABLE, your app is ready to use the following methods to prompt the user for update.

updateFlexible

Starts a flexible update process and prompts the user with a dialog to download the new version now or when Wi-Fi is available. The success callback from this method can be triggered more than once according to its status.

Return values

  • UPDATE_NOT_AVAILABLE
  • DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS
  • UPDATE_PROMPT
  • RESULT_OK
  • RESULT_CANCELED
  • RESULT_IN_APP_UPDATE_FAILED
  • ACTIVITY_RESULT_UNKNOWN
  • DOWNLOADING
  • DOWNLOADED

If the user does not install the downloaded flexible update:

  • When app is minimized and reactivated: snackbar to install is shown thanks to the plugin’s onResume method.
  • When app is closed and restarted: nothing happens. In this case, you should call getUpdateAvailability and it will return DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS. With this information, you are ready to either:
    • Call updateFlexible to show again the snackbar with the RESTART button
    • Call updateImmediate to install now the downloaded update (recommended)
Make sure to call getUpdateAvailability as often as needed to ensure there are no flexible updates downloaded pending install, as they will consume storage space until installed

updateImmediate

Starts an immediate update process and prompts the user with a fullscreen dialog to download now or when Wi-Fi is available. The update is downloaded and installed in the foreground, preventing the user from interacting with your app until the installation succeeds and the app is automatically restarted.

Return values

  • UPDATE_NOT_AVAILABLE
  • DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS
  • RESULT_OK
  • RESULT_CANCELED
  • RESULT_IN_APP_UPDATE_FAILED
  • ACTIVITY_RESULT_UNKNOWN
  • DOWNLOADING
  • DOWNLOADED

setSnackbarOptions

Sets the label and the button text for the snackbar shown after downloading a flexible update. You are free to call this method at any time. You can also call it again to show different snackbar messages after the snackbar was shown.

If not called, default messages in English will be shown.

Return values

  • onSuccess = “SUCCESS”
  • onFail = Internal error description.
Calling this method won’t show the snacbkar; It simply sets the values for the snackbar shown after a Flexible update is ready to be installed.

Testing Demo App

  1. Disable automatic app updates from Play Store’s Settings panel.
  2. Join the app’s open testing program.
  3. Install latest version from the Play Store and do not open the app.
  4. Close the Play Store app.
  5. Manually uninstall the latest version that you just installed.
  6. Install a previous APK version from the Download section below.
  7. Open the demo app and check for updates. You should get the UPDATE_AVAILABLE success callback message.
  8. If you get UPDATE_NOT_AVAILABLE, wait between 12 to 24 hs and retry. This is because Play Services seem to keep a server-side cache of updates checking.
You cannot begin from step 6 (install old version directly) because In-App updates require the app to be installed from Google Play Store at least once

Download demo app

All these APK are Play Store-signed, so you can use them to test the actual update process on real devices or emulators with Google Play Store active.

App version Plugin version target Sdk compile Sdk min Sdk
1.4.4 2.1.0 33 32 21
1.4.3 2.1.0 33 32 21
1.4.2 2.1.0 32 32 21
1.3.4 2.0.5 30 30 22
1.1.9 1.0.6 29 29 21

Latest version in Play Store is 1.4.4.

Testing In-App Updates in your app

Easy mode + pseudo APK update

This testing method can be used with any release track. It is good for testing purposes because the downloaded APK won’t be installed due to a signature mismatch between the preinstalled one and the one from the Store.

  1. Install from the Store the current version of your app.
  2. Uninstall it manually (not from inside the Store)
  3. Compile your app with a lower versioncode than the one available in the Store.
  4. Install the signed production app.
  5. Check for updates normally.
  6. Both Flexible and Immediate update process will take place normally.
  7. Replacing the installed APK with the downloaded one will fail due to a signature mismatch.
  8. The normal install process will end and you will return to the same test app you had installed.
  9. You can keep testing different update scenarios without actually having the new version installed, while the update flow takes place normally.
Android Studio Logcat

Downloaded update discarded due to certificate mismatch.

Easy + real APK update

This mode involves the following procedure:

  1. Upload first version to the Play Store in the Internal testing track.
  2. Upload the second version to the Play Store in the same track.
  3. Add the target user(s) to the Internal testing program Testers email list.
  4. Join the testing program with the invite link.
  5. From the App bundle explorer in Play Developers Console, download the Signed, universal APK for the first version.
  6. Install this Play Console-Signed APK in phone / emulator.
  7. Run this signed APK and check for updates normally. The updates process should work and install the second version from the Play Store because the signatures match.

By the book mode

You can use the Internal app sharing method to test in-app updates as suggested by the official Android developers guide.

Code snippet to use plugin in your app

var updates = {
  getInAppUpdate: function () {
    var onSuccess = function (strSuccess) {
      if (strSuccess == 'UPDATE_AVAILABLE' || strSuccess == 'DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS') {
        // updates.updateFlexible(); // uncomment this to show background update dialog!
        updates.updateImmediate(); // uncomment this to show foreground update dialog!
      }
    };
    var onFailure = function (strError) {
      console.warn(strError);
    };
    cordova.plugins.InAppUpdate.getUpdateAvailability(onSuccess, onFailure);
  },
  updateFlexible: function () {
    var onSuccess = function (strSuccess) {
      console.log(strSuccess);
    };
    var onFailure = function (strError) {
      console.warn(strError);
    };
    var snackbarText = "Actualización lista para instalar!"; // Translation: Update ready to install!
    var snackbarButton = "REINICIAR"; // Translation: RESTART
    var snackbarButtonColor = "#FF80AB";
    cordova.plugins.InAppUpdate.setSnackbarOptions(onSuccess, onFailure, snackbarText, snackbarButton, snackbarButtonColor);
    var onUpdateSuccess = function (strSuccess) {
      console.log(strSuccess);
    };
    var onUpdateFailure = function (strError) {
      console.warn(strError);
    };
    cordova.plugins.InAppUpdate.updateFlexible(onUpdateSuccess, onUpdateFailure);
  },
  updateImmediate: function () {
    var onSuccess = function (strSuccess) {
      console.log(strSuccess);
      if(strSuccess == 'RESULT_CANCELED'){
        console.log('User declined immediate update dialog.');
      }
    };
    var onFailure = function (strError) {
      console.warn(strError);
    };
    cordova.plugins.InAppUpdate.updateImmediate(onSuccess, onFailure);
  }
};

More plugin demo apps

Check out the following Cordova plugin demo apps ready for download on your device. The source code is included for compiling to any platform.

Disclaimer

The content in this post is for general information purposes only. The information is provided by the author and/or external sources and while we endeavour to keep the information up to date and correct, we make no representations or warranties of any kind, express or implied, about the completeness, accuracy, reliability, suitability or availability with respect to the website or the information, products, services, or related graphics contained on the post for any purpose. Some of the content and images used in this post may be copyrighted by their respective owners. The use of such materials is intended to be for educational and informational purposes only, and is not intended to infringe on the copyrights of any individuals or entities. If you believe that any content or images used here violate your copyright, please contact us and we will take appropriate measures to remove or attribute the material in question.