Related
I am using this code to get the Google Play Store app version but this is causing my app to hang. Please specify another way to get the app version or how I can use this code to make the app not hang and run successfully.
public class VersionChecker extends AsyncTask<String, String, String> {
private String newVersion;
#Override
protected String doInBackground(String... params) {
try {
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + "trai.gov.in.dnd" + "&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();
} catch (IOException e) {
e.printStackTrace();
}
return newVersion;
}
}
This is my code to get the app version from asynctask
VersionChecker versionChecker = new VersionChecker();
try {
String appVersionName = BuildConfig.VERSION_NAME;
String mLatestVersionName = versionChecker.execute().get();
if (versionChecker.compareVersionNames(appVersionName, mLatestVersionName) == -1) {
showAppUpdateDialog();
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
Just replace your code
.get()
.select("div[itemprop=softwareVersion]")
.first()
.ownText();
with below:
.get()
.select(".hAyfc .htlgb")
.get(3)
.ownText();
it will work..!
The problem arises because the element div [itemprop = softwareVersion] is no longer found on the Google Play website (therefore it no longer returns the version number), it should only be changed to a new query with the changes made by google on your website.
Note: Take into account that if the structure is changed again, this code must be changed.
I hope it helps
Update: 12/09/2019
public class VersionChecker extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
private String newVersion;
try {
Document document = Jsoup.connect("https://play.google.com/store/apps/details?id=" + "com.example.package" + "&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();
}
}
}
}
return newVersion;
}
}
Codigo Java
VersionChecker versionChecker = new VersionChecker();
try {
String latestVersion = versionChecker.execute().get();
String versionName = BuildConfig.VERSION_NAME.replace("-DEBUG","");
if (latestVersion != null && !latestVersion.isEmpty()) {
if (!latestVersion.equals(versionName)) {
showDialogToSendToPlayStore();
}else{
continueWithTheLogin();
}
}
Log.d("update", "Current version " + Float.valueOf(versionName) + ", Playstore version " + Float.valueOf(latestVersion));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
It seems you use the "app-version" shown on the Google Play Store website to trigger an "update popup" to your users and notify when a new version is available. First of all, Google Play Store website is changing often, so that's not very reliable as your app might not be able to "parse/handle" those changes. If you want to keep that approach, some other answers already explained how to parse the right HTML tag and how to do in the background correctly. Keep in mind your app will be still responsible for the "parsing", eventually you would do the parsing remotely on a web-server, and expose to your app a stable API endpoint to retrieve the "latest-version" of your own app. If you do not want to bother with parsing HTML tags or host your own API, there are third-party APIs that can do that for you. We provide one such API here: https://42matters.com/docs/app-market-data/android/apps/lookup (it returns a JSON object with the latest "version name" of the app).
You could also use https://github.com/danielemaddaluno/Android-Update-Checker to not implement your own code, under the hood it does more or less the same as you do.
Personally I would use a remote service like Firebase Remote Config https://firebase.google.com/docs/remote-config or a simple JSON file hosted on your website specifying the latest published version of your app (just remember to change it once the update of your app is really published on Google Play, nowadays it might take a while). Also, I would rather use the "versionCode" as explained here: https://developer.android.com/studio/publish/versioning
With this approach you could "trigger" the update when you want, more control on your side (especially in case you want to revert the "Please update" message, useful if you find a bug in the latest version you published)
Change this two lines
{
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")
....
you are using BuildConfig.APPLICATION_ID but you need package_name
BuildConfig is provided by Gradle. If you are not building using Gradle then you cannot access the package name using BuildConfig.
I would use Context.getPackageName() because the result is provided from the operating system, rather than a constant in build parameters.
You need to put it into AysncTask
//********* Check for Updated Version of APP
private class GetVersionCode extends AsyncTask<Void, String, String> {
String currentVersion = null;
#Override
protected String doInBackground(Void... voids) {
String newVersion = null;
try {
currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + Activity.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) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String onlineVersion) {
super.onPostExecute(onlineVersion);
if (onlineVersion != null && !onlineVersion.isEmpty()) {
if (!currentVersion.equalsIgnoreCase(onlineVersion)) {
//Todo code here
}
}
Log.d("update", "Current version " + currentVersion + "playstore version " + onlineVersion);
}
}
Google change the API from 'softwareVersion' to 'currentVersion' and we can get the same version using ".hAyfc .htlgb"
Below code will not work i.e.
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[itemprop=softwareVersion]").first().ownText();
Instead of above code just add this code, it will work fine i.e.
Document document = 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();
if(document != null) {
if(document.select(".hAyfc .htlgb").get(5) != null) {
latestVersion = document.select(".hAyfc .htlgb").get(5).ownText();
} else {
latestVersion = currentVersion;
}
}
Note: There is no official API to get the current application version from Google Play. So use the above code to get the current version. Sometimes get(5).ownText() will change as google is updating the Google Play site. [Previously it was working with get(2).ownText()].
just try this,
Replace the code ,
.get()
.select("div:containsOwn(Current Version)")
.next()
.text();
You can achieve this much easier using UpdateManager - https://developer.android.com/reference/com/google/android/things/update/UpdateManager
You can setup your Update Manager as such
// Creates instance of the manager.
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(this);
// Returns an intent object that you use to check for an update.
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
//On Success Listener
appUpdateInfoTask.addOnSuccessListener(this);
In your On Success method, you can call
result.availableVersionCode()
Which returns 0 when the version is not different. Which if it is different you can just pull this value from your app directly.
There are many posts about doing this in java, but I found that NSoup (the port of the JSoup library) doesn't work for me, so I failed to port it to c#/Xamarin. For multiplayer functions of a game I'm working on, I need to make sure clients are synced before starting multiplayer matchmaking. This means I have to force the user to update the app if there's a new version available before they're allowed to invite other players to matches, join quick matches, etc..
So when a user presses the "quick match" button, for example, I need to:
Check for the version name (im incrementing version name, not code, for breaking changes)
Compare the version name from that to the current version name installed
3.
-If the newer version name is greater than the current one, I need to give the user the option to update their app, and send them to the google play store page for my app if they choose 'yes'. Then I'll just let them update from there and our work is done.
-If the versions are the same, allow whatever the button's functionality (i.e sending them to the waiting room for matchmaking) to proceed.
Create the methods necessary to check for updates and act accordingly:
private void CheckUpdate(Action doIfUpToDate)
{
if(NeedUpdate())
{
Android.App.AlertDialog.Builder alert = new Android.App.AlertDialog.Builder(this);
alert.SetTitle("New Update");
alert.SetMessage("You must download the newest version of this to play multiplayer. Would you like to now?");
alert.SetCancelable(false);
alert.SetPositiveButton("Yes", new EventHandler<DialogClickEventArgs>((object sender, DialogClickEventArgs e) => GetUpdate()));
alert.SetNegativeButton("No", delegate{});
alert.Show();
}
else
{
doIfUpToDate.Invoke();
}
}
private bool NeedUpdate()
{
try
{
var curVersion = PackageManager.GetPackageInfo(PackageName, 0).VersionName;
var newVersion = curVersion;
string htmlCode;
//probably better to do in a background thread
using (WebClient client = new WebClient())
{
htmlCode = client.DownloadString("https://play.google.com/store/apps/details?id=" + PackageName + "&hl=en");
}
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlCode);
newVersion = doc.DocumentNode.SelectNodes("//div[#itemprop='softwareVersion']")
.Select(p => p.InnerText)
.ToList()
.First()
.Trim();
return String.Compare(curVersion, newVersion) < 0;
}
catch (Exception e)
{
Log.Error(TAG, e.Message);
Toast.MakeText(this, "Trouble validating app version for multiplayer gameplay.. Check your internet connection", ToastLength.Long).Show();
return true;
}
}
private void GetUpdate()
{
try
{
StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse("market://details?id=" + PackageName)));
}
catch (ActivityNotFoundException e)
{
//Default to the the actual web page in case google play store app is not installed
StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse("https://play.google.com/store/apps/details?id=" + PackageName)));
}
}
And then from a given button that could start a multiplayer game:
var quickMatchButton = FindViewById<Button>(Resource.Id.button_quick_game);
quickMatchButton.Click += new EventHandler((object sender, EventArgs e) => CheckUpdate(() => startQuickMatch()));
I put my app to Google Play, now I do something like adding new function, new UI, etc then re-upload app into Google Play.
So I want, when user launch app, if there is a new update, one dialog show to remind the user, allow them to update the latest version.
Google seems not provide any API to get app version, so is there any solution to do?
Try to store current version in their mobile and store newest version in your server.
When user launch app, check if it different, app will display dialog to remind use download newest application.
EDIT:
Check it comment:
https://stackoverflow.com/a/14512102/4531387
Use Jsoup library and follow these steps:
1.add the dependency in your app level build.gradle
compile 'org.jsoup:jsoup:1.10.2'
2. Add this class in your src
public class VersionChecker extends AsyncTask<String, String, String> {
private String newVersion;
#Override
protected String doInBackground(String... params) {
try {
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();
} catch (IOException e) {
e.printStackTrace();
}
return newVersion;
}}// add following lines to your code where you want to get live app version
VersionChecker versionChecker = new VersionChecker();try {
mLatestVersionName = versionChecker.execute().get();} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();}
I have put my app on the Google Play Store. It has been installed by lots of my company's customers. I understand the mechanism of how the app is intended to upgrade.
The users should check the auto-update check box in the Playstore app for each app they want to auto-update. However some users have unchecked it or not checked it in the first place.
The app i have written is for the care industry and is used by carers to deliver homecare. Some of our customers my have 1200 carers. They would have to call all the carers into the office to update the phones individually. This is obviously unacceptable.
Is there a way to programmatically check if there is an updated version of my app on the Play Store?
Could i have code that runs every time the user starts the app that checks the Play Store?
If there is an updated version then the user could be directed to the Playstore. This will mean it is not essential to have the auto-update checked.
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.
Include JSoup in your apps build.gradle file :
dependencies {
compile 'org.jsoup:jsoup:1.8.3'
}
and get current version like :
currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
And execute following thread :
private class GetVersionCode extends AsyncTask<Void, String, String> {
#Override
protected String doInBackground(Void... voids) {
String newVersion = null;
try {
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + MainActivity.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(".hAyfc .htlgb")
.get(7)
.ownText();
return newVersion;
} catch (Exception e) {
return newVersion;
}
}
#Override
protected void onPostExecute(String onlineVersion) {
super.onPostExecute(onlineVersion);
Log.d("update", "Current version " + currentVersion + "playstore version " + onlineVersion);
if (onlineVersion != null && !onlineVersion.isEmpty()) {
if (Float.valueOf(currentVersion) < Float.valueOf(onlineVersion)) {
//show dialog
}
}
}
For more details visit : http://revisitingandroid.blogspot.in/2016/12/programmatically-check-play-store-for.html
Firebase Remote Config could be a possible and reliable solution for now, since google didn't expose any api to it.
Check Firebase Remote Config Docs
Steps
1.Create a firebase project and add google_play_service.json to your project
2.Create keys like "android_latest_version_code" and "android_latest_version_name" in firebase console->Remote Config
3.Android Code
public void initializeFirebase() {
if (FirebaseApp.getApps(mContext).isEmpty()) {
FirebaseApp.initializeApp(mContext, FirebaseOptions.fromResource(mContext));
}
final FirebaseRemoteConfig config = FirebaseRemoteConfig.getInstance();
FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()
.setDeveloperModeEnabled(BuildConfig.DEBUG)
.build();
config.setConfigSettings(configSettings);
}
Get current version name and code
int playStoreVersionCode = FirebaseRemoteConfig.getInstance().getString(
"android_latest_version_code");
PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
int currentAppVersionCode = pInfo.versionCode;
if(playStoreVersionCode>currentAppVersionCode){
//Show update popup or whatever best for you
}
4. And keep firebase "android_latest_version_code" and "android_latest_version_name" upto date with your current production version name and code.
Firebase remote config works on both Android and IPhone.
You can get current Playstore Version using JSoup with some modification like below:
#Override
protected String doInBackground(Void... voids) {
String newVersion = null;
try {
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + MainActivity.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(".hAyfc .htlgb")
.get(7)
.ownText();
return newVersion;
} catch (Exception e) {
return newVersion;
}
}
#Override
protected void onPostExecute(String onlineVersion) {
super.onPostExecute(onlineVersion);
Log.d("update", "playstore version " + onlineVersion);
}
answer of #Tarun is not working anymore.
Google has introduced in-app updates API
The API currently supports two flows:
The “immediate” flow is a full-screen user experience that guides the user from download to update before they can use your app.
The “flexible flow” allows users to download the update while continuing to use your app.
There's AppUpdater library.
How to include:
Add the repository to your project build.gradle:
allprojects {
repositories {
jcenter()
maven {
url "https://jitpack.io"
}
}
}
Add the library to your module build.gradle:
dependencies {
compile 'com.github.javiersantos:AppUpdater:2.6.4'
}
Add INTERNET and ACCESS_NETWORK_STATE permissions to your app's Manifest:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Add this to your activity:
AppUpdater appUpdater = new AppUpdater(this);
appUpdater.start();
#Tarun answer was working perfectly.but now isnt ,due to the recent changes from Google on google play website.
Just change these from #Tarun answer..
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
Coming From a Hybrid Application POV.
This is a javascript example, I have a Update Available footer on my main menu. If an update is available (ie. my version number within the config file is less than the version retrieved, display the footer) This will then direct the user to the app/play store, where the user can then click the update button.
I also get the whats new data (ie Release Notes) and display these in a modal on login if its the first time on this version.
On device Ready, set your store URL
if (device.platform == 'iOS')
storeURL = 'https://itunes.apple.com/lookup?bundleId=BUNDLEID';
else
storeURL = 'https://play.google.com/store/apps/details?id=BUNDLEID';
The Update Available method can be ran as often as you like. Mine is ran every time the user navigates to the home screen.
function isUpdateAvailable() {
if (device.platform == 'iOS') {
$.ajax(storeURL, {
type: "GET",
cache: false,
dataType: 'json'
}).done(function (data) {
isUpdateAvailable_iOS(data.results[0]);
}).fail(function (jqXHR, textStatus, errorThrown) {
commsErrorHandler(jqXHR, textStatus, false);
});
} else {
$.ajax(storeURL, {
type: "GET",
cache: false
}).done(function (data) {
isUpdateAvailable_Android(data);
}).fail(function (jqXHR, textStatus, errorThrown) {
commsErrorHandler(jqXHR, textStatus, false);
});
}
}
iOS Callback: Apple have an API, so very easy to get
function isUpdateAvailable_iOS (data) {
var storeVersion = data.version;
var releaseNotes = data.releaseNotes;
// Check store Version Against My App Version ('1.14.3' -> 1143)
var _storeV = parseInt(storeVersion.replace(/\./g, ''));
var _appV = parseInt(appVersion.substring(1).replace(/\./g, ''));
$('#ft-main-menu-btn').off();
if (_storeV > _appV) {
// Update Available
$('#ft-main-menu-btn').text('Update Available');
$('#ft-main-menu-btn').click(function () {
openStore();
});
} else {
$('#ft-main-menu-btn').html(' ');
// Release Notes
settings.updateReleaseNotes('v' + storeVersion, releaseNotes);
}
}
Android Callback: PlayStore you have to scrape, as you can see the version is relatively easy to grab and the whats new i take the html instead of the text as this way I can use their formatting (ie new lines etc)
function isUpdateAvailable_Android(data) {
var html = $(data);
var storeVersion = html.find('div[itemprop=softwareVersion]').text().trim();
var releaseNotes = html.find('.whatsnew')[0].innerHTML;
// Check store Version Against My App Version ('1.14.3' -> 1143)
var _storeV = parseInt(storeVersion.replace(/\./g, ''));
var _appV = parseInt(appVersion.substring(1).replace(/\./g, ''));
$('#ft-main-menu-btn').off();
if (_storeV > _appV) {
// Update Available
$('#ft-main-menu-btn').text('Update Available');
$('#ft-main-menu-btn').click(function () {
openStore();
});
} else {
$('#ft-main-menu-btn').html(' ');
// Release Notes
settings.updateReleaseNotes('v' + storeVersion, releaseNotes);
}
}
The open store logic is straight forward, but for completeness
function openStore() {
var url = 'https://itunes.apple.com/us/app/appname/idUniqueID';
if (device.platform != 'iOS')
url = 'https://play.google.com/store/apps/details?id=appid'
window.open(url, '_system')
}
Ensure Play Store and App Store have been Whitelisted:
<access origin="https://itunes.apple.com"/>
<access origin="https://play.google.com"/>
Firebase Remote Config is better.
Quickly and easily update our applications without the need to publish a new build to the app
Implementing Remote Config on Android
Adding the Remote Config dependancy
compile 'com.google.firebase:firebase-config:9.6.0'
Once done, we can then access the FirebaseRemoteConfig instance throughout our application where required:
FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
Retrieving Remote Config values
boolean someBoolean = firebaseRemoteConfig.getBoolean("some_boolean");
byte[] someArray = firebaseRemoteConfig.getByteArray("some_array");
double someDouble = firebaseRemoteConfig.getDouble("some_double");
long someLong = firebaseRemoteConfig.getLong("some_long");
String appVersion = firebaseRemoteConfig.getString("appVersion");
Fetch Server-Side values
firebaseRemoteConfig.fetch(cacheExpiration)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
mFirebaseRemoteConfig.activateFetched();
// We got our config, let's do something with it!
if(appVersion < CurrentVersion){
//show update dialog
}
} else {
// Looks like there was a problem getting the config...
}
}
});
Now once uploaded the new version to playstore, we have to update the version number inside firebase. Now if it is new version the update dialog will display
Inside OnCreate method write below code..
VersionChecker versionChecker = new VersionChecker();
try {
latestVersion = versionChecker.execute().get();
Toast.makeText(getBaseContext(), latestVersion , Toast.LENGTH_SHORT).show();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
this gives you play store version of app..
then you have to check app version as below
PackageManager manager = getPackageManager();
PackageInfo info = null;
try {
info = manager.getPackageInfo(getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
assert info != null;
version = info.versionName;
after that you can compare it with store version and setup your own update screens
if(version.equals(latestVersion)){
Toast.makeText(getBaseContext(), "No Update" , Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getBaseContext(), "Update" , Toast.LENGTH_SHORT).show();
}
And add VersionChecker.class as below
public class VersionChecker extends AsyncTask<String, String, String> {
private 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(".hAyfc .htlgb")
.get(7)
.ownText();
} catch (IOException e) {
e.printStackTrace();
}
return newVersion;
}
}
Set up a server that exposes an HTTP url that reports the latest version, then use an AlarmManager to call that URL and see if the version on the device is the same as the latest version. If it isn't pop up a message or notification and send them to the market to upgrade.
There are some code examples: How to allow users to check for the latest app version from inside the app?
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 it solved through this, as this works for latest Google playstore changes also. Hope that helps.
private void CheckUPdate() {
VersionChecker versionChecker = new VersionChecker();
try
{ String appVersionName = BuildConfig.VERSION_NAME;
String mLatestVersionName = versionChecker.execute().get();
if(!appVersionName.equals(mLatestVersionName)){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this);
alertDialog.setTitle("Please update your app");
alertDialog.setMessage("This app version is no longer supported. Please update your app from the Play Store.");
alertDialog.setPositiveButton("UPDATE NOW", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final String appPackageName = getPackageName();
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + appPackageName)));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
}
}
});
alertDialog.show();
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
#SuppressLint("StaticFieldLeak")
public class VersionChecker extends AsyncTask<String, String, String> {
private String newVersion;
#Override
protected String doInBackground(String... params) {
try {
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id="+getPackageName())
.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();
} catch (IOException e) {
e.printStackTrace();
}
return newVersion;
}
}
There is no official GooglePlay API to do it.
But you can use this unofficial library to get app version data.
And, if the above doesn't work for you, you can always http connect to your app's page (e.g. https://play.google.com/store/apps/details?id=com.shots.android&hl=en) and parse the "Current Version" field.
You can try following code using Jsoup
String latestVersion = doc.getElementsContainingOwnText("Current Version").parents().first().getAllElements().last().text();
Google introduced In-app updates feature, (https://developer.android.com/guide/app-bundle/in-app-updates) it works on Lollipop+ and gives you the ability to ask the user for an update with a nice dialog (FLEXIBLE) or with mandatory full-screen message (IMMEDIATE).
Here is how Flexible update will look like:
and here is Immedtiate update flow:
You can check my answer here https://stackoverflow.com/a/56808529/5502121 to get the complete sample code of implementing both Flexible and Immediate update flows.
Hope it helps!
confirmed only that method work now:
newVersion = Jsoup.connect("https://play.google.com/store/apps/details?id=" + AcMainPage.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(".hAyfc .htlgb")
.get(5)
.ownText();
Google introduced in-app update api. Using that we can ask user to update app inside the application. if user accept we can directly download latest app and install without redirect to playstore. for more details please refer the below link
link1link2
I am not sure about JAVA programming though, but with latest changes you can
Request https://play.google.com/store/apps/details?id=<package.name> url.
Parse the data as text.
Match regex /key: 'ds:4',\n[\ ]*hash: '[0-9]*',\n[\ ]*data:\ ([\S".,\[\]\ ]*),/ with the response.
This has a group with it which will give group value as ["size", "version", "supported android version"]. e.g. ["16M", "1.0.0", "5.0 and up"].
Parse the group as an array and you will get array[1] as latest version.
Implementation doesn't depend on any language.
if your app is on Google Play Store then Just use this function its automatically checks the app update and shows a msg to the user for update
public void checkUpdate()
{
if (isInternetOn())
{
AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(getApplicationContext());
Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();
appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE))
{
try {
appUpdateManager.startUpdateFlowForResult(appUpdateInfo, AppUpdateType.FLEXIBLE, this, "Your Request Code");
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
});
}
}
and additionally you can check internet Connectivity before checking the update with this function`
public boolean isInternetOn()
{
ConnectivityManager connec = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connec.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.CONNECTED ||
connec.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.CONNECTING ||
connec.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.CONNECTING ||
connec.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.CONNECTED)
{
return true;
} else if (connec.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.DISCONNECTED ||
connec.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.DISCONNECTED)
{
return false;
}
return false;
}`
Within my application, I want to check if there is any updated version of my application is in the app store. If there is any, then have to inform the user through an alert message and if he/she opt for upgrade I want to update the new version.I want to do all this through my application. Is this possible?
I have the same issue but it resolved by JSOUP library.
Here is the library download link: http://jsoup.org/download
String 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[itemprop=softwareVersion]").first()
.ownText();
Log.e("new Version", newVersion);
Nevertheless , you can make an http request on the web version of the playstore (https://play.google.com/store/apps/details?id=your.namespace)
To make the request you can use DefaultHttpClient
Once you get the page content you should parse it (jsoup is a good solution) and search for :
<div class="content" itemprop="softwareVersion"> 2.2.0 </div>
Once you find this part of the page , you can extract the version number and compare it with the one available in your app :
try
{
String version = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
if( ! version.equals(versionFromHTML))
{
Toast.makeText(this, "New version available on play store", Toast.LENGTH_SHORT);
}
}
catch (NameNotFoundException e)
{
//No version do something
}
For the HTML parsing part , have a look here
Keep in mind that everybody won't see the new version in the same time. It could take time to be propagated (probably because of cache).
Edit:
Google introduced In-app updates lib. It works on Lollipop+ and gives you the ability to ask the user for an update with a nice dialog (FLEXIBLE) or with the mandatory full-screen message (IMMEDIATE).
Well there is another way I figured out and this is how I am doing it.
HttpPost httppostUserName = new HttpPost("https://androidquery.appspot.com/api/market?app=com.supercell.clashofclans"); //your package name
HttpClient httpclient = new DefaultHttpClient();
HttpResponse responseUser = httpclient.execute(httppostUserName);
String responseStringUser = EntityUtils.toString(responseUser.getEntity(), HTTP.UTF_8);
Log.d(Constants.TAG, "Response: " + responseStringUser);
try {
JSONObject Json = new JSONObject(responseStringUser);
newVersion = Json.getString("version");
} catch (Exception e) {
e.printStackTrace();
}
You will get a clearer view if you paste the url in your browser to see the results.
You can use the Play Core Library In-app updates to tackle this. You can check for update availability and install them if available seamlessly.
Note that, In-app updates works only with devices running Android 5.0 (API level 21) or higher, and requires you to use Play Core library 1.5.0 or higher.
In-app updates are not compatible with apps that use APK expansion files (.obb files). You can either go for flexible downloads or immediate updates which Google Play takes care of downloading and installing the update for you.
dependencies {
implementation 'com.google.android.play:core:1.5.0'
...
}
EDIT
They have recently changed Google play website and now this code is broken. Avoid this solution or be ready to patch your app whenever Google Play pages change.
Ahmad Arlan's answer is the best answer so far. But if you got here and you try to cut and paste his code you'll go through the same issues I just had, so I might as well just post it here to help others like me.
Make sure you have INTERNET permission on your AndroidManifest.xml file.
<uses-permission android:name="android.permission.INTERNET"/>
Add JSOUP dependency to your module build.gradle.
dependencies {
compile 'org.jsoup:jsoup:1.10.2'
}
Surround the snippet with try and catch and don't run it on the main thread.
public class MainActivity extends AppCompatActivity {
String newVersion;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new FetchAppVersionFromGooglePlayStore().execute();
}
class FetchAppVersionFromGooglePlayStore extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
try {
return
Jsoup.connect("https://play.google.com/store/apps/details?id=" + "com.directed.android.smartstart" + "&hl=en")
.timeout(10000)
.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();
} catch (Exception e) {
return "";
}
}
protected void onPostExecute(String string) {
newVersion = string;
Log.d("new Version", newVersion);
}
}
}
I posted a copy here of the project on github.
This worked for me.
Add this dependency.
implementation 'org.jsoup:jsoup:1.8.3'
At onCreate() method use the following code:
try {
String currentVersion="";
currentVersion = getApplicationContext().getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
Log.e("Current Version","::"+currentVersion);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
new GetVersionCode().execute();
Create class GetVersionCode:
private 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=" + 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();
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 (onlineVersion.equals(currentVersion)) {
} else {
AlertDialog alertDialog = new AlertDialog.Builder(context).create();
alertDialog.setTitle("Update");
alertDialog.setIcon(R.mipmap.ic_launcher);
alertDialog.setMessage("New Update is available");
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Update", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName())));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + context.getPackageName())));
}
}
});
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}
Log.d("update", "Current version " + currentVersion + "playstore version " + onlineVersion);
}
}
Google Play already does this. When you upload a new version of your app, it will either send an alert directly to your users' devices or download the upgrade automatically if the user has this option turned on in the Google Play app.
private void checkForUpdate() {
PackageInfo packageInfo = null;
try { packageInfo=getPackageManager().getPackageInfo(DashboardActivity.this.getPackageName(), 0);
int curVersionCode = packageInfo.versionCode
if (curVersionCode > 1) { // instead of one use value get from server for the new update.
showUpdateDialog();
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
Beware of policy violations, Google will suspend your App if any 3rd party frameworks used for App update, this happened to me recently.
Update 2019 Android Dev Summit
Google introduced In-app updates lib. It works on Lollipop+ and gives you the ability to ask the user for an update with a nice dialog (FLEXIBLE) or with the mandatory full-screen message (IMMEDIATE).
In-app updates works only with devices running Android 5.0 (API level
21) or higher.