android app update notification
android app update notification

Android App Update Notification are necessary as most of them fix a current bug or maybe developers might have introduced an awesome feature for users.

Need some career advice or prepping for an Android developer interview? Hit me up on Topmate.io, and let's chat!

However not every user is interested in checking for updates or even updating your app. In such a scenario, what can we do?

Either you can force or remind them, to update the current version of the app installed on their Android smartphone.

This can be achieved using the In-app updates provided by Play Core library (1.5.0+)

Note: In-app updates works only with devices running Android 5.0 (API level 21) or higher, and requires you to use Play Core library 1.5.0 or higher.

Type of In app Updates

There are two types of update notification you can send to your user:

  1. Flexible App Update | Prompt user to Update App
  2. Forced App Update | Force User to Update App

Flexible App Update

In a flexible app update, developer will be able to prompt user to update their app in background while using the old version.

Once the background downloading is finished an android snackbar prompt appears to install and reopen the app.

Android App Update Notification
Android App Update Notification Flexible Flow

Code for Flexible Update

Before requesting an update, you need to first check if one is available for your app.

// Creates the instance of the manager.
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context);

// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();

// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
    if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
          && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
              // Request the update.
    }
});

Start an Update using code below:

appUpdateManager.startUpdateFlowForResult(
    // Pass the intent that is returned by 'getAppUpdateInfo()'.
    appUpdateInfo,
    AppUpdateType.FLEXIBLE,
    // The current activity making the update request.
    this,
    // Include a request code to later monitor this update request.
    MY_REQUEST_CODE);

Callback status for updates

public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == MY_REQUEST_CODE) {
    if (resultCode != RESULT_OK) {
      log("Update flow failed! Result code: " + resultCode);
      // If the update is cancelled or fails,
      // you can request to start the update again.
    }
  }
}

Monitor the update status

// Create a listener to track request state updates.
InstallStateUpdatedListener listener = state -> {
    // Show module progress, log state, or install the update.
  };

// Before starting an update, register a listener for updates.
appUpdateManager.registerListener(listener);

// Start an update.

// When status updates are no longer needed, unregister the listener.
appUpdateManager.unregisterListener(listener);

Install Update

@Override
public void onStateUpdate(InstallState state) {
  if (state.installStatus() == InstallStatus.DOWNLOADED) {
    // After the update is downloaded, show a notification
    // and request user confirmation to restart the app.
    popupSnackbarForCompleteUpdate();
  }
  ...
}

/* Displays the snackbar notification and call to action. */
private void popupSnackbarForCompleteUpdate() {
  Snackbar snackbar =
      Snackbar.make(
          findViewById(R.id.activity_main_layout),
          "An update has just been downloaded.",
          Snackbar.LENGTH_INDEFINITE);
  snackbar.setAction("RESTART", view -> appUpdateManager.completeUpdate());
  snackbar.setActionTextColor(
      getResources().getColor(R.color.snackbar_action_text_color));
  snackbar.show();
}

Check if Downloaded Update is installed or not in onResume():

// Checks that the update is not stalled during 'onResume()'.
// However, you should execute this check at all app entry points.
@Override
protected void onResume() {
  super.onResume();

  appUpdateManager
      .getAppUpdateInfo()
      .addOnSuccessListener(appUpdateInfo -> {
              ...
              // If the update is downloaded but not installed,
              // notify the user to complete the update.
              if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
                  popupSnackbarForCompleteUpdate();
              }
          });
}

Forced (Immediate) App Update

Forced or an immediate app update is one were user is forced to download the app update first and then only be able to open and run app.

Android App Update Notification Immediate Flow
Android App Update Notification Immediate Flow

Code for Immediate App Update

Check for Update

// Creates instance of the manager.
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context);

// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();

// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
    if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
          // For a flexible update, use AppUpdateType.FLEXIBLE
          && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
              // Request the update.
    }
});

Start an Update

appUpdateManager.startUpdateFlowForResult(
    // Pass the intent that is returned by 'getAppUpdateInfo()'.
    appUpdateInfo,
    // Or 'AppUpdateType.FLEXIBLE' for flexible updates.
    AppUpdateType.IMMEDIATE,
    // The current activity making the update request.
    this,
    // Include a request code to later monitor this update request.
    MY_REQUEST_CODE);

Get the callback Status

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == MY_REQUEST_CODE) {
    if (resultCode != RESULT_OK) {
      log("Update flow failed! Result code: " + resultCode);
      // If the update is cancelled or fails,
      // you can request to start the update again.
    }
  }
}

If you are performing an immediate update, and the user consents to installing the update, Google Play displays the update progress on top of your app’s UI across the entire duration of the update. During the update, if the user closes or terminates your app, the update should continue to download and install in the background without additional user confirmation.

However, when your app returns to the foreground, you should confirm that the update is not stalled in the UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS state. If the update is stalled in this state, resume the update, as shown below:

// Checks that the update is not stalled during 'onResume()'.
// However, you should execute this check at all entry points into the app.
@Override
protected void onResume() {
  super.onResume();

  appUpdateManager
      .getAppUpdateInfo()
      .addOnSuccessListener(
          appUpdateInfo -> {
            ...
            if (appUpdateInfo.updateAvailability()
                == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
                // If an in-app update is already running, resume the update.
                manager.startUpdateFlowForResult(
                    appUpdateInfo,
                    IMMEDIATE,
                    this,
                    MY_REQUEST_CODE);
            }
          });
}

Source:

Google Play

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

You May Also Like