61

I want to add a "Check for update" button in apps so that when someone clicks it, it will display a toast message / progress dialog for checking the app's version.

If new version is found the apps will auto download it to the phone and let user to manually install the updated apps.

Or any others method will do as long as it can check for latest version and notify the user to update.


Update: Now you can do this inside your app using https://developer.android.com/guide/playcore/in-app-updates

xDragonZ
  • 12,502
  • 6
  • 37
  • 52

12 Answers12

41

You can use this Android Library: https://github.com/danielemaddaluno/Android-Update-Checker. It aims to provide a reusable instrument to check asynchronously if exists any newer released update of your app on the Store. It is based on the use of Jsoup (http://jsoup.org/) to test if a new update really exists parsing the app page on the Google Play Store:

private boolean web_update(){
    try {       
        String curVersion = applicationContext.getPackageManager().getPackageInfo(BuildConfig.APPLICATION_ID, 0).versionName;   
        String newVersion = curVersion;
        newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID + "&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();
        return (value(curVersion) < value(newVersion)) ? true : false;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

And as "value" function the following (works if values are beetween 0-99):

private long value(String string) {
    string = string.trim();
    if( string.contains( "." )){ 
        final int index = string.lastIndexOf( "." );
        return value( string.substring( 0, index ))* 100 + value( string.substring( index + 1 )); 
    }
    else {
        return Long.valueOf( string ); 
    }
}

If you want only to verify a mismatch beetween versions, you can change:

value(curVersion) < value(newVersion) with value(curVersion) != value(newVersion)

Lakpriya Senevirathna
  • 2,488
  • 2
  • 17
  • 35
madx
  • 6,723
  • 4
  • 55
  • 59
26

If it is an application on the Market, then on app start-up, fire an Intent to open up the Market app hopefully which will cause it to check for updates.

Otherwise implementing and update checker is fairly easy. Here is my code (roughly) for it:

String response = SendNetworkUpdateAppRequest(); // Your code to do the network request
                                                 // should send the current version
                                                 // to server
if(response.equals("YES")) // Start Intent to download the app user has to manually install it by clicking on the notification
    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("URL TO LATEST APK")));

Of course you should rewrite this to do the request on a background thread but you get the idea.

If you like something a little but more complex but allows your app to automatically apply the update see here.

Nabeel K
  • 5,938
  • 11
  • 38
  • 68
Jasoneer
  • 2,078
  • 2
  • 15
  • 20
20

Google updated play store two months before. This is the solution working right now for me..

class GetVersionCode extends AsyncTask<Void, String, String> {

    @Override

