Android获取Google Play商店应用程序版本

7
我正在使用这段代码来获取Google Play Store应用程序的版本,但这导致我的应用程序挂起。请指定另一种获取应用程序版本的方法,或者告诉我如何修改此代码以使应用程序不挂起并成功运行。
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;
    }
}

这是我从异步任务中获取应用程序版本的代码

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

这是针对特定应用程序的吗? - Gastón Saillén
针对特定应用程序是的 - Priyanka Singhal
你能贴出调用这个异步任务的函数代码吗? - Ashish Kumar
你是如何解决compareVersionNames错误的? - Clinton Canarias
1
截至2022年5月26日,谷歌已更改了他们的Play商店页面,并将最新的“版本”隐藏在一个可点击的按钮后面,以显示一个模态框。我们不仅需要解析/爬取页面,还必须使用无头浏览器来单击该按钮,显示模态框,然后解析模态框以获取版本信息。真是麻烦。如果有人知道更好的方法,请分享! - Joshua Pinter
显示剩余4条评论
8个回答

7

只需替换您的代码

.get()
.select("div[itemprop=softwareVersion]")
.first()
.ownText();

                    

抱歉,我只能使用英语进行翻译。
.get()
.select(".hAyfc .htlgb")
.get(3)
.ownText();

它将起作用..!


你现在需要使用 .get(5) 而不是 .get(3),但这是我发现的唯一有效的方法。 - Ian Oswald
你是如何解决compareVersionNames错误的? - Clinton Canarias

2
  1. 看起来你使用Google Play商店网站上显示的“应用程序版本”来触发“更新弹出窗口”,以通知用户新版本已经可用。首先,Google Play商店网站经常更改,因此这不是非常可靠的,因为你的应用程序可能无法“解析/处理”这些更改。如果你想继续使用这种方法,其他答案已经解释了如何解析正确的HTML标记以及如何在后台正确执行操作。请记住,你的应用程序仍将负责“解析”,最终你可以在Web服务器上远程执行解析,并公开一个稳定的API端点以检索你自己应用程序的“最新版本”。如果你不想费心解析HTML标记或托管自己的API,则有第三方API可以为你完成此操作。我们在此提供一个此类API:https://42matters.com/docs/app-market-data/android/apps/lookup(它返回一个具有应用程序最新“版本名称”的JSON对象)。

  2. 你还可以使用https://github.com/danielemaddaluno/Android-Update-Checker来避免实现自己的代码,在幕后它做的事情与你做的差不多。

  3. 个人而言,我会使用远程服务,例如Firebase远程配置https://firebase.google.com/docs/remote-config或托管在你的网站上的简单JSON文件,指定你的应用程序的最新发布版本(只需记住一旦真正发布了应用程序的更新,就要更改它,现在可能需要一段时间)。此外,我更愿意使用“versionCode”,如此处所述:https://developer.android.com/studio/publish/versioning。采用这种方法,你可以在想要时“触发”更新,在你这一方面拥有更多的控制(特别是在你想要还原“请更新”消息的情况下很有用,如果你在你发布的最新版本中发现错误)。


2
问题出现的原因是在Google Play网站上找不到div [itemprop = softwareVersion]元素(因此不再返回版本号),必须将其更改为适应您网站上Google所做的更改的新查询。
注意:如果结构再次更改,则必须更改此代码。
希望这有所帮助。
更新日期:2019年12月09日
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;
    }
}

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

好的!你的解决方案比排名第一的要好。 - Jeff T.
showDialogToSendToPlayStore()是什么?我需要添加一个库吗? - H Hooshyar

0

谷歌将 API 从 'softwareVersion' 更改为 'currentVersion',我们可以使用 ".hAyfc .htlgb" 获取相同的版本。

下面的代码将无法工作。

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

不要使用上面的代码,只需添加以下代码即可,它会正常工作。
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()].

0

更改这两行代码

{
 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")
....

您正在使用BuildConfig.APPLICATION_ID,但您需要package_name

BuildConfig由Gradle提供。如果您不是使用Gradle构建,则无法使用BuildConfig访问包名称。

我会使用Context.getPackageName(),因为结果是由操作系统提供的,而不是构建参数中的常量。


好的,让我来做一下并检查。 - Priyanka Singhal
你是在一个异步任务中执行这个操作吗? - Gastón Saillén
应用程序加载仍需要一些时间。 - Priyanka Singhal
在异步任务中是可以的。 - Priyanka Singhal
你的清单文件中有互联网权限吗?你能发布你的错误日志吗?谢谢。 - Gastón Saillén
我在清单文件中拥有互联网权限,且没有错误。只是应用程序需要一些时间来加载活动。 - Priyanka Singhal

0

你需要将它放入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);
        }
    }

嗨,OP说他已经有一个异步任务了,请检查我的答案中的评论。 - Gastón Saillén
哦,我明白了... 如果他在那方面做错了什么,可能会澄清这个问题。 - Nikunj Peerbits
没问题,伙计 :) - Gastón Saillén

0

试一下这个:

替换代码,

                .get()
                .select("div:containsOwn(Current Version)")
                .next()
                .text();

0

你可以使用UpdateManager更容易地实现这一点 - https://developer.android.com/reference/com/google/android/things/update/UpdateManager

您可以设置您的Update Manager如下

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

在你的On Success方法中,你可以调用
result.availableVersionCode()

当版本号相同时,返回0。如果版本号不同,您可以直接从您的应用程序中获取此值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接