以编程方式检查Play商店是否有应用更新

时间:2014-08-08 10:25:47

标签: android

我已将我的应用程序放在Google Play商店中。它已被我公司的许多客户安装。我理解应用程序如何升级的机制。

用户应检查Playstore应用中的自动更新复选框,以查找要自动更新的每个应用。但是,有些用户已取消选中或未首先检查过它。

我写的应用程序是针对护理行业的,护理人员使用它来提供家庭护理。我们的一些客户有1200名护理员。他们必须打电话给所有护理人员进入办公室以单独更新电话。这显然是不可接受的。

有没有办法以编程方式检查Play商店中是否有我的应用的更新版本?

我可以在每次用户启动检查Play商店的应用时运行代码吗? 如果有更新版本,则可以将用户定向到Playstore。这意味着检查自动更新并不重要。

提前致谢

马特

18 个答案:

答案 0 :(得分:33)

在您的应用build.gradle文件中包含JSoup:

dependencies {
    compile 'org.jsoup:jsoup:1.8.3'
}

并获取当前版本:

currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;

执行以下主题:

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("div[itemprop=softwareVersion]")
                    .first()
                    .ownText();
            return newVersion;
        } catch (Exception e) {
            return newVersion;
        }
    }

    @Override
    protected void onPostExecute(String onlineVersion) {
        super.onPostExecute(onlineVersion);
        if (onlineVersion != null && !onlineVersion.isEmpty()) {
            if (Float.valueOf(currentVersion) < Float.valueOf(onlineVersion)) {
                //show dialog
            }
        }
        Log.d("update", "Current version " + currentVersion + "playstore version " + onlineVersion);
    }

有关详细信息,请访问:http://revisitingandroid.blogspot.in/2016/12/programmatically-check-play-store-for.html

答案 1 :(得分:23)

2019年4月24日更新:

Android宣布了一项功能,可能会解决这个问题。使用应用内更新API: https://android-developers.googleblog.com/2018/11/unfolding-right-now-at-androiddevsummit.html

<强>原始

AFAIK,没有支持此功能的官方Google API。

您应该考虑从API获取版本号。

而不是连接到外部API或网页(如Google Play商店)。 API或网页可能会发生变化,因此您应该考虑检查当前应用的版本代码是否低于您从自己的API获得的版本号。

请记住,如果您更新了应用,则需要使用应用版本号更改自己API中的版本。

我建议您使用版本号在自己的网站或API中创建文件。 (最终制作一个cronjob并自动更新版本,并在出现问题时发送通知)

您必须从Google Play商店页面获取此值:

<div class="content" itemprop="softwareVersion"> x.x.x  </div>

如果手机上使用的版本低于您自己的API上显示的版本号,请检入您的应用。

理想情况下,显示她/他需要通知更新的指示。

你可以做的事情

使用您自己的API的版本号

优点:

  • 无需加载Google Play商店的全部代码(节省数据/带宽)

缺点:

  • 用户可以离线,因为无法访问API,因此检查无效

Google Play商店网页上的版本号

优点:

  • 您不需要API

缺点:

  • 用户可以离线,这使得检查无用,因为无法访问API
    • 使用此方法可能会为您的用户带来更多带宽/移动数据
    • Play商店网页可能会发生变化,这会让您的版本“开膛手”不再起作用。

答案 2 :(得分:18)

Firebase远程配置目前可能是一种可行且可靠的解决方案,因为谷歌没有公开任何api。

检查Firebase Remote Config Docs

<强>步骤 1.创建一个firebase项目并将google_play_service.json添加到您的项目中

2.在firebase控制台中创建“android_latest_version_code”和“android_latest_version_name”等键 - &gt; Remote Config

3. Android代码

    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);
}

获取当前版本名称和代码

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。并使用您当前的生产版本名称和代码保持firebase“android_latest_version_code”和“android_latest_version_name”最新。

Firebase远程配置适用于Android和iPhone。

答案 3 :(得分:15)

您可以使用JSoup获取当前 Playstore版本,并进行如下修改:

@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);
}
@Tarun的答案不再适用了。

答案 4 :(得分:7)

AppUpdater个库。 如何包括:

  1. 将存储库添加到项目 build.gradle
  2. allprojects {
        repositories {
            jcenter()
            maven {
                url "https://jitpack.io"
            }
        }
    }
    
    1. 将库添加到模块 build.gradle
    2. dependencies {
          compile 'com.github.javiersantos:AppUpdater:2.6.4'
      }
      
      1. 为您的应用的清单添加INTERNET和ACCESS_NETWORK_STATE权限:
      2. <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        
        1. 将此添加到您的活动:
        2. AppUpdater appUpdater = new AppUpdater(this); 
          appUpdater.start();
          

答案 5 :(得分:5)

@Tarun的答案工作得很好。但现在不行了,因为谷歌最近在Google Play网站上发生了变化。

只需从@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);

    }
}

并且不要忘记添加JSoup库

dependencies {
compile 'org.jsoup:jsoup:1.8.3'}

和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();

}

那是...... 感谢this link

答案 6 :(得分:3)

设置一个服务器,公开报告最新版本的HTTP URL,然后使用AlarmManager调用该URL,并查看设备上的版本是否与最新版本相同。如果没有弹出消息或通知并将其发送到市场进行升级。

