Force update of an Android app when a new version is available

Android

Android Problem Overview


I have an app in Google Play Store. When an update version is available, the older version will become unusable – that is, if users do not update the app, they do not enter in the app. How can I force users to update the app when a new version becomes available?

Android Solutions


Solution 1 - Android

I agree with Scott Helme's point in another answer here. But in some extreme situations (security issues, API breaking changes...) where you absolutely need the users to update to continue using the app, you could provide a simple versioning API. The API would look like this:

versionCheck API:

Request parameters:

  • int appVersion

Response

  1. boolean forceUpgrade
  2. boolean recommendUpgrade

When your app starts, you could call this API that pass in the current app version, and check the response of the versioning API call.

If forceUpgrade is true, show a popup dialog with options to either let user quit the app, or go to Google Play Store to upgrade the app.

Else if recommendUpgrade is true, show the pop-up dialog with options to update or to continue using the app.

Even with this forced upgrade ability in place, you should continue to support older versions, unless absolutely needed.

Solution 2 - Android

try this: First you need to make a request call to the playstore link, fetch current version from there and then compare it with your current version.

String currentVersion, latestVersion;
Dialog dialog;
private void getCurrentVersion(){
 PackageManager pm = this.getPackageManager();
        PackageInfo pInfo = null;

        try {
            pInfo =  pm.getPackageInfo(this.getPackageName(),0);

        } catch (PackageManager.NameNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        currentVersion = pInfo.versionName;
      
   new GetLatestVersion().execute();

}

private class GetLatestVersion extends AsyncTask<String, String, JSONObject> {

        private ProgressDialog progressDialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected JSONObject doInBackground(String... params) {
            try {
//It retrieves the latest version by scraping the content of current version from play store at runtime
                Document doc = Jsoup.connect(urlOfAppFromPlayStore).get();
                latestVersion = doc.getElementsByClass("htlgb").get(6).text();

            }catch (Exception e){
                e.printStackTrace();

            }

            return new JSONObject();
        }

        @Override
        protected void onPostExecute(JSONObject jsonObject) {
            if(latestVersion!=null) {
                if (!currentVersion.equalsIgnoreCase(latestVersion)){
                   if(!isFinishing()){ //This would help to prevent Error : BinderProxy@45d459c0 is not valid; is your activity running? error
                    showUpdateDialog();
                    }
                }
            }
            else
                background.start();
            super.onPostExecute(jsonObject);
        }
    }

private void showUpdateDialog(){
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("A New Update is Available");
        builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse
                        ("market://details?id=yourAppPackageName")));
                dialog.dismiss();
            }
        });

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                background.start();
            }
        });

        builder.setCancelable(false);
        dialog = builder.show();
    }

Solution 3 - Android

You shouldn't stop supporting an older version as soon as a new version comes out. This will result in a terrible user experience. I don't know of any software vendor in existence that does this, for good reason.

What happens if the user can't update or doesn't want to at that time? They simply can't use your app, which is bad.

Google don't provide any option for version tracking like that so you would have to roll your own. A simple web service to return the current live version that your app can check would be sufficient. You can then update the version and the app will know it is outdated. I would only recommend using this to let your users know there is an update more quickly than depending on Google Play. It should not really be used to prevent the app from working, just to prompt the user to update.

Solution 4 - Android

Solution from Google team

Starting from Android 5.0 that's easily achievable through the new Google Play In App updates mechanism. The requirements are to have Play Core library of version 1.5.0+ and use App Bundles idstribution instead of apks.

The library provides you 2 different ways to notify the users about the update:

  1. Flexible, when users can continue using the app while it is being updated in the background.

  2. Immediate - blocking screen that doesn't allow a user to enter the app until they update it.

There are next steps to implement it:

  1. Check for update availability
  2. Start an update
  3. Get a callback for update status
  4. Handle the update

All of these steps implementations are described in details on the official site: https://developer.android.com/guide/app-bundle/in-app-updates

Solution 5 - Android

