How to get app market version information from google play store?

88,865

Solution 1

I recomned dont use a library just create a new class

1.

public 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=" + "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.hAyfc:nth-child(4) > span:nth-child(2) > div:nth-child(1) > span:nth-child(1)")
                .first()
                .ownText();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return newVersion;
}
  1. In your activity:

        VersionChecker versionChecker = new VersionChecker();
        String latestVersion = versionChecker.execute().get();
    

THAT IS ALL

Solution 2

Current solution

This is super hacky, but best I could come up quickly. Seemed to work with all apps I tried. PHP solution, but you can just pick the preg_match() regex part for any other language.

public function getAndroidVersion(string $storeUrl): string
{
    $html = file_get_contents($storeUrl);
    $matches = [];
    preg_match('/\[\[\[\"\d+\.\d+\.\d+/', $html, $matches);
    if (empty($matches) || count($matches) > 1) {
        throw new Exception('Could not fetch Android app version info!');
    }
    return substr(current($matches), 4);
}

Solution until May 2022 (NO LONGER WORKS)

Using PHP backend. This has been working for a year now. It seems Google does not change their DOM that often.

public function getAndroidVersion(string $storeUrl): string
{
    $dom = new DOMDocument();
    $dom->loadHTML(file_get_contents($storeUrl));
    libxml_use_internal_errors(false);
    $elements = $dom->getElementsByTagName('span');

    $depth = 0;
    foreach ($elements as $element) {
        foreach ($element->attributes as $attr) {
            if ($attr->nodeName === 'class' && $attr->nodeValue === 'htlgb') {
                $depth++;
                if ($depth === 7) {
                    return preg_replace('/[^0-9.]/', '', $element->nodeValue);
                    break 2;
                }
            }
        }
    }
}

Even older version (NO LONGER WORKS)

Here is jQuery version to get the version number if anyone else needs it.

    $.get("https://play.google.com/store/apps/details?id=" + packageName + "&hl=en", function(data){
        console.log($('<div/>').html(data).contents().find('div[itemprop="softwareVersion"]').text().trim());
    });

Solution 3

I suspect that the main reason for requesting app's version is for prompting user for update. I am not in favour of scraping the response, because this is something that could break functionality in future versions.

If app's minimum version is 5.0, you can implement in-app update according to the documentation https://developer.android.com/guide/app-bundle/in-app-updates

If the reason of requesting apps version is different, you can still use the appUpdateManager in order to retrieve the version and do whatever you want (e.g. store it in preferences).

For example we can modify the snippet of the documentation to something like that:

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

// Returns an intent object that you use to check for an update.
val appUpdateInfoTask = appUpdateManager.appUpdateInfo

// Checks that the platform will allow the specified type of update.
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
    val version = appUpdateInfo.availableVersionCode()
    //do something with version. If there is not a newer version it returns an arbitary int
}

Solution 4

Use this code its perfectly working fine.

public void forceUpdate(){
    PackageManager packageManager = this.getPackageManager();
    PackageInfo packageInfo = null;
    try {
        packageInfo =packageManager.getPackageInfo(getPackageName(),0);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    String currentVersion = packageInfo.versionName;
    new ForceUpdateAsync(currentVersion,TodayWork.this).execute();
}

public class ForceUpdateAsync extends AsyncTask<String, String, JSONObject> {

    private String latestVersion;
    private String currentVersion;
    private Context context;
    public ForceUpdateAsync(String currentVersion, Context context){
        this.currentVersion = currentVersion;
        this.context = context;
    }

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

        try {
            latestVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + context.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(3) > span:nth-child(2) > div:nth-child(1) > span:nth-child(1)")
                    .first()
                    .ownText();
            Log.e("latestversion","---"+latestVersion);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return new JSONObject();
    }

    @Override
    protected void onPostExecute(JSONObject jsonObject) {
        if(latestVersion!=null){
            if(!currentVersion.equalsIgnoreCase(latestVersion)){
                // Toast.makeText(context,"update is available.",Toast.LENGTH_LONG).show();
                if(!(context instanceof SplashActivity)) {
                    if(!((Activity)context).isFinishing()){
                        showForceUpdateDialog();
                    }
                }
            }
        }
        super.onPostExecute(jsonObject);
    }

    public void showForceUpdateDialog(){

        context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName())));
    }

}

Solution 5

Firebase Remote Config can help best here,

Please refer this answer https://stackoverflow.com/a/45750132/2049384

Share:
88,865
ravidl
Author by

ravidl

Android enthusiast and love to program and develop android apps.

Updated on July 09, 2022