有一些代码示例:How to allow users to check for the latest app version from inside the app?

答案 7 :(得分:3)

来自混合应用程序POV。 这是一个javascript示例,我的主菜单上有一个Update Available页脚。如果有可用的更新(即我的配置文件中的版本号小于检索到的版本,则显示页脚)这将引导用户进入应用程序/播放商店,然后用户可以单击更新按钮。 / p>

我还获得了最新的数据(即发行说明),并在登录时以模式显示这些数据,如果是第一次使用此版本。

在设备就绪时,设置商店网址

        if (device.platform == 'iOS')
           storeURL = 'https://itunes.apple.com/lookup?bundleId=BUNDLEID';
        else
           storeURL = 'https://play.google.com/store/apps/details?id=BUNDLEID';

可以随时运行Update Available方法。每次用户导航到主屏幕时都会运行。

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回调:Apple有一个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回调:PlayStore你必须抓,因为你可以看到版本相对容易抓取和什么新的我采取HTML而不是文本,因为这样我可以使用他们的格式(即新行等)< / p>
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);
    }
}

开放存储逻​​辑是直接的,但为了完整性

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')
}

确保Play商店和App Store已列入白名单:

  <access origin="https://itunes.apple.com"/>
  <access origin="https://play.google.com"/>

答案 8 :(得分:3)

Firebase远程配置更好。

  • 快速轻松地更新我们的应用程序,而无需将新版本发布到应用程序

在Android上实现远程配置

添加远程配置依赖性

compile 'com.google.firebase:firebase-config:9.6.0'

完成后,我们可以在需要时在整个应用程序中访问FirebaseRemoteConfig实例:

FirebaseRemoteConfig firebaseRemoteConfig = FirebaseRemoteConfig.getInstance();

获取远程配置值

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");

获取服务器端值

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...
                    }
                }
            });

现在,将新版本上传到Playstore后,我们必须在firebase中更新版本号。现在,如果是新版本,将显示更新对话框

答案 9 :(得分:3)

在OnCreate方法内部编写以下代码。

VersionChecker versionChecker = new VersionChecker();
    try {
        latestVersion = versionChecker.execute().get();
        Toast.makeText(getBaseContext(), latestVersion , Toast.LENGTH_SHORT).show();

    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }

这使您可以播放应用的商店版本。

然后您必须检查以下应用程序版本

PackageManager manager = getPackageManager();
    PackageInfo info = null;
    try {
        info = manager.getPackageInfo(getPackageName(), 0);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    assert info != null;
    version = info.versionName;

之后,您可以将其与商店版本进行比较,并设置自己的更新屏幕

if(version.equals(latestVersion)){
        Toast.makeText(getBaseContext(), "No Update" , Toast.LENGTH_SHORT).show();
    }else {
        Toast.makeText(getBaseContext(), "Update" , Toast.LENGTH_SHORT).show();

    }

并如下添加VersionChecker.class

公共类VersionChecker扩展了AsyncTask {

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;
}

}

答案 10 :(得分:2)

您可以尝试使用Jsoup

代码
String latestVersion = doc.getElementsContainingOwnText("Current Version").parents().first().getAllElements().last().text();

答案 11 :(得分:2)

除了使用JSoup之外,我们还可以进行模式匹配,以便从playStore获取应用版本。

匹配google playstore的最新模式,即      <div class="BgcNfc">Current Version</div><span class="htlgb"><div><span class="htlgb">X.X.X</span></div> 我们首先必须匹配上面的节点序列,然后从上面的序列中获取版本值。以下是相同的代码段:

    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;
    }

我通过此解决了这个问题,因为这也适用于最新的Google Playstore更改。希望有所帮助。

答案 12 :(得分:2)

没有正式的GooglePlay API。

但您可以使用this unofficial library来获取应用版本数据。

并且,如果以上内容对您不起作用,您可以随时http连接到您应用的页面(例如https://play.google.com/store/apps/details?id=com.shots.android&hl=en)并解析“当前版本”字段。

答案 13 :(得分:1)

现在只确认该方法有效:

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();

答案 14 :(得分:1)

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;
    }
}

答案 15 :(得分:1)

enter image description here

Google已引入in-app updates API

该API当前支持两种流程:

  • “立即”流程是一种全屏用户体验,可指导用户从下载到更新,然后再使用您的应用程序。
  • “灵活流程”允许用户在继续使用您的应用的同时下载更新。

答案 16 :(得分:0)

enter image description here Google引入了应用内更新API。使用它,我们可以要求用户在应用程序内部更新应用程序。如果用户接受,我们可以直接下载最新的应用并安装,而无需重定向到playstore。有关更多详细信息,请参阅下面的链接

link1 link2

答案 17 :(得分:0)

Google引入了应用内更新功能(https://developer.android.com/guide/app-bundle/in-app-updates),该功能可在Lollipop +上运行,并且使您能够通过漂亮的对话框(FLEXIBLE)或使用强制性全屏消息(IMMEDIATE)。

以下是灵活更新的外观: enter image description here

这是即兴更新流程: enter image description here

您可以在https://stackoverflow.com/a/56808529/5502121处查看我的答案,以获取实现灵活立即更新流程的完整示例代码。 希望对您有帮助!