    protected String doInBackground(Void... voids) {

        String newVersion = null;

        try {
            Document document = Jsoup.connect("https://play.google.com/store/apps/details?id=" + MainActivity.this.getPackageName()  + "&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();
            if (document != null) {
                Elements element = document.getElementsContainingOwnText("Current Version");
                for (Element ele : element) {
                    if (ele.siblingElements() != null) {
                        Elements sibElemets = ele.siblingElements();
                        for (Element sibElemet : sibElemets) {
                            newVersion = sibElemet.text();
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return newVersion;

    }


    @Override

    protected void onPostExecute(String onlineVersion) {

        super.onPostExecute(onlineVersion);

        if (onlineVersion != null && !onlineVersion.isEmpty()) {

            if (Float.valueOf(currentVersion) < Float.valueOf(onlineVersion)) {
                //show anything
            }

        }

        Log.d("update", "Current version " + currentVersion + "playstore version " + onlineVersion);

    }
}

and don't forget to add JSoup library

dependencies {
compile 'org.jsoup:jsoup:1.8.3'}

and on Oncreate()

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    String currentVersion;
    try {
        currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }

    new GetVersionCode().execute();

}

that's it.. Thanks to this link

Rajesh Naddy
  • 1,120
  • 12
  • 17
  • Above code throwing exception at `get();` _Java.Lang.RuntimeException: Exception of type 'Java.Lang.RuntimeException' was thrown_ – R15 May 22 '18 at 10:08
  • @PriyankaAgrawal Sorry Mam for the delay, just now I checked my project ,its working..have u added Jsoup library? – Rajesh Naddy May 22 '18 at 12:33
  • Above issue has been solve by using code under `AsyncTask` class. But the line `document.getElementsContainingOwnText("Current Version");` returning value _
    Current Version
    _. so I think there is not meaning going ahead. I am using Xamarin.android.
    – R15 May 22 '18 at 13:07
  • @PriyankaAgrawal might be mainThread() issue.Thanks for pointing out, i have developed it in Android Studio no idea on Xamarin.. – Rajesh Naddy May 22 '18 at 13:14
5

Navigate to your play page:

https://play.google.com/store/apps/details?id=com.yourpackage

Using a standard HTTP GET. Now the following jQuery finds important info for you:

Current Version

$("[itemprop='softwareVersion']").text()

What's new

$(".recent-change").each(function() { all += $(this).text() + "\n"; })

Now that you can extract these information manually, simply make a method in your app that executes this for you.

public static String[] getAppVersionInfo(String playUrl) {
    HtmlCleaner cleaner = new HtmlCleaner();
    CleanerProperties props = cleaner.getProperties();
    props.setAllowHtmlInsideAttributes(true);
    props.setAllowMultiWordAttributes(true);
    props.setRecognizeUnicodeChars(true);
    props.setOmitComments(true);
    try {
        URL url = new URL(playUrl);
        URLConnection conn = url.openConnection();
        TagNode node = cleaner.clean(new InputStreamReader(conn.getInputStream()));
        Object[] new_nodes = node.evaluateXPath("//*[@class='recent-change']");
        Object[] version_nodes = node.evaluateXPath("//*[@itemprop='softwareVersion']");

        String version = "", whatsNew = "";
        for (Object new_node : new_nodes) {
            TagNode info_node = (TagNode) new_node;
            whatsNew += info_node.getAllChildren().get(0).toString().trim()
                    + "\n";
        }
        if (version_nodes.length > 0) {
            TagNode ver = (TagNode) version_nodes[0];
            version = ver.getAllChildren().get(0).toString().trim();
        }
        return new String[]{version, whatsNew};
    } catch (IOException | XPatherException e) {
        e.printStackTrace();
        return null;
    }
}

Uses HtmlCleaner

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
  • 1
    Looking around answers to questions here, I hate to admit but this seems to be only solution doable without spending hours trying to crack down that “api” of Google Play... – Smar Mar 30 '16 at 11:06
  • I am getting version name. How I can get versionCode by above code? – Ajit Sharma Jun 01 '16 at 06:18
  • @AjitSharma Call the method, and use the returned array. `String res[] = getAppVersionInfo("myplayurl"); String version = res[0];` –  Jun 01 '16 at 14:01
  • @Kilanny, I am doing tht but I am getting version name which is different from version code in android. eg. versionCode 1 & versionName "1.0". – Ajit Sharma Jun 02 '16 at 04:29
  • @AjitSharma Please see this to retrieve code/name http://stackoverflow.com/a/6593822/4795214 –  Jun 02 '16 at 11:39
  • @Kilanny, Yes right but I want VersionCode from Playstore so tht I can compare with my app versioncode. – Ajit Sharma Jun 03 '16 at 06:57
  • Google play gives you version name. So compare with version name, and get the version name of your current app using the above comment link. –  Jun 04 '16 at 11:35
  • `div[itemprop=softwareVersion]` is no longer used in play store, will not work anymore – digiwizkid Apr 06 '18 at 02:59
5

add compile 'org.jsoup:jsoup:1.10.2' to dependencies in APP LEVEL build.gradle

&

Just add below code and you are good to go.

private class GetVersionCode extends AsyncTask<Void, String, String> {
    @Override
    protected String doInBackground(Void... voids) {

        try {
            newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + SplashActivity.this.getPackageName() + "&hl=it")
                    .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();
            return newVersion;
        } catch (Exception e) {
            return newVersion;
        }
    }

    @Override
    protected void onPostExecute(String onlineVersion) {
        super.onPostExecute(onlineVersion);

        if (!currentVersion.equalsIgnoreCase(onlineVersion)) {
            //show dialog
            new AlertDialog.Builder(context)
                    .setTitle("Updated app available!")
                    .setMessage("Want to update app?")
                    .setPositiveButton("Update", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            // continue with delete
                            final String appPackageName = getPackageName(); // getPackageName() from Context or Activity object
                            try {
                                Toast.makeText(getApplicationContext(), "App is in BETA version cannot update", Toast.LENGTH_SHORT).show();
                                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
                            } catch (ActivityNotFoundException anfe) {
                                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
                            }
                        }
                    })
                    .setNegativeButton("Later", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            // do nothing
                            dialog.dismiss();
                            new MyAsyncTask().execute();
                        }
                    })
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .show();

        }
    }
}
Andi
  • 119
  • 2
  • 8
  • `div[itemprop=softwareVersion]` is no longer used in play store page, will not work anymore. – digiwizkid Apr 06 '18 at 02:57
  • yes, `div[itemprop=softwareVersion]` is not worked in my app anymore. Now, How can i use **jsop** library for get latest version of the app? – viren kheni Apr 10 '18 at 09:33
2

There is no API for this, and you can't auto install it, you can just redirect them to it's Market page so they can upgrade. You can have your latest version in a file on a Web server, and have the app check it. Here's one implementation of this:

http://code.google.com/p/openintents/source/browse/#svn%2Ftrunk%2FUpdateCheckerApp

