query the google play store for the version of an app?
Found a suitable API via G+:
this is the API: https://androidquery.appspot.com
example call: https://androidquery.appspot.com/api/market?app=org.ligi.fast
and this wrapper/code: https://github.com/androidquery/androidquery
Android get Google Play Store app version
Just replace your code
.get()
.select("div[itemprop=softwareVersion]")
.first()
.ownText();
with below:
.get()
.select(".hAyfc .htlgb")
.get(3)
.ownText();
it will work..!
Programmatically check Play Store for app updates
Update 17 October 2019
https://developer.android.com/guide/app-bundle/in-app-updates
Update 24 april 2019:
Android announced a feature which will probably fix this problem. Using the in-app Updates API:
https://android-developers.googleblog.com/2018/11/unfolding-right-now-at-androiddevsummit.html
Original:
As far a I know, there is no official Google API which supports this.
You should consider to get a version number from an API.
Instead of connecting to external APIs or webpages (like Google Play Store).
There is a risk that something may change in the API or the webpage, so you should consider to check if the version code of the current app is below the version number you get from your own API.
Just remember if you update your app, you need to change the version in your own API with the app version number.
I would recommend that you make a file in your own website or API, with the version number. (Eventually make a cronjob and make the version update automatic, and send a notification when something goes wrong)
You have to get this value from your Google Play Store page (is changed in the meantime, not working anymore):
<div class="content" itemprop="softwareVersion"> x.x.x </div>
Check in your app if the version used on the mobile is below the version nummer showed on your own API.
Show indication that she/he needs to update with a notification, ideally.
Things you can do
Version number using your own API
Pros:
- No need to load the whole code of the Google Play Store (saves on data/bandwidth)
Cons:
- User can be offline, which makes checking useless since the API can't be accessed
Version number on webpage Google Play Store
Pros:
- You don't need an API
Cons:
- User can be offline, which makes checking useless since the API can't be accessed
- Using this method may cost your users more bandwidth/mobile data
- Play store webpage could change which makes your version 'ripper' not work anymore.
Getting versionCode and VersionName from Google Play
There is no official Google Play API, Playstore uses an internal protobuf API which is not documented and not open. IMHO, you could :
- use an open source library that reverse engineer the API
- scrap apk download sites that have already extracted this information (most likely via the same protobuf Google Play API)
Note that there is a Google Play developer API but you can't list your apks, versions, apps. It's essentially used to manage the app distribution, reviews, edits etc..
Google play internal API
play-store-api Java library
This library uses Google Play Store protobuf API (undocumented and closed API) and requires an email/password to generate a token that can be reused to play with the API :
GplaySearch googlePlayInstance = new GplaySearch();
DetailsResponse response = googlePlayInstance.getDetailResponse("user@gmail.com",
"password", "com.facebook.katana");
AppDetails appDetails = response.getDocV2().getDetails().getAppDetails();
System.out.println("version name : " + appDetails.getVersionString());
System.out.println("version code : " + appDetails.getVersionCode());
with this method :
public DetailsResponse getDetailResponse(String email,
String password,
String packageName) throws IOException, ApiBuilderException {
// A device definition is required to log in
// See resources for a list of available devices
Properties properties = new Properties();
try {
properties.load(getClass().getClassLoader().getSystemResourceAsStream("device-honami" +
".properties"));
} catch (IOException e) {
System.out.println("device-honami.properties not found");
return null;
}
PropertiesDeviceInfoProvider deviceInfoProvider = new PropertiesDeviceInfoProvider();
deviceInfoProvider.setProperties(properties);
deviceInfoProvider.setLocaleString(Locale.ENGLISH.toString());
// Provide valid google account info
PlayStoreApiBuilder builder = new PlayStoreApiBuilder()
.setDeviceInfoProvider(deviceInfoProvider)
.setHttpClient(new OkHttpClientAdapter())
.setEmail(email)
.setPassword(password);
GooglePlayAPI api = builder.build();
// We are logged in now
// Save and reuse the generated auth token and gsf id,
// unless you want to get banned for frequent relogins
api.getToken();
api.getGsfId();
// API wrapper instance is ready
return api.details(packageName);
}
device-honami.properties
is device property file that is required to identify device characteristics. You have some device.properties file sample here
The OkHttpClientAdapter
can be found here
Dependencies used to run this example :
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
compile 'com.github.yeriomin:play-store-api:0.19'
compile 'com.squareup.okhttp3:okhttp:3.8.1'
}
Scrap third part apk download sites
http://apk-dl.com
You could get the version name & version code from http://apk-dl.com (of course unofficial) by scraping the page with jsoup for the required package name :
String packageName = "com.facebook.katana";
Document doc = Jsoup.connect("http://apk-dl.com/" + packageName).get();
Elements data = doc.select(".file-list .mdl-menu__item");
if (data.size() > 0) {
System.out.println("full text : " + data.get(0).text());
Pattern pattern = Pattern.compile("(.*)\\s+\\((\\d+)\\)");
Matcher matcher = pattern.matcher(data.get(0).text());
if (matcher.find()) {
System.out.println("version name : " + matcher.group(1));
System.out.println("version code : " + matcher.group(2));
}
}
https://apkpure.com
Another possibility is scrapping https://apkpure.com :
String packageName = "com.facebook.katana";
Elements data = Jsoup.connect("https://apkpure.com/search?q=" + packageName)
.userAgent("Mozilla")
.get().select(".search-dl .search-title a");
if (data.size() > 0) {
Elements data2 = Jsoup.connect("https://apkpure.com" + data.attr("href"))
.userAgent("Mozilla")
.get().select(".faq_cat dd p");
if (data2.size() > 0) {
System.out.println(data2.get(0).text());
Pattern pattern = Pattern.compile("Version:\\s+(.*)\\s+\\((\\d+)\\)");
Matcher matcher = pattern.matcher(data2.get(0).text());
if (matcher.find()) {
System.out.println("version name : " + matcher.group(1));
System.out.println("version code : " + matcher.group(2));
}
}
}
https://api-apk.evozi.com
Also, https://api-apk.evozi.com has an internal JSON api but :
- sometimes it doesn't work (return
Ops, APK Downloader got access denied when trying to download
) mostly for non popular app - it has mechanism in place against scraping bot (random token generated in JS with a random variable name)
The following is returning the version name and code with https://api-apk.evozi.com FWIW :
String packageName = "com.facebook.katana";
String data = Jsoup.connect("https://apps.evozi.com/apk-downloader")
.userAgent("Mozilla")
.execute().body();
String token = "";
String time = "";
Pattern varPattern = Pattern.compile("dedbadfbadc:\\s+(\\w+),");
Pattern timePattern = Pattern.compile("t:\\s+(\\w+),");
Matcher varMatch = varPattern.matcher(data);
Matcher timeMatch = timePattern.matcher(data);
if (varMatch.find()) {
Pattern tokenPattern = Pattern.compile("\\s*var\\s*" + varMatch.group(1) + "\\s*=\\s*'(.*)'.*");
Matcher tokenMatch = tokenPattern.matcher(data);
if (tokenMatch.find()) {
token = tokenMatch.group(1);
}
}
if (timeMatch.find()) {
time = timeMatch.group(1);
}
HttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("https://api-apk.evozi.com/download");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("t", time));
params.add(new BasicNameValuePair("afedcfdcbdedcafe", packageName));
params.add(new BasicNameValuePair("dedbadfbadc", token));
params.add(new BasicNameValuePair("fetch", "false"));
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
HttpResponse response = httpclient.execute(httppost);
JsonElement element = new JsonParser().parse(EntityUtils.toString(response.getEntity()));
JsonObject result = element.getAsJsonObject();
if (result.has("version") && result.has("version_code")) {
System.out.println("version name : " + result.get("version").getAsString());
System.out.println("version code : " + result.get("version_code").getAsInt());
} else {
System.out.println(result);
}
Implementation
You could implement it on a backend of yours that communicates directly with your Java application, this way you could maintain the process of retrieving version code/name if one of the above method fails.
If you are only interested in your own apps, a cleaner solution would be :
- to set up a backend which will store all your current app version name / version code
- all developer/publisher in your company could share a publish task (gradle task) which will use the Google Play developer API to publish apk and that gradle task would include a call to your backend to store the version code / version name entry when the app is published. The main goal would be to automate the whole publication with storage of the app metadata on your side.
Fetching application version from play store inside Android
I do not experience the certificate error with curl. Perhaps ensure your packages including certificate store are up-to-date?
As a general habit I suggest surrounding the URL in quotes as some common url characters can be interpreted by the shell. The following snippet retrieves the app version from the play url:
$ curl -s 'https://play.google.com/store/apps/details?id=org.thoughtcrime.redphone' | xmllint --xpath "//div[@itemprop='softwareVersion']/text()" --html - 2> /dev/null
0.9.6
I notice that google applications have application versions that vary by device:
$ curl -s 'https://play.google.com/store/apps/details?id=com.google.android.apps.maps' | xmllint --xpath "//div[@itemprop='softwareVersion']/text()" --html - 2> /dev/null
Varies with device
Related Topics
Yuv to Rgb Conversion by Fragment Shader
Android: Drawing Custom Shapes
Android: Subscribe to Firebase Cloud Messaging(Fcm) Topic
How to Know If a Fragment Is Visible
How to Use Default Android Drawables
Mediaplayer Setdatasource, Better to Use Path or Filedescriptor
Httpclient on Android:Nohttpresponseexception Through Umts/3G
How to Check If Music Is Playing by Using a Broadcast Receiver
Dependencies' Cannot Be Applied to '(Groovy.Lang.Closure)'
How to Close the Status Bar/Notification Panel After Notification Button Click
Why Is Calling Process.Killprocess(Process.Mypid()) a Bad Idea
Android Audiotrack Playing .Wav File, Getting Only White Noise
Android Studio 4.1 Plugin Error: Plugin * Is Incompatible (Supported Only in Intellij Idea)
Get Current Visible Text in Textview
Android 4.4 Giving Err_Cache_Miss Error in Onreceivederror for Webview Back