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

流过昼夜 提交于 2019-11-27 00:27:51
Horacio Solorio

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

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());
    });

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())));
    }

}

Firebase Remote Config can help best here,

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

Apart from using JSoup, we can alternatively do pattern matching for getting the app version from playStore.

To match the latest pattern from google playstore ie <div class="BgcNfc">Current Version</div><span class="htlgb"><div><span class="htlgb">X.X.X</span></div> we first have to match the above node sequence and then from above sequence get the version value. Below is the code snippet for same:

    private String getAppVersion(String patternString, String inputString) {
        try{
            //Create a pattern
            Pattern pattern = Pattern.compile(patternString);
            if (null == pattern) {
                return null;
            }

            //Match the pattern string in provided string
            Matcher matcher = pattern.matcher(inputString);
            if (null != matcher && matcher.find()) {
                return matcher.group(1);
            }

        }catch (PatternSyntaxException ex) {

            ex.printStackTrace();
        }

        return null;
    }


    private String getPlayStoreAppVersion(String appUrlString) {
        final String currentVersion_PatternSeq = "<div[^>]*?>Current\\sVersion</div><span[^>]*?>(.*?)><div[^>]*?>(.*?)><span[^>]*?>(.*?)</span>";
        final String appVersion_PatternSeq = "htlgb\">([^<]*)</s";
        String playStoreAppVersion = null;

        BufferedReader inReader = null;
        URLConnection uc = null;
        StringBuilder urlData = new StringBuilder();

        final URL url = new URL(appUrlString);
        uc = url.openConnection();
        if(uc == null) {
           return null;
        }
        uc.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
        inReader = new BufferedReader(new InputStreamReader(uc.getInputStream()));
        if (null != inReader) {
            String str = "";
            while ((str = inReader.readLine()) != null) {
                           urlData.append(str);
            }
        }

        // Get the current version pattern sequence 
        String versionString = getAppVersion (currentVersion_PatternSeq, urlData.toString());
        if(null == versionString){ 
            return null;
        }else{
            // get version from "htlgb">X.X.X</span>
            playStoreAppVersion = getAppVersion (appVersion_PatternSeq, versionString);
        }

        return playStoreAppVersion;
    }

I got this solved through this. This also solves the latest changes done by Google in PlayStore. Hope that helps.

Use server API which will store version info

Like you said.This is an easy way to detect an update. Pass your version info with every API calls. When playstore is updated change the version in server. Once the server version is higher than installed app version, you can return a status code/message in API response which can be handled and update message can be showed. You can also block users from using very old app like WhatsApp do if u use this method.

Or you can use push notification, which is easy to do...Also

Full source code for this solution: https://stackoverflow.com/a/50479184/5740468

