当新版本可用时,Android如何在程序中自动更新应用程序

14

在我的应用程序中,我想检查应用商店中是否有任何更新版本的应用程序。如果有,要通过提示信息通知用户,如果用户选择升级,我想更新新版本。我希望通过我的应用程序完成所有这些操作。这是否可能?

在我的应用程序中,我想要检查是否存在应用商店中的最新版本。如果有,我希望通过提示消息通知用户,并且如果他/她选择升级,我希望能够更新到最新版本。请问这种方式是否可行?

问题不清楚。 - Biraj Zalavadia
如果您的应用程序将要发布到Play商店,操作系统会自动更新它。如果您不打算将其放在Play商店上,则必须创建自己的更新方法。您的应用程序将发布在哪里? - CurlyPaul
你的问题不太清楚——你是否在Play商店中有一个版本为1.0的应用程序,而你现在想要上传下一个版本2.0? - Legendary Genius
是的先生,但我想在应用程序启动时向用户更新新版本可用并下载它。 - user2914699
也许这个问题的答案可以帮到你:https://dev59.com/qWct5IYBdhLWcg3wcs-G - CurlyPaul
显示剩余3条评论
10个回答

12

我也遇到了同样的问题,但通过使用JSOUP库解决了。这是该库的下载链接:http://jsoup.org/download

String 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[itemprop=softwareVersion]").first()
                        .ownText();

                Log.e("new Version", newVersion);