Nikolay Elenkov
  • 52,576
  • 10
  • 84
  • 84
  • For future reference, the application seems to be [here](https://github.com/openintents/openintents/tree/master/UpdateCheckerApp) now. – Smar Mar 30 '16 at 11:12
1

I did using in-app updates. This will only with devices running Android 5.0 (API level 21) or higher,

Chathz
  • 723
  • 4
  • 16
  • 41
1

Here's how to find the current and latest available versions:

       try {
            String curVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
            String newVersion = curVersion;
            newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + getPackageName() + "&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.hAyfc:nth-child(4) .IQ1z0d .htlgb")
                    .first()
                    .ownText();
            Log.d("Curr Version" , curVersion);
            Log.d("New Version" , newVersion);

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
Alftheo
  • 868
  • 7
  • 17
zafar Khan
  • 21
  • 1
0

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

Community
  • 1
  • 1
Mohammad
  • 6,024
  • 3
  • 22
  • 30
0

I know the OP was very old, at that time in-app-update was not available. But from API 21, you can use in-app-update checking. You may need to keep your eyes on some points which are nicely written up here:

Junaed
  • 1,457
  • 13
  • 15
0

We can check Update by Add these Code:

First we need to add dependencies :

implementation 'org.jsoup:jsoup:1.10.2'

Second we need to create Java File:

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.widget.Toast;

import org.jsoup.Jsoup;

public class CurrentVersion{
    private Activity activity;
    public CurrentVersion(Activity activity) {
        this.activity = activity;
    }
    //current version of app installed in the device
private String getCurrentVersion(){
        PackageManager pm = activity.getPackageManager();
        PackageInfo pInfo = null;
        try {
        pInfo = pm.getPackageInfo(activity.getPackageName(),0);
        } catch (PackageManager.NameNotFoundException e1) {
        e1.printStackTrace();
        }
        return pInfo.versionName;
        }
private class GetLatestVersion extends AsyncTask<String, String, String> {
    private String latestVersion;
    private ProgressDialog progressDialog;
    private boolean manualCheck;
    GetLatestVersion(boolean manualCheck) {
        this.manualCheck = manualCheck;
    }
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        if (manualCheck)
        {
            if (progressDialog!=null)
            {
                if (progressDialog.isShowing())
                {
                    progressDialog.dismiss();
                }
            }
        }
        String currentVersion = getCurrentVersion();
        //If the versions are not the same
        if(!currentVersion.equals(latestVersion)&&latestVersion!=null){
            final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
            builder.setTitle("An Update is Available");
            builder.setMessage("Its better to update now");
            builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    //Click button action
                    activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id="+activity.getPackageName())));
                    dialog.dismiss();
                }
            });
            builder.setCancelable(false);
            builder.show();
        }
        else {
            if (manualCheck) {
                Toast.makeText(activity, "No Update Available", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    protected String doInBackground(String... params) {
        try {
            //It retrieves the latest version by scraping the content of current version from play store at runtime
            latestVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + activity.getPackageName() + "&hl=it")
                    .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(".hAyfc .htlgb")
                    .get(7)
                    .ownText();
            return latestVersion;
        } catch (Exception e) {
            return latestVersion;
        }
    }
}
    public void checkForUpdate(boolean manualCheck)
    {
        new GetLatestVersion(manualCheck).execute();
    }
}

Third We need to add this class in your main class where you want to show the update:

AppUpdateChecker appUpdateChecker=new AppUpdateChecker(this); 
appUpdateChecker.checkForUpdate(false);

I hope it will help you

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Raiyan Shahid
  • 49
  • 1
  • 3
0

Using jsoup HTML parser library @ https://jsoup.org/

implementation 'org.jsoup:jsoup:1.13.1'

You can simply create a method for that;

private void IsUpdateAvailable() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            String newversion = "no";
            String newversiondot = "no";
            try {
                newversiondot = Jsoup.connect("https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID + "&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.hAyfc:nth-child(4) > span:nth-child(2) > div:nth-child(1) > span:nth-child(1)")
                        .first()
                        .ownText();

                newversion = newversiondot.replaceAll("[^0-9]", "");

            } catch (IOException e) {
                Log.d("TAG NEW", "run: " + e);
            }

            final String finalNewversion = newversion;
            final String finalNewversiondot = newversiondot;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (Integer.parseInt(finalNewversion) > Integer.parseInt(getApplicationContext().getPackageManager().getPackageInfo(BuildConfig.APPLICATION_ID, 0).versionName.replaceAll("[^0-9]", ""))) {
                            showDialog(UsersActivity.this, "Version: "+finalNewversiondot);
                        }
                    } catch (PackageManager.NameNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }).start();
}
Lakpriya Senevirathna
  • 2,488
  • 2
  • 17
  • 35