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?
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
boolean forceUpgrade
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.
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();
}
background.start();
in builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
–
Battle 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 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:
Flexible, when users can continue using the app while it is being updated in the background.
Immediate - blocking screen that doesn't allow a user to enter the app until they update it.
There are next steps to implement it:
- Check for update availability
- Start an update
- Get a callback for update status
- 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
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:
I covered all the code in this answer: https://mcmap.net/q/151736/-prompt-android-app-user-to-update-app-if-current-version-lt-gt-market-version
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.
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
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.
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>
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://mcmap.net/q/151737/-android-version-code-for-app-updating
I used a simple approach to make this work:
- Create Firebase database
- Add your latest version
- If the version is different than the installed version, show the popup of installing the update. It works perfectly for me...
It is better to define our own process to for upgrade.
- Create a web service which gives latest version for app (ios,android) from our server.
- Or Any web service that you used in app (e.g Login) will return latest app version from server.
- 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.
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://mcmap.net/q/151735/-android-in-app-version-check 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.
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.
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..
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
You can achieve the same using the answers mentioned here, if you are looking for an easy to integrate built in solution. You can use App Upgrade https://appupgrade.dev/ service to force update your mobile apps.
- Create new version entry for your app version that 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.
- Integrate your app with App Upgrade using available SDK. Official SDK are available for React Native, Flutter, Expo, Android and iOS(Swift). The SDK will take care of the rest. Whenever you want to force upgrade a version just create a version entry in app upgrade dashboard.
- You can also integrate using API. Just 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:
See the response has force update true. So handle in the app by showing popup.
You can find the complete user documentation here. https://appupgrade.dev/docs
Thanks.
In my opinion, the simplest way is to create an API, which contains the latest version of your application. Then in the application, create a dialog and check if the version of the application on the human machine is equal to the version on the API. If not, display the Dialog and ask the user to update the app on the store. This Dialog will navigate to your app dashboard on the store
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.
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.
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.
- Just save the latest Version code of your app on Firebase Remote
Config panel - Fetch that version code value whenever the app is opened
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
For those looking for a quick and free solution, I would recommend Semaphr. Integration should not take more than 10 minutes and you can control everything from the dashboard:
- what message to show
- which versions should be covered
- schedule your upgrade
- see live app versions statistics
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;
}
}
}
}
© 2022 - 2024 — McMap. All rights reserved.