7
尽管如此,您可以在Play商店的Web版本上进行HTTP请求(https://play.google.com/store/apps/details?id=your.namespace)。
为了发起请求,您可以使用DefaultHttpClient
一旦您获取到页面内容,您应该解析它(jsoup是一个好的解决方案),并搜索以下内容:
<div class="content" itemprop="softwareVersion"> 2.2.0  </div>

一旦您找到页面的这个部分,您可以提取版本号并将其与您的应用程序中可用的版本进行比较:

try
{
    String version = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
    if( ! version.equals(versionFromHTML))
    {
        Toast.makeText(this, "New version available on play store", Toast.LENGTH_SHORT);
    }
 
}
catch (NameNotFoundException e)
{
    //No version do something
}

对于HTML解析部分,请参考这里
请注意,并非所有人都会同时看到新版本。可能需要时间传播(可能是因为缓存)。 编辑: Google推出了In-app更新库。它适用于Lollipop+,并为您提供以美观的对话框(灵活)或全屏强制消息(IMMEDIATE)向用户请求更新的能力。

谢谢您先生,但我在Google Play商店下载应用程序时遇到了问题。使用以下代码无法下载:Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=package name")); startActivity(intent); - user2914699
我不是在谈论下载应用程序,而只是使用DefaultHttpClient检查网页以获取版本号。 - grunk
谢谢,这是个好主意。 - Lucifer
这实际上是个不好的主意,因为你可以为不同的设备提供不同的版本,而版本可能是“随设备而异”。 - Fenix Voltres

2

我发现了另一种方法,我是这样做的。

HttpPost httppostUserName = new HttpPost("https://androidquery.appspot.com/api/market?app=com.supercell.clashofclans"); //your package name
HttpClient httpclient = new DefaultHttpClient();

HttpResponse responseUser = httpclient.execute(httppostUserName);
String responseStringUser = EntityUtils.toString(responseUser.getEntity(), HTTP.UTF_8);

Log.d(Constants.TAG, "Response: " + responseStringUser);
try {
    JSONObject Json = new JSONObject(responseStringUser);
    newVersion = Json.getString("version");
} catch (Exception e) {
    e.printStackTrace();
}

如果您将URL粘贴到浏览器中查看结果,您将获得更清晰的视图。


您好,我无法从您的代码中获取版本名称。我没有得到JSON。 - Vrajesh
@Vrajesh 在你的浏览器中查看此链接:https://androidquery.appspot.com/api/market?app=com.supercell.clashofclans。同时检查一下你的包名。 - Salmaan
@Vrajesh,你的应用程序已经发布在Play商店上了吗?如果是的话,你应该能够看到版本和其他信息。你可以分享一下你的应用链接吗? - Salmaan
大家好,我无法获取Google Play商店的版本。如果有人有想法,请告诉我。 - Teraiya Mayur
能否请给出投反对票的人解释一下为什么要投反对票呢? - Salmaan
显示剩余4条评论

2
您可以使用Play Core Library In-app更新来解决此问题。如果有更新可用,您可以检查更新可用性无缝安装它们。
请注意,In-app更新仅适用于运行Android 5.0(API级别21)或更高版本的设备,并需要您使用Play Core Library 1.5.0或更高版本。
In-app更新与使用APK扩展文件(.obb文件)的应用程序不兼容。您可以选择灵活下载立即更新,Google Play会为您下载和安装更新。
dependencies {
    implementation 'com.google.android.play:core:1.5.0'
    ...
}

1

编辑

他们最近更改了Google Play网站,现在这个代码已经失效。避免使用此解决方案,或者准备在Google Play页面更改时修补您的应用程序。

Ahmad Arlan的答案目前是最好的答案。但如果你到这里并尝试剪切和粘贴他的代码,你会遇到我刚刚遇到的同样的问题,所以我也可以在这里发布它来帮助像我一样的其他人。


  1. Make sure you have INTERNET permission on your AndroidManifest.xml file.

    <uses-permission android:name="android.permission.INTERNET"/>
    
  2. Add JSOUP dependency to your module build.gradle.

    dependencies {
        compile 'org.jsoup:jsoup:1.10.2'
    }
    
  3. Surround the snippet with try and catch and don't run it on the main thread.

    public class MainActivity extends AppCompatActivity {
    
        String newVersion;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            new FetchAppVersionFromGooglePlayStore().execute();
        }
    
        class FetchAppVersionFromGooglePlayStore extends AsyncTask<String, Void, String> {
    
            protected String doInBackground(String... urls) {
                try {
                    return
                            Jsoup.connect("https://play.google.com/store/apps/details?id=" + "com.directed.android.smartstart" + "&hl=en")
                            .timeout(10000)
                            .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 (Exception e) {
                    return "";
                }
            }
    
            protected void onPostExecute(String string) {
                newVersion = string;
                Log.d("new Version", newVersion);
            }
        }
    }
    
我在github上发布了该项目的副本。

出现异常 - javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: 找不到证书路径的信任锚点。 - user3209435
@user3209435 确实,Google Play 进行了更改,现在这段代码已经不再可用。也许这不是最好的策略。我不再使用它。我们现在使用后端调用。 - GabrielOshiro

1
这对我有用。 添加此依赖项。
    implementation 'org.jsoup:jsoup:1.8.3'

在 onCreate() 方法中使用以下代码:
try {
       String currentVersion="";
        currentVersion = getApplicationContext().getPackageManager().getPackageInfo(getPackageName(), 0).versionName;

        Log.e("Current Version","::"+currentVersion);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }

    new GetVersionCode().execute();

创建获取版本代码的类 GetVersionCode:
private 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=" + 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) {
                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 (onlineVersion.equals(currentVersion)) {

            } else {
                AlertDialog alertDialog = new AlertDialog.Builder(context).create();
                alertDialog.setTitle("Update");
                alertDialog.setIcon(R.mipmap.ic_launcher);
                alertDialog.setMessage("New Update is available");

                alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Update", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        try {
                            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + context.getPackageName())));
                        } catch (android.content.ActivityNotFoundException anfe) {
                            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + context.getPackageName())));
                        }
                    }
                });

                alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });

                alertDialog.show();
            }

        }

        Log.d("update", "Current version " + currentVersion + "playstore version " + onlineVersion);

    }
}

0

Google Play 已经实现了这个功能。当您上传应用的新版本后,它会直接向用户设备发送通知或在用户在 Google Play 应用中开启了自动更新选项后会自动下载升级。


0

更新2019 Android Dev Summit

Google推出了应用内更新库。它适用于Lollipop+,并且可以让您使用漂亮的对话框(灵活)或强制全屏消息(立即)向用户请求更新。

应用内更新仅适用于运行Android 5.0(API级别21)或更高版本的设备。


0

注意政策违规,如果使用任何第三方框架进行应用程序更新,Google将暂停您的应用程序,我最近就遇到了这种情况。

enter image description here


0
 private void checkForUpdate() {
        PackageInfo packageInfo = null;
        try {      packageInfo=getPackageManager().getPackageInfo(DashboardActivity.this.getPackageName(), 0);
            int curVersionCode = packageInfo.versionCode
            if (curVersionCode > 1) {  // instead of one use value get from server for the new update.
                showUpdateDialog();
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }

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