Update button is showing in play store on the second time when we go to play store from the app, here is what I am tried.
//getting the version from j soup library
try {
newVersion = Jsoup.connect(AppConstant.APP_PLAYSTORE_URL+ "&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();
}
//compare version name
if (mLatestVersionName != null && !mLatestVersionName.equals("") &&(Double.parseDouble(BuildConfig.VERSION_NAME) !=Double.parseDouble(mLatestVersionName))) {
openCheckerDialog();
}
//getting callback status from play store either it is updated or not
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == RC_UPDATE_APP_FROM_PLAYSTORE && resultCode == Activity.RESULT_OK)
{
//doing task
Log.v("Update", "Not Updated");
}
else
openCheckerDialog();
}
//moving to play store from the app
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(APP_PLAYSTORE_URL));
startActivityForResult(i, RC_UPDATE_APP_FROM_PLAYSTORE);
But this is not working as expected, could anyone please help with this? Any suggestion and code review is welcome
Officially available - A new way to force app update
This functionality officially known as "In-app updates"
In-app updates works only with devices running Android 5.0 (API level
21) or higher
requires you to use Play Core library 1.5.0 or higher.
2 types of options available for forcing in-app update:
Flexible - will allow the user to discard the update and continue
using the application
Immediate - will show a blocking UI that will
prompt the user to update.
Note: In-App Updates API looks at the Production, Alpha and Beta tracks in Google Play. You can’t rely on this API to update old Production versions to Internal Test updates
Links:
Documentation - https://developer.android.com/guide/app-bundle/in-app-updates
Play-core library - https://developer.android.com/guide/app-bundle/playcore#include_playcore
Reference article with an use case/scenarios covered - https://medium.com/#malmstein/theres-a-new-update-available-75a2c5bda76e
Note: When you publish your app an Android App Bundle, the maximum allowed compressed download size of an app using in-app updates is
150MB. In-app updates are not compatible with apps that use APK
expansion files (.obbfiles).
(4 liked)
This may help you
String newVersion = null;
try {
Document document = Jsoup.connect("https://play.google.com/store/apps/details?id=" + 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();
}
}
}
}
if (onlineVersion != null && !onlineVersion.isEmpty()) {
if (Float.valueOf(currentVersion) < Float.valueOf(onlineVersion)) {
//show anything
final String appPackageName = getApplicationContext().getPackageName(); // getPackageName() from Context or Activity object
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)));
}
}
}
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;
}`