How to Work with Android's In-App Update API

How to work with Android's in-app update API?

Step 1: Add dependency (build.gradle (app)):

dependencies {

implementation 'com.google.android.play:core:1.7.3'
...
}

Step 2: Check for update availability and start if it's available

private AppUpdateManager mAppUpdateManager;
private static final int RC_APP_UPDATE = 11;

In onStart() method:

mAppUpdateManager = AppUpdateManagerFactory.create(this);

mAppUpdateManager.registerListener(installStateUpdatedListener);

mAppUpdateManager.getAppUpdateInfo().addOnSuccessListener(appUpdateInfo -> {

if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE /*AppUpdateType.IMMEDIATE*/)){

try {
mAppUpdateManager.startUpdateFlowForResult(
appUpdateInfo, AppUpdateType.FLEXIBLE /*AppUpdateType.IMMEDIATE*/, MainActivity.this, RC_APP_UPDATE);

} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}

} else if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED){
//CHECK THIS if AppUpdateType.FLEXIBLE, otherwise you can skip
popupSnackbarForCompleteUpdate();
} else {
Log.e(TAG, "checkForAppUpdateAvailability: something else");
}
});

Step 3: Listen to update state

InstallStateUpdatedListener installStateUpdatedListener = new 
InstallStateUpdatedListener() {
@Override
public void onStateUpdate(InstallState state) {
if (state.installStatus() == InstallStatus.DOWNLOADED){
//CHECK THIS if AppUpdateType.FLEXIBLE, otherwise you can skip
popupSnackbarForCompleteUpdate();
} else if (state.installStatus() == InstallStatus.INSTALLED){
if (mAppUpdateManager != null){
mAppUpdateManager.unregisterListener(installStateUpdatedListener);
}

} else {
Log.i(TAG, "InstallStateUpdatedListener: state: " + state.installStatus());
}
}
};

Step 4: Get a callback for update status

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (requestCode == RC_APP_UPDATE) {
if (resultCode != RESULT_OK) {
Log.e(TAG, "onActivityResult: app download failed");
}
}
}

Step 5: Flexible update

private void popupSnackbarForCompleteUpdate() {

Snackbar snackbar =
Snackbar.make(
findViewById(R.id.coordinatorLayout_main),
"New app is ready!",
Snackbar.LENGTH_INDEFINITE);

snackbar.setAction("Install", view -> {
if (mAppUpdateManager != null){
mAppUpdateManager.completeUpdate();
}
});


snackbar.setActionTextColor(getResources().getColor(R.color.install_color));
snackbar.show();
}

Step 6: Don't forget to unregister listener (in onStop method)

if (mAppUpdateManager != null) {
mAppUpdateManager.unregisterListener(installStateUpdatedListener);
}

Note: Add this listener in any one activity in your app preferably in MainActivity (Home page)

For testing, you can use FakeAppUpdateManager

https://developer.android.com/reference/com/google/android/play/core/appupdate/testing/FakeAppUpdateManager.html

Constraint: In-app update works only with devices running Android 5.0 (API level 21) or higher

Official Documentation: https://developer.android.com/guide/playcore/in-app-updates

Where to put in-app update implementation in Android

THIS ANSWER IS A HACK!

I have had quite a bit of trouble with in app updates. the issue being that this librery was made for users that stay in the same activity where startUpdateFlowForResult is called from and then whenever the user does something unexpected like checking whatsapp or going to the next activity everything breaks down and the update doesnt get completed. and you can try to fix it with endless boilerplate but since calling a snackbar that is activity agnostic is super complex that will cost you at least some gray hairs and leave you with delicate code that probably still is somewhat buggy.

THE ALTERNATIVE

I finally gave upand decided to redirect my users directly to GooglePlayStore:

if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE ) { //maybe you could add some additional checks like priority level here
makeUpdateDialog(mContext).show();
}

I use the In-app Updates library exclusively to check for availability and then I show a dialog with the following code in the action button:

try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(ownGooglePlayLink)));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(ownWebLink)));
}

public static final String ownGooglePlayLink="market://details?id=com.my.package.name";
public static final String ownWebLink="https://play.google.com/store/apps/details?id=com.my.package.name";

This is admitedly very hacky but its not as bad as it seems. I find that the user experience remmains good and the user can either skip your update or return to the app after initializing the update.

The android in-app update API is not working as I expected

This actually just randomly worked about 36 hours later when I opened the app again.
There must be a 24 hour delay or so from when update goes live til when the API will pick it up.



Related Topics



Leave a reply



Submit