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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:12:16  来源:igfitidea点击:

Programmatically check Play Store for app updates

android

提问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-androiddevsum​​mit.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

检查Firebase 远程配置文档

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 JSoupwith 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库。如何包括:

  1. Add the repository to your projectbuild.gradle:
  1. 将存储库添加到您的项目build.gradle
allprojects {
    repositories {
        jcenter()
        maven {
            url "https://jitpack.io"
        }
    }
}
allprojects {
    repositories {
        jcenter()
        maven {
            url "https://jitpack.io"
        }
    }
}
  1. Add the library to your modulebuild.gradle:
  1. 将库添加到您的模块build.gradle
dependencies {
    compile 'com.github.javiersantos:AppUpdater:2.6.4'
}
dependencies {
    compile 'com.github.javiersantos:AppUpdater:2.6.4'
}
  1. Add INTERNET and ACCESS_NETWORK_STATE permissions to your app's Manifest:
  1. 将 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"/>
  1. Add this to your activity:
  1. 将此添加到您的活动中:
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

enter image description here

在此处输入图片说明

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('&nbsp;');
        // 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('&nbsp;');
        // 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"/>