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 applicatio
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())));
}
}
My workaround is to parse the Google Play website and extract the version number. If you're facing CORS issue or want to save bandwidth on the user's device, consider to run it from your web server.
let ss = [html];
for (let p of ['div', 'span', '>', '<']) {
let acc = [];
ss.forEach(s => s.split(p).forEach(s => acc.push(s)));
ss = acc;
}
ss = ss
.map(s => s.trim())
.filter(s => {
return parseFloat(s) == +s;
});
console.log(ss); // print something like [ '1.10' ]
You can get the html text by fetching https://play.google.com/store/apps/details?id=your.package.name
. For comparability, you may use https://www.npmjs.com/package/cross-fetch which works on both browser and node.js.
Others have mentioned parsing the html from Google Play website with certain css class or pattern like "Current Version" but these methods may not be as robust. Because Google could change the class name any time. It may as well return text in different language according to the users' locale preference, so you may not get the word "Current Version".
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()
}
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.
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/
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());
});
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;
}
}
}
}
}