Comments

  • ravidl
    ravidl almost 2 years

    How can I get the application version information from google play store for prompting the user for force/recommended an update of the application when play store application is updated i.e. in case of the user is using old version application. I have already gone through andorid-market-api which is not the official way and also requires oauth login authentication from google. I have also gone through android query which provides in-app version check, but it is not working in my case. I found the following two alternatives:

    • Use server API which will store version info
    • Use google tags and access it in-app, which is not a preferred way to go.

    Are there any other ways to do it easily?

  • ravidl
    ravidl over 8 years
    I have tried android-market-api, which is not working now. I have also tried android-query and it is no more working.
  • ravidl
    ravidl over 8 years
    I'm looking for the solution other than server API. Thanks for the reply!
  • Joe Aspara
    Joe Aspara over 8 years
    Yes, android-market-api seems doesn't work anymore for me too.
  • ravidl
    ravidl about 8 years
    what will be the output of this? I'm not getting this! Is it output version info? If yes, then in what format?
  • Horacio Solorio
    Horacio Solorio about 8 years
    you will get a string of the versionName, you can find this version name in the file "build.gradle".
  • Brad Montgomery
    Brad Montgomery about 8 years
    This is a hack. But it's a really nice hack that doesn't require much effort, especially considering that Google makes it hard to work with their apis. +1. :)
  • Sandro Wiggers
    Sandro Wiggers almost 8 years
    Nice hack, but not necessary anymore since this: github.com/googlesamples/android-play-publisher-api/tree/mas‌​ter/…
  • Sandro Wiggers
    Sandro Wiggers almost 8 years
  • Sandro Wiggers
    Sandro Wiggers almost 8 years
  • Sandro Wiggers
    Sandro Wiggers almost 8 years
  • yUdoDis
    yUdoDis over 7 years
    Thank you...a hack but beautiful.
  • chintan mahant
    chintan mahant about 7 years
    How to Use in Cakephp 2.0
  • chintan mahant
    chintan mahant about 7 years
    How to Use in Cakephp 2.0
  • Anuj
    Anuj over 6 years
    i need for ionic but when i am using it then getting some cors issue ,
  • Aleksander Mielczarek
    Aleksander Mielczarek over 6 years
    @SandroWiggers which method from official API does check app version?
  • zulkarnain shah
    zulkarnain shah over 6 years
    Ya it can fail for a number of reasons. e.g., 1. Google changes the keys that you use in select("div[itemprop=softwareVersion]"). The best thing to do is to maintain an API on your own server that gives you the current market version of your app which you can then compare with the one installed on the users device
  • vincent
    vincent over 6 years
    This just broken. If you're using regular expression instead you can use <div[^>]*?>Current Version</div><div><span[^>]*?>(.*?)</span></div>
  • bkm
    bkm about 6 years
    True this way is broken. The expression you provided is also not working @vincent
  • vincent
    vincent about 6 years
    @bkm They seem to be changing it atm. Let's see what ends up being "stable".
  • Drarok
    Drarok about 6 years
    This is super brittle. How do I know? An app I've inherited does this and has started crashing hard today.
  • Cesar
    Cesar about 6 years
    I got this working after fixing the pattern with "\s" between Current Version: <div[^>]*?>Current\sVersion</div><div><span[^>]*?>(.*?)</spa‌​n></div>
  • bkm
    bkm about 6 years
    .select("<div[^>]*?>Current\\sVersion</div><div><span[^>]*?>‌​(.*?)</span></div>") produces this error Method threw 'org.jsoup.select.Selector$SelectorParseException' exception @Cesar
  • Vrajesh
    Vrajesh about 6 years
    For android user add this dependency in gradle file, compile 'org.jsoup:jsoup:1.11.3'
  • Ian Warburton
    Ian Warburton almost 6 years
    Every API call seems like overkill to me.
  • shijin
    shijin almost 6 years
    Don't add a new api call. Add version information in api. refer github.com/mindhaq/restapi-versioning-spring
  • TejpalBh
    TejpalBh almost 6 years
    Seriously man.. I'm just trying trying n trying since morning finally this one worked... Thank you so much...
  • Сергей
    Сергей almost 6 years
    I'll post the full code using AsynsTask with your permission
  • rraallvv
    rraallvv about 5 years
    So, has anyone tried the android-play-publisher-api to get the current version number? I skimmed through the code but didn't find any hint that it could be used for that.
  • Dominik
    Dominik almost 5 years
    Is there no official way to do this. I mean you just read the html website. Not the prettiest way.
  • Lukas
    Lukas almost 5 years
    But if you use this method, the update needs to be reviewed by the google team and how do you know when to change the version in the API?
  • ge0rg
    ge0rg over 4 years
    This is also downloading a huge pile of HTML data (as of today it's 780 Kilobytes) over the user's mobile data connection. Not everybody is in California and has an unlimited data plan. This code is not just not robust, it's also a huge nuisance to users.
  • Beeno Tung
    Beeno Tung over 4 years
    Not relaying on the word "Current Version" is more robust as the user may have different locacle preference
  • double-beep
    double-beep about 4 years
    While this code may solve the question, including an explanation of how and why this solves the problem, especially when the question has multiple good answers, would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply. From Review
  • Gi0rgi0s
    Gi0rgi0s over 3 years
    I don't see softwareVersion in output of this command. It's probably changed
  • Firze
    Firze over 3 years
    @Gi0rgi0s This has not been working for long time now. Their DOM has been stable thou. I have been parsing the DOM. Currently looking for class: htlgb
  • amoljdv06
    amoljdv06 over 2 years
    Best solution, this is an official way to get app update information
  • Samuel Hassid
    Samuel Hassid about 2 years
    Nowadays the regex is <div[^>]*?>Current Version</div><span[^>]*?><div[^>]*?><span[^>]*?>(.*?)</span>‌​</div></span>
  • MyTwoCents
    MyTwoCents about 2 years
    As of today . Play Store UI is updated and version is moved to a popup. This logic doesnt work any more :(
  • Martinedo
    Martinedo about 2 years
    thank you for the current solution, you saved me lot of time after Google updated the UI in May 2022