Google introduced In-app updates lib, (https://developer.android.com/guide/app-bundle/in-app-updates) it works on Lollipop+ and gives you the ability to ask the user for an update with a nice dialog (FLEXIBLE) or with mandatory full-screen message (IMMEDIATE).

You need to implement the latter. Here is how it will look like: enter image description here

I covered all the code in this answer: https://stackoverflow.com/a/56808529/5502121

Solution 6 - Android

Scott and Michael's answers are correct. Host a service that provides a min version number you support and compare that to the installed version. You should hopefully never need to use this, but it's a life saver if some version is out there you absolutely must kill due to some serious flaw.

I just wanted to add the code for what to do next. Here is how you then launch the Google Play Intent and take them to your new version in the store after prompting the user that they must upgrade.

public class UpgradeActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upgrade);
        final String appName = "com.appname";
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              
                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id="+appName)));
                
            }
        });
    }
}

You should re-consider your design if you have to force upgrades on each release.

Solution 7 - Android

Officially google provide an Android API for this. > The API is currently being tested with a handful of partners, and will become available to all developers soon.

Update API is available now - https://developer.android.com/guide/app-bundle/in-app-updates

Solution 8 - Android

I highly recommend checking out Firebase's Remote Config functionality for this.

I implemented it using a parameter - app_version_enabled - with a condition "Disabled Android Versions" that looks like this:

applies if App ID == com.example.myapp and App version regular expression ^(5.6.1|5.4.2) 

Default for the parameter is "true", but Disabled Android Versions has a value of false. In my regex for Disabled Android Versions, you can add more disabled versions simply with another |{version name} inside those parentheses.

Then I just check if the configuration says the version is enabled or not -- I have an activity that I launch that forces the user to upgrade. I check in the only two places the app can be launched from externally (my default launcher activity and an intent-handling activity). Since Remote Config works on a cache basis, it won't immediately capture "disabled" versions of the app if the requisite time hasn't passed for the cache to be invalidated, but that is at most 12 hours if you're going by their recommended cache expiration value.

Solution 9 - Android

check version code of local and play store apk

