我如何从Google Play商店获取应用程序版本信息,以便在更新Play商店应用程序时(即在用户使用旧版本应用程序的情况下)提示用户强制/建议对应用程序进行更新。 我已经通过了andorid-market-api,这不是官方方法,还需要Google的oauth登录身份验证。 我也经历了android查询
它提供了应用内版本检查功能,但在我的情况下不起作用。
我发现以下两种选择:
- 使用服务器API来存储版本信息
- 使用google标记并在应用内访问它,这不是首选方式。
还有其他简便的方法吗?
- 我喜欢你的第一种方式
- @CapDroid还有其他方法吗? 特别是在独立应用程序的情况下。
- 我不知道:(大多数情况下,我是按照你的第一种方式:)
- 如果有其他选择,那么采用第一种方法也是第一种方法,尽管学习起来很有趣。 好问题!
- 在Android Market中以编程方式检查我的应用程序版本的可能重复项
- 我已经尝试过目前无法使用的市场API! 您提到的问题有提及吨市场API的答案。 所以没有重复的问题
- 试试这个:github.com/googlesamples/android-play-publisher-api/tree/mas ter /
我建议不要使用库只是创建一个新类
1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class VersionChecker extends AsyncTask<String, String, String>{ 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("div.hAyfc:nth-child(4) > span:nth-child(2) > div:nth-child(1) > span:nth-child(1)") .first() .ownText(); } catch (IOException e) { e.printStackTrace(); } return newVersion; } |
在您的活动中:
1 2 | VersionChecker versionChecker = new VersionChecker(); String latestVersion = versionChecker.execute().get(); |
就这些
- 这将是什么输出?我没有得到这个!是否输出版本信息?如果是,则采用什么格式?
- 您将获得versionName的字符串,可以在文件" build.gradle"中找到此版本名称。
- 这是一个hack。但这确实是一个不错的技巧,不需要太多的努力,尤其是考虑到Google使得使用它们的api变得困难。 +1。 :)
- 不错的骇客,但自此不再需要了:github.com/googlesamples/android-play-publisher-api/tree/mas ter /
- 谢谢。。。但是很漂亮。
- @SandroWiggers哪个官方API可以检查应用程序版本?
- 是的,它可能由于多种原因而失败。例如,1. Google更改您在select(" div [itemprop = softwareVersion]")中使用的密钥。最好的办法是在自己的服务器上维护一个API,该API可为您提供应用程序的当前市场版本,然后您可以将其与用户设备上安装的API进行比较。
-
这刚刚坏了。如果您使用正则表达式,则可以使用
]*?>Current Version]*?>(.*?) - 诚然,这种方式被打破了。您提供的表达式也不起作用@vincent
- @bkm他们似乎正在更改它的atm。让我们看看最终结果是"稳定"的。
- 在当前版本之间使用" \ s"修复模式后,我可以使用此功能:] *?> Current \ sVersion ] *?>(。*?)
- .select("] *?> Current \\ sVersion ] *?>(。*?)")产生此错误方法抛出org.jsoup.select.Selector $ SelectorParseException异常@Cesar
- 对于android用户,将此依赖项添加到gradle文件中,编译org.jsoup:jsoup:1.11.3
- 认真的人..我只是想尝试n从早上开始就终于尝试了,这个工作了...非常感谢...
- 那么,有没有人尝试过android-play-publisher-api获取当前版本号?我浏览了一下代码,但没有发现任何提示可用于此目的。
- 没有官方的方法可以做到这一点。我的意思是您刚刚阅读了html网站。不是最漂亮的方法。
- 这还通过用户移动数据连接下载了大量的HTML数据(到今天为止为780 Kb)。并非每个人都在加利福尼亚州并且有无限的数据计划。该代码不仅不够健壮,而且对用户也造成了很大的麻烦。
使用此代码可以完美地工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | public void forceUpdate(){ PackageManager packageManager = this.getPackageManager(); PackageInfo packageInfo = null; try { packageInfo =packageManager.getPackageInfo(getPackageName(),0); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } String currentVersion = packageInfo.versionName; new ForceUpdateAsync(currentVersion,TodayWork.this).execute(); } public class ForceUpdateAsync extends AsyncTask<String, String, JSONObject> { private String latestVersion; private String currentVersion; private Context context; public ForceUpdateAsync(String currentVersion, Context context){ this.currentVersion = currentVersion; this.context = context; } @Override protected JSONObject doInBackground(String... params) { try { 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.hAyfc:nth-child(3) > span:nth-child(2) > div:nth-child(1) > span:nth-child(1)") .first() .ownText(); Log.e("latestversion","---"+latestVersion); } catch (IOException e) { e.printStackTrace(); } return new JSONObject(); } @Override protected void onPostExecute(JSONObject jsonObject) { if(latestVersion!=null){ if(!currentVersion.equalsIgnoreCase(latestVersion)){ // Toast.makeText(context,"update is available.",Toast.LENGTH_LONG).show(); if(!(context instanceof SplashActivity)) { if(!((Activity)context).isFinishing()){ showForceUpdateDialog(); } } } } super.onPostExecute(jsonObject); } public void showForceUpdateDialog(){ context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName()))); } } |
如果有人需要,这里是jQuery版本,以获取版本号。
1 2 3 | $.get("https://play.google.com/store/apps/details?id=" + packageName +"&hl=en", function(data){ console.log($('').html(data).contents().find('div[itemprop="softwareVersion"]').text().trim()); }); |
- 我需要离子性的,但是当我使用它时,会出现一些问题,
- 这太脆了。我怎么知道?我继承的一个应用程序执行此操作,并且今天开始严重崩溃。
Firebase Remote Config在这里可以提供最佳帮助,
请参考这个答案
https://stackoverflow.com/a/45750132/2049384
除了使用JSoup,我们还可以进行模式匹配,以从playStore获取应用程序版本。
要匹配来自Google Playstore的最新模式,即
我们首先必须匹配上面的节点序列,然后从上面的序列中获取版本值。以下是相同的代码段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | 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 ="]*?>Current\\\\sVersion<span[^>]*?>(.*?)>]*?>(.*?)><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中所做的最新更改。希望能有所帮助。
- 在您的允许下,我将使用AsynsTask发布完整代码
- 由于用户可能有不同的地点偏爱,因此不中继"当前版本"一词更为可靠
我怀疑请求应用程序版本的主要原因是提示用户进行更新。我不赞成取消响应,因为这可能会破坏将来版本的功能。
如果应用的最低版本为5.0,则可以根据文档https://developer.android.com/guide/app-bundle/in-app-updates实施应用内更新
如果请求应用程序版本的原因不同,您仍然可以使用appUpdateManager来检索版本并执行所需的任何操作(例如,将其存储在首选项中)。
例如,我们可以将文档的片段修改为如下形式:
1 2 3 4 5 6 7 8 9 10 11 | // Creates instance of the manager. val appUpdateManager = AppUpdateManagerFactory.create(context) // Returns an intent object that you use to check for an update. val appUpdateInfoTask = appUpdateManager.appUpdateInfo // Checks that the platform will allow the specified type of update. appUpdateInfoTask.addOnSuccessListener { appUpdateInfo -> val version = appUpdateInfo.availableVersionCode() //do something with version. If there is not a newer version it returns an arbitary int } |
此解决方案的完整源代码:https://stackoverflow.com/a/50479184/5740468
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | import android.os.AsyncTask; import android.support.annotation.Nullable; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; public class GooglePlayAppVersion extends AsyncTask<String, Void, String> { private final String packageName; private final Listener listener; public interface Listener { void result(String version); } public GooglePlayAppVersion(String packageName, Listener listener) { this.packageName = packageName; this.listener = listener; } @Override protected String doInBackground(String... params) { return getPlayStoreAppVersion(String.format("https://play.google.com/store/apps/details?id=%s", packageName)); } @Override protected void onPostExecute(String version) { listener.result(version); } @Nullable private static String getPlayStoreAppVersion(String appUrlString) { String currentVersion_PatternSeq ="]*?>Current\\\\sVersion<span[^>]*?>(.*?)>]*?>(.*?)><span[^>]*?>(.*?)</span>", appVersion_PatternSeq ="htlgb\">([^<]*)</s"; try { URLConnection connection = new URL(appUrlString).openConnection(); connection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6"); try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { StringBuilder sourceCode = new StringBuilder(); String line; while ((line = br.readLine()) != null) sourceCode.append(line); // Get the current version pattern sequence String versionString = getAppVersion(currentVersion_PatternSeq, sourceCode.toString()); if (versionString == null) return null; // get version from"htlgb">X.X.X</span> return getAppVersion(appVersion_PatternSeq, versionString); } } catch (IOException e) { e.printStackTrace(); } return null; } @Nullable private static String getAppVersion(String patternString, String input) { try { Pattern pattern = Pattern.compile(patternString); if (pattern == null) return null; Matcher matcher = pattern.matcher(input); if (matcher.find()) return matcher.group(1); } catch (PatternSyntaxException e) { e.printStackTrace(); } return null; } } |
用法:
1 2 3 | new GooglePlayAppVersion(getPackageName(), version -> Log.d("TAG", String.format("App version: %s", version) ).execute(); |
使用服务器API来存储版本信息
如您所说,这是检测更新的简便方法。在每次API调用时传递您的版本信息。 Playstore更新后,请更改服务器中的版本。服务器版本高于已安装的应用程序版本后,您可以在API响应中返回状态代码/消息,可以对其进行处理并显示更新消息。如果您使用此方法,您还可以阻止用户使用像WhatsApp这样的非常老的应用程序。
或者您可以使用推式通知,这很容易做到...也
- 我正在寻找服务器API以外的解决方案。谢谢回复!
- 试试这个Google官方api:github.com/googlesamples/android-play-publisher-api/tree/mas ter /
- 如何在Cakephp 2.0中使用
- 对我来说,每个API调用似乎都太过分了。
- 不要添加新的api调用。在api中添加版本信息。参考github.com/mindhaq/restapi-versioning-spring
- 但是,如果您使用此方法,则Google团队需要审查更新,并且您如何知道何时更改API中的版本?
对于PHP
1 2 3 4 | $package='com.whatsapp'; $html = file_get_contents('https://play.google.com/store/apps/details?id='.$package.'&hl=en'); preg_match_all('/<span class="htlgb"><span class="htlgb">(.*?)<\\/span><\\/div><\\/span>/s', $html, $output); print_r($output[1][3]); |
- 尽管这段代码可以解决问题,包括解释如何以及为什么解决问题的方法,特别是当问题有多个好的答案时,这实际上将有助于提高您的帖子质量,并可能导致更多的投票。 请记住,您将来会为读者回答问题,而不仅仅是现在问的人。 请编辑您的答案以添加说明,并指出适用的限制和假设。 来自评论
服务器端的用户版本Api:
这是目前仍获得市场版本的最佳方法。当您上传新的APK时,请更新api中的版本。因此,您将在您的应用程序中获得最新版本。
-这是最好的,因为没有google api可以获取应用程序版本。
使用Jsoup库:
这基本上是网页抓取。这不是一种方便的方法,因为如果Google更改了他们的代码,则此过程将无法进行。虽然可能性较小。无论如何,要使用Jsop库获取版本。
将此库添加到您的build.gradle中
实现'org.jsoup:jsoup:1.11.1'
创建一个用于版本检查的类:
import android.os.AsyncTask import org.jsoup.Jsoup import
java.io.IOExceptionclass PlayStoreVersionChecker(private val packageName: String) :
AsyncTask() {
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 private var playStoreVersion: String =""
override fun doInBackground(vararg params: String?): String {
try {
playStoreVersion =
Jsoup.connect("https://play.google.com/store/apps/details?id=$packageName&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 (e: IOException) {
}
return playStoreVersion
} }
现在,使用以下类:
val playStoreVersion = PlayStoreVersionChecker(" com.example")。execute()。get()
我的解决方法是解析Google Play网站并提取版本号。
如果您遇到CORS问题或想节省用户设备上的带宽,请考虑从Web服务器上运行它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | let ss = [html]; for (let p of ['div', 'span', '>', '<']) { let acc = []; ss.forEach(s => s.split(p).forEach(s => acc.push(s))); ss = acc; } ss = ss .map(s => s.trim()) .filter(s => { return parseFloat(s) == +s; }); console.log(ss); // print something like [ '1.10' ] |
您可以通过获取
其他人提到使用某些CSS类或模式(例如"当前版本")从Google Play网站解析html,但是这些方法可能不那么可靠。因为Google可以随时更改班级名称。它也可能根据用户的语言环境偏好返回不同语言的文本,因此您可能不会得到"当前版本"一词。
- 更好的方法是使用Firebase远程配置。
- 其他方法是使用您自己的API。
这样的好处是,您将可以检查版本号而不是名称,这应该更加方便:)另一方面-您应该注意每次发布后在api / firebase中更新版本。
-
从Google Play网页上获取版本。我已经实现了这种方式,并且可以工作超过1年,但是在此期间,我不得不将"匹配器"更改3-4次,因为网页上的内容已更改。另外,不时检查它有些头痛,因为您不知道可以在哪里更改。
但是,如果您仍然想使用这种方式,这是基于okHttp 的我的kotlin代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40private fun getVersion(onChecked: OnChecked, packageName: String) {
Thread {
try {
val httpGet = HttpGet("https://play.google.com/store/apps/details?id="
+ packageName +"&hl=it")
val response: HttpResponse
val httpParameters = BasicHttpParams()
HttpConnectionParams.setConnectionTimeout(httpParameters, 10000)
HttpConnectionParams.setSoTimeout(httpParameters, 10000)
val httpclient = DefaultHttpClient(httpParameters)
response = httpclient.execute(httpGet)
val entity = response.entity
val `is`: InputStream
`is` = entity.content
val reader: BufferedReader
reader = BufferedReader(InputStreamReader(`is`,"iso-8859-1"), 8)
val sb = StringBuilder()
var line: String? = null
while ({ line = reader.readLine(); line }() != null) {
sb.append(line).append("\
")
}
val resString = sb.toString()
var index = resString.indexOf(MATCHER)
index += MATCHER.length
val ver = resString.substring(index, index + 6) //6 is version length
`is`.close()
onChecked.versionUpdated(ver)
return@Thread
} catch (ignore: Error) {
} catch (ignore: Exception) {
}
onChecked.versionUpdated(null)
}.start()
}
您可以调用以下WebService:
http://carreto.pt/tools/android-store-version/?package=[YOUR_APP_PACKAGE_NAME]
使用Volley的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | String packageName ="com.google.android.apps.plus"; String url ="http://carreto.pt/tools/android-store-version/?package="; JsonObjectRequest jsObjRequest = new JsonObjectRequest (Request.Method.GET, url+packageName, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { /* here you have access to: package_name, - the app package name status - success (true) of the request or not (false) author - the app author app_name - the app name on the store locale - the locale defined by default for the app publish_date - the date when the update was published version - the version on the store last_version_description - the update text description */ try{ if(response != null && response.has("status") && response.getBoolean("status") && response.has("version")){ Toast.makeText(getApplicationContext(), response.getString("version").toString(), Toast.LENGTH_LONG).show(); } else{ //TODO handling error } } catch (Exception e){ //TODO handling error } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { //TODO handling error } }); |
- 应该更容易:github.com/googlesamples/android-play-publisher-api/tree/mas ter /
- 如何在Cakephp 2.0中使用
我建议使用ex。推送通知以通知您的应用程序有新更新,或者使用您自己的服务器从那里启用您的应用程序读取版本。
是的,每次您更新应用程序时,它的其他工作都是可行的,但是在这种情况下,您并不依赖于某些"非正式"或第三方的服务,这些服务可能会失效。
以防万一您错过了什么-之前对您的主题的讨论
向Google Play商店查询应用程序的版本?
- 我试过了android-market-api,现在无法正常工作。我也尝试了android-query,它不再起作用。
- 是的,android-market-api对我来说似乎也不再起作用。
- 您可以使用以下代码:github.com/googlesamples/android-play-publisher-api/tree/mas ter /