import android.os.AsyncTask;
import android.support.annotation.Nullable;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class GooglePlayAppVersion extends AsyncTask<String, Void, String> {

    private final String packageName;
    private final Listener listener;
    public interface Listener {
        void result(String version);
    }

    public GooglePlayAppVersion(String packageName, Listener listener) {
        this.packageName = packageName;
        this.listener = listener;
    }

    @Override
    protected String doInBackground(String... params) {
        return getPlayStoreAppVersion(String.format("https://play.google.com/store/apps/details?id=%s", packageName));
    }

    @Override
    protected void onPostExecute(String version) {
        listener.result(version);
    }

    @Nullable
    private static String getPlayStoreAppVersion(String appUrlString) {
        String
              currentVersion_PatternSeq = "<div[^>]*?>Current\\sVersion</div><span[^>]*?>(.*?)><div[^>]*?>(.*?)><span[^>]*?>(.*?)</span>",
              appVersion_PatternSeq = "htlgb\">([^<]*)</s";
        try {
            URLConnection connection = new URL(appUrlString).openConnection();
            connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                StringBuilder sourceCode = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) sourceCode.append(line);

                // Get the current version pattern sequence
                String versionString = getAppVersion(currentVersion_PatternSeq, sourceCode.toString());
                if (versionString == null) return null;

                // get version from "htlgb">X.X.X</span>
                return getAppVersion(appVersion_PatternSeq, versionString);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Nullable
    private static String getAppVersion(String patternString, String input) {
        try {
            Pattern pattern = Pattern.compile(patternString);
            if (pattern == null) return null;
            Matcher matcher = pattern.matcher(input);
            if (matcher.find()) return matcher.group(1);
        } catch (PatternSyntaxException e) {
            e.printStackTrace();
        }
        return null;
    }

}

Usage:

new GooglePlayAppVersion(getPackageName(), version -> 
    Log.d("TAG", String.format("App version: %s", version)
).execute();
lganzzzo

I will recommend to use ex. push notification to notify your app that there is a new update, OR use your own server to enable your app read version from there.

Yes its additional work each time you update your app, but in this case your are not depended on some "unofficial" or third party things that may run out of service.

Just in case you missed something - previous discussion of your topic query the google play store for the version of an app?

You can call the following WebService: http://carreto.pt/tools/android-store-version/?package=[YOUR_APP_PACKAGE_NAME]

Example Using Volley:

String packageName = "com.google.android.apps.plus";
String url = "http://carreto.pt/tools/android-store-version/?package=";
JsonObjectRequest jsObjRequest = new JsonObjectRequest
    (Request.Method.GET, url+packageName, null, new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        /*
                                here you have access to:

                                package_name, - the app package name
                                status - success (true) of the request or not (false)
                                author - the app author
                                app_name - the app name on the store
                                locale - the locale defined by default for the app
                                publish_date - the date when the update was published
                                version - the version on the store
                                last_version_description - the update text description
                             */
                        try{
                            if(response != null && response.has("status") && response.getBoolean("status") && response.has("version")){
                                Toast.makeText(getApplicationContext(), response.getString("version").toString(), Toast.LENGTH_LONG).show();
                            }
                            else{
                                //TODO handling error
                            }
                        }
                        catch (Exception e){
                            //TODO handling error
                        }

                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        //TODO handling error
                    }
        });

the easiest way is using firebase package from google and using remote notifications or realtime config with the new version and sent id to the users below up version number see more https://firebase.google.com/

the benefits here thay you'll be able to check version number instead of name, that should be more convinient :) At the other hand - you should take care of updating version in api/firebase each time after release.

  • take version from google play web page. I have implemented this way, and it works more that 1 year, but during this time i have to change 'matcher' 3-4 times, because content on the web page were changed. Also it some head ache to check it from time to time, because you can't know where it can be changed. but if you still want to use this way, here is my kotlin code based on okHttp:

    private fun getVersion(onChecked: OnChecked, packageName: String) {
    
    Thread {
        try {
            val httpGet = HttpGet("https://play.google.com/store/apps/details?id="
                    + packageName + "&hl=it")
    
            val response: HttpResponse
            val httpParameters = BasicHttpParams()
            HttpConnectionParams.setConnectionTimeout(httpParameters, 10000)
            HttpConnectionParams.setSoTimeout(httpParameters, 10000)
            val httpclient = DefaultHttpClient(httpParameters)
            response = httpclient.execute(httpGet)
    
            val entity = response.entity
            val `is`: InputStream
            `is` = entity.content
            val reader: BufferedReader
            reader = BufferedReader(InputStreamReader(`is`, "iso-8859-1"), 8)
            val sb = StringBuilder()
            var line: String? = null
            while ({ line = reader.readLine(); line }() != null) {
                sb.append(line).append("\n")
            }
    
            val resString = sb.toString()
            var index = resString.indexOf(MATCHER)
            index += MATCHER.length
            val ver = resString.substring(index, index + 6) //6 is version length
            `is`.close()
            onChecked.versionUpdated(ver)
            return@Thread
        } catch (ignore: Error) {
        } catch (ignore: Exception) {
        }
    
        onChecked.versionUpdated(null)
    }.start()
    }
    

I suspect that the main reason for requesting app's version is for prompting user for update. I am not in favour of scrapping 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
}
Vikram Sahu

Using Jquery

$.get("https://play.google.com/store/apps/details?id=--bundleID--", function(data){
        htmlContentsArray=$('<div/>').html(data).contents();
        htmlContents=htmlContentsArray['prevObject']['0']['childNodes']['141'].outerText;
        if(htmlContents == ''){
            htmlContents=htmlContentsArray['prevObject']['0']['childNodes']['144'].outerText;
        }
        latest_version_array=htmlContents.split('Current Version');
            var latest_version_string=latest_version_array['1'];
            var latest_version=latest_version_string.substr(0,5);
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!