try {
        versionChecker VersionChecker = new versionChecker();
        String versionUpdated = VersionChecker.execute().get().toString();
        Log.i("version code is", versionUpdated);


        PackageInfo packageInfo = null;
        try {
            packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        int version_code = packageInfo.versionCode;
        String version_name = packageInfo.versionName;
        Log.i("updated version code", String.valueOf(version_code) + "  " + version_name);
        if (version_name != versionUpdated) {
            String packageName = getApplicationContext().getPackageName();//
            UpdateMeeDialog updateMeeDialog = new UpdateMeeDialog();
            updateMeeDialog.showDialogAddRoute(MainActivity.this, packageName);
            Toast.makeText(getApplicationContext(), "please updated", Toast.LENGTH_LONG).show();
        }
    } catch (Exception e) {
        e.getStackTrace();
    }

implement class for version check

class versionChecker extends AsyncTask<String, String, String> {
String newVersion;

@Override
protected String doInBackground(String... params) {

    try {
        newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=+YOR_PACKAGE_NAME+&hl=en")
                .timeout(30000)
                .userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
                .referrer("http://www.google.com")
                .get()
                .select("div[itemprop=softwareVersion]")
                .first()
                .ownText();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return newVersion;
}
}

dialob box for update

public class UpdateMeeDialog {

ActivityManager am;
TextView rootName;
Context context;
Dialog dialog;
String key1,schoolId;
public void showDialogAddRoute(Activity activity, final String packageName){
    context=activity;
    dialog = new Dialog(context);

    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setCancelable(false);
    dialog.setContentView(R.layout.dialog_update);
    am = (ActivityManager)activity.getSystemService(Context.ACTIVITY_SERVICE);

    Button cancelDialogue=(Button)dialog.findViewById(R.id.buttonUpdate);
    Log.i("package name",packageName);
    cancelDialogue.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent=new Intent(Intent.ACTION_VIEW);                
    intent.setData(Uri.parse("https://play.google.com/store/apps/details?
    id="+packageName+"&hl=en"));
            context.startActivity(intent);
        }
    });
    dialog.show();
}
}

dialog layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#d4e9f2">


<TextView
    android:layout_width="match_parent"
    android:layout_height="40dp"

    android:text="Please Update First..!!"
    android:textSize="20dp"
    android:textColor="#46a5df"
    android:textAlignment="center"
    android:layout_marginTop="50dp"
    android:id="@+id/textMessage"
    />
<LinearLayout
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:weightSum="1"
    android:layout_marginTop="50dp"
    android:layout_below="@+id/textMessage"
    android:layout_height="50dp">

    <Button
        android:id="@+id/buttonUpdate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Update"
        android:background="#67C6F1"
        android:textAlignment="center" />
</LinearLayout>

Solution 10 - Android

You can use the Play Core Library In-app updates to tackle this. You can check for update availability and install them if available seamlessly.

In-app updates are not compatible with apps that use APK expansion files (.obb files). You can either go for flexible downloads or immediate updates which Google Play takes care of downloading and installing the update for you.

dependencies {
    implementation 'com.google.android.play:core:1.5.0'
    ...
}

Refer this answer https://stackoverflow.com/a/58212818/7579041

Solution 11 - Android

It is better to define our own process to for upgrade.

  1. Create a web service which gives latest version for app (ios,android) from our server.
  2. Or Any web service that you used in app (e.g Login) will return latest app version from server.
  3. Once app will get version from #1 or 2. App will cross check it with local/cuurent appversion. if there is difference then we can show alert as follows,

Android & iOS : If latest app version available then it will show alert as “Latest version available with more features, To upgrade click on upgrade button” (Alert with “Upgarde” and “No. Thanks” button.) Then app will redirect to playstore/Appstore and it will open latest version.

 --- we can do upgrade compulsory or optionally.

Before Upgrade process please make sure that you handled proper db migration process if there is any db schema change.

Solution 12 - Android

For forcing the app user to update if an update is available in the market, you should first check the app version on the market and compare it with the version of the app on the device. If they are different, it may be an update available. In this post I wrote down the code for getting the current version of market and current version on the device and compare them together. I also showed how to show the update dialog and redirect the user to the update page. Please visit this link: https://stackoverflow.com/a/33925032/5475941 Just make sure that in the dialog you only show the user update button and don't show him the cancel button. In this case he will be forced to update, before he can use the app.

Solution 13 - Android

What should definitely be mentioned here is the soon-to-be released In-app Updates API.

> You'll have two options with this API; the first is a full-screen experience for critical updates when you expect the user to wait for the update to be applied immediately. The second option is a flexible update, which means the user can keep using the app while the update is downloaded. You can completely customize the update flow so it feels like part of your app.

Solution 14 - Android

It is good idea to use remote config for app version and always check in launch activity is current app version is same as remote version or not if not force for update from app store..

Simple logic happy coding..

https://firebase.google.com/docs/remote-config/android

Solution 15 - Android

Google released In-App Updates for the Play Core library.

I implemented a lightweight library to easily implement in-app updates. You can find to the following link an example about how to force the user to perform the update.

https://github.com/dnKaratzas/android-inapp-update#forced-updates

Solution 16 - Android

I used a simple approach to make this work:

  1. Create Firebase database
  2. Add your latest version
  3. If the version is different than the installed version, show the popup of installing the update. It works perfectly for me...

Solution 17 - Android

You can achieve the same using the answers mentioned here, but if you are looking for an easy to integrate built in solution. You can use https://appupgrade.dev/ service to force update you mobile apps. You need to create new version for your app versions you want to update in the app upgrade service and select whether you want to force it or just want to let users know that new version is available.

enter image description here

after this you will need to call the appupgrade api from your app with the required details such as your app version, platform, environment and app name. The API will return you the details.. that this app needs to be updated or not. Based on the response you can show popup in your app.You can call this API when app starts or periodically to check for the update. You can even provide a custom message. API response:

enter image description here

See the response has force update true. So handle in the app by showing popup. enter image description here

You can find the complete user documentation here. https://appupgrade.dev/docs

Thanks.

Solution 18 - Android

you can do this by doing a match between a version number that is kept on app in a variable and similarly the current app version is kept on server side and each time user opens the app the first request should be send to check that if it founds matching do nothing simply let the user use your app otherwise fire an intent to the google playstore or open a webview window to your app(window.open("https://play.google.com/store/apps/details?id=package_name";, '_system', 'location=yes');) and there they will automatically have the button asking for update that's what google playstore does for you if you dont have automatic updates on.

Solution 19 - Android

You can notify your users that there is a new version of the current app available to update. Also, if this condition is true, you can block login in the app.

Please see if this provides you the solution.

Solution 20 - Android

Well, there could be many solutions to this problem like scraping the version code from App Page (Google Play App page), etc.

But I am going to show you the ultimate solution that won't cost a penny and will work like magic.

  1. Just save the latest Version code of your app on Firebase Remote
    Config panel

  2. Fetch that version code value whenever the app is opened

  3. Compare it with the current version code of the app, which you can get by the following code

    private int getCurrentVersionCode() {
    try {
        return getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
    } catch (NameNotFoundException e) {
        e.printStackTrace();
    }
    return -1;
    

    }

If the fetched version code is greater than the current version, show an AlertDialog asking to update the app. Otherwise, the app is already updated.

So, whenever you roll out the new version, you need to put that new version code in Firebase Remote config panel

You can read the whole tutorial on how to force users to update the app using Firebase Remote Config

Solution 21 - Android

var activeVersion = "3.9.2";

var currentVersion = "3.9.1";

var activeVersionArr = activeVersion.split(".");
var currentVersionArr = currentVersion.split(".");

var compareArray =JSON.stringify(activeVersionArr)==JSON.stringify(currentVersionArr);
   
if(compareArray){
  return false;
}

if(!compareArray){
  for(var i=0;i<activeVersionArr.length;i++){      
      if(activeVersionArr[i]!==currentVersionArr[i]){            
        if(activeVersionArr[i] > currentVersionArr[i]){
          return true;
        }else{
          return false;
        }          
      }
  }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionashrafulView Question on Stackoverflow
Solution 1 - AndroidMichaelView Answer on Stackoverflow
Solution 2 - AndroidAshuKingSharmaView Answer on Stackoverflow
Solution 3 - AndroidScott HelmeView Answer on Stackoverflow
Solution 4 - AndroidGaketView Answer on Stackoverflow
Solution 5 - AndroidKirill KarmazinView Answer on Stackoverflow
Solution 6 - AndroidbsautnerView Answer on Stackoverflow
Solution 7 - AndroidCoolView Answer on Stackoverflow
Solution 8 - AndroidChantell OsejoView Answer on Stackoverflow
Solution 9 - AndroidMahesh PanditView Answer on Stackoverflow
Solution 10 - AndroidAmin PinjariView Answer on Stackoverflow
Solution 11 - AndroidSandeepView Answer on Stackoverflow
Solution 12 - AndroidMohammadView Answer on Stackoverflow
Solution 13 - AndroidMarko GajićView Answer on Stackoverflow
Solution 14 - AndroidNeeraj SinghView Answer on Stackoverflow
Solution 15 - AndroiddKaratzasView Answer on Stackoverflow
Solution 16 - AndroiddiveshView Answer on Stackoverflow
Solution 17 - AndroidShashi Prakash GautamView Answer on Stackoverflow
Solution 18 - Androidshiva2492View Answer on Stackoverflow
Solution 19 - AndroidVansuita Jr.View Answer on Stackoverflow
Solution 20 - AndroidWaqas YounisView Answer on Stackoverflow
Solution 21 - AndroidKeshav GeraView Answer on Stackoverflow