Android 以编程方式检查 Play 商店的应用更新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25201349/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Programmatically check Play Store for app updates
提问by turtleboy
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.
我已将我的应用放在 Google Play 商店中。我公司的很多客户都安装了它。我了解应用程序的升级机制。
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.
用户应该为他们想要自动更新的每个应用程序选中 Playstore 应用程序中的自动更新复选框。但是,有些用户一开始就取消选中或未选中它。
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.
我编写的应用程序适用于护理行业,护理人员使用它来提供家庭护理。我们的一些客户有 1200 名护理人员。他们必须把所有的护理人员叫到办公室来单独更新电话。这显然是不能接受的。
Is there a way to programmatically check if there is an updated version of my app on the Play Store?
有没有办法以编程方式检查 Play 商店中是否有我的应用程序的更新版本?
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.
我可以让代码在每次用户启动检查 Play 商店的应用程序时运行吗?如果有更新版本,则可以将用户定向到 Playstore。这意味着不必检查自动更新。
Thanks in advance
提前致谢
Matt
马特
采纳答案by Richard Lindhout
Update 17 October 2019
2019 年 10 月 17 日更新
https://developer.android.com/guide/app-bundle/in-app-updates
https://developer.android.com/guide/app-bundle/in-app-updates
Update 24 april 2019:
2019 年 4 月 24 日更新:
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
Android 宣布了一项可能会解决此问题的功能。使用应用内更新 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.
据我所知,没有官方的谷歌 API 支持这一点。
You should consider to get a version number from an API.
您应该考虑从 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.
而不是连接到外部 API 或网页(如 Google Play 商店)。API 或网页中存在某些内容可能发生变化的风险,因此您应该考虑检查当前应用程序的版本代码是否低于您从自己的 API 获取的版本号。
Just remember if you update your app, you need to change the version in your own API with the app version number.
请记住,如果您更新您的应用程序,您需要使用应用程序版本号更改您自己的 API 中的版本。
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)
我建议您在自己的网站或 API 中制作一个带有版本号的文件。(最终做一个cronjob并使版本自动更新,并在出现问题时发送通知)
You have to get this value from your Google Play Store page (is changed in the meantime, not working anymore):
您必须从您的 Google Play 商店页面获取此值(同时更改,不再工作):
<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.
如果手机上使用的版本低于您自己的 API 上显示的版本号,请检查您的应用程序。
Show indication that she/he needs to update with a notification, ideally.
最好显示她/他需要通过通知进行更新的指示。
Things you can do
你可以做的事情
Version number using your own API
使用您自己的 API 的版本号
Pros:
优点:
- No need to load the whole code of the Google Play Store (saves on data/bandwidth)
- 无需加载 Google Play 商店的整个代码(节省数据/带宽)
Cons:
缺点:
- User can be offline, which makes checking useless since the API can't be accessed
- 用户可以离线,由于无法访问API,因此检查无用
Version number on webpage Google Play Store
Google Play 商店网页上的版本号
Pros:
优点:
- You don't need an API
- 您不需要 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.
- 用户可以离线,由于无法访问API,因此检查无用
- 使用此方法可能会花费您的用户更多带宽/移动数据
- Play 商店网页可能会更改,这会使您的版本“开膛手”不再起作用。
回答by Tarun
Include JSoup in your apps build.gradle file :
在您的应用程序 build.gradle 文件中包含 JSoup:
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
更多详情请访问:http: //revisitingandroid.blogspot.in/2016/12/programmatically-check-play-store-for.html
回答by Sreedhu Madhu
Firebase Remote Configcould be a possible and reliable solution for now, since google didn't expose any api to it.
Firebase 远程配置现在可能是一个可能且可靠的解决方案,因为谷歌没有向它公开任何 api。
Check Firebase Remote Config Docs
Steps1.Create a firebase project and add google_play_service.json to your project
步骤 1.创建一个 firebase 项目并将 google_play_service.json 添加到您的项目中
2.Create keys like "android_latest_version_code" and "android_latest_version_name" in firebase console->Remote Config
2.在firebase控制台->远程配置中创建“android_latest_version_code”和“android_latest_version_name”等键
3.Android Code
3.安卓代码
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.
4. 并使用您当前的生产版本名称和代码使 firebase "android_latest_version_code" 和 "android_latest_version_name" 保持最新。
Firebase remote config works on both Android and IPhone.
Firebase 远程配置适用于 Android 和 iPhone。
回答by Nikunj
You can get current Playstore Versionusing JSoup
with some modification like below:
您可以使用以下修改来获取当前的Playstore 版本JSoup
:
@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.
@Tarun 的回答不再有效。
回答by stenlytw
There's AppUpdaterlibrary. How to include:
有AppUpdater库。如何包括:
- Add the repository to your projectbuild.gradle:
- 将存储库添加到您的项目build.gradle:
allprojects { repositories { jcenter() maven { url "https://jitpack.io" } } }
allprojects { repositories { jcenter() maven { url "https://jitpack.io" } } }
- Add the library to your modulebuild.gradle:
- 将库添加到您的模块build.gradle:
dependencies { compile 'com.github.javiersantos:AppUpdater:2.6.4' }
dependencies { compile 'com.github.javiersantos:AppUpdater:2.6.4' }
- Add INTERNET and ACCESS_NETWORK_STATE permissions to your app's Manifest:
- 将 INTERNET 和 ACCESS_NETWORK_STATE 权限添加到您应用的清单中:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<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();
AppUpdater appUpdater = new AppUpdater(this); appUpdater.start();
回答by Rajesh Naddy
@Tarun answer was working perfectly.but now isnt ,due to the recent changes from Google on google play website.
@Tarun 回答工作正常。但现在不是,由于谷歌最近在 google play 网站上的变化。
Just change these from @Tarun answer..
只需从@Tarun 答案中更改这些即可。
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
并且不要忘记添加 JSoup 库
dependencies {
compile 'org.jsoup:jsoup:1.8.3'}
and on Oncreate()
和 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
就是这样..感谢这个链接
回答by Rajesh Naddy
Inside OnCreate method write below code..
在 OnCreate 方法里面写下面的代码..
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..
这为您提供 Play 商店版本的应用程序..
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
并添加 VersionChecker.class 如下
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;
}
}
回答by Nihas Nizar
Firebase Remote Config is better.
Firebase 远程配置更好。
- Quickly and easily update our applications without the need to publish a new build to the app
- 快速轻松地更新我们的应用程序,而无需向应用程序发布新版本
Implementing Remote Config on Android
在 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 = 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
现在一旦将新版本上传到 Playstore,我们必须在 firebase 中更新版本号。现在,如果是新版本,将显示更新对话框
回答by aswanth bonthala
Google has introduced in-app updates API
Google 引入了应用内更新 API
The API currently supports two flows:
API 目前支持两种流:
- 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.
- “立即”流程是一种全屏用户体验,可引导用户从下载到更新,然后才能使用您的应用。
- “灵活流程”允许用户在继续使用您的应用程序的同时下载更新。
回答by tyler_mitchell
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.
来自混合应用程序 POV。这是一个 javascript 示例,我的主菜单上有一个更新可用页脚。如果有可用更新(即我在配置文件中的版本号小于检索到的版本,显示页脚)这会将用户定向到应用程序/播放商店,然后用户可以在其中单击更新按钮。
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
在设备就绪上,设置您的商店 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
iOS回调:苹果有API,很容易搞定
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)
Android回调:PlayStore你必须刮,因为你可以看到版本相对容易获取,新的我采用html而不是文本,因为这样我可以使用它们的格式(即新行等)
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:
确保 Play 商店和 App Store 已被列入白名单:
<access origin="https://itunes.apple.com"/>
<access origin="https://play.google.com"/>