当新版本可用时强制更新Android应用程序

ash*_*ful 86 android

我在Google Play商店中有一款应用.当更新版本可用时,旧版本将变得无法使用 - 也就是说,如果用户未更新应用程序,则他们不会进入应用程序.当新版本可用时,如何强制用户更新应用程序?

Mic*_*ael 85

我同意Scott Helme的观点.但在某些极端情况下(安全问题,API中断更改......)您绝对需要用户更新以继续使用该应用程序,您可以提供简单的版本控制API.API看起来像这样:

versionCheck API:

请求参数:

  • int appVersion

响应

  1. boolean forceUpgrade
  2. boolean recommendUpgrade

当您的应用启动时,您可以调用此API传递当前应用版本,并检查版本控制API调用的响应.

如果forceUpgradetrue,则显示一个弹出式对话框,其中包含允许用户退出应用的选项,或者转到Google Play商店以升级应用.

否则,如果recommendUpgradetrue,显示的选项弹出对话框更新或继续使用应用程序.

即使有这种强制升级功能,您仍应继续支持旧版本,除非绝对需要.

  • 对于推荐的升级,我认为如果用户拒绝,您不应该再次显示.你也可以"每n次用户打开应用程序一次"显示它.您可以自己决定n值并实现它. (8认同)
  • @SepGH 自那以后情况发生了变化,Android 现在提供了一个 API,您可以使用该 API 强制用户升级并阻止他在未升级到最低版本的情况下继续使用该应用程序:https://developer.android。 com/guide/app-bundle/in-app-updates (6认同)
  • 一个更好的解决方案imo是在所有API调用的标头中系统地传递应用程序的版本,然后让API返回特定的状态代码,如果它检测到版本已过时.然后在应用程序内处理它.这比为此检查调用另一个专用API更好,并且必须弄清楚应该在app/service内完成此API调用的时间/位置. (3认同)
  • @RaphaelC 这实际上取决于您的服务器端实现。在某些情况下,添加一个检查所有 API 版本的过滤器也并不完美。 (2认同)

Ash*_*rma 51

试试这个:首先你需要调用playstore链接,从那里获取当前版本,然后将它与你当前的版本进行比较.

String currentVersion, latestVersion;
Dialog dialog;
private void getCurrentVersion(){
 PackageManager pm = this.getPackageManager();
        PackageInfo pInfo = null;

        try {
            pInfo =  pm.getPackageInfo(this.getPackageName(),0);

        } catch (PackageManager.NameNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        currentVersion = pInfo.versionName;

   new GetLatestVersion().execute();

}

private class GetLatestVersion extends AsyncTask<String, String, JSONObject> {

        private ProgressDialog progressDialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected JSONObject doInBackground(String... params) {
            try {
//It retrieves the latest version by scraping the content of current version from play store at runtime
                Document doc = Jsoup.connect(urlOfAppFromPlayStore).get();
                latestVersion = doc.getElementsByClass("htlgb").get(6).text();

            }catch (Exception e){
                e.printStackTrace();

            }

            return new JSONObject();
        }

        @Override
        protected void onPostExecute(JSONObject jsonObject) {
            if(latestVersion!=null) {
                if (!currentVersion.equalsIgnoreCase(latestVersion)){
                   if(!isFinishing()){ //This would help to prevent Error : BinderProxy@45d459c0 is not valid; is your activity running? error
                    showUpdateDialog();
                    }
                }
            }
            else
                background.start();
            super.onPostExecute(jsonObject);
        }
    }

private void showUpdateDialog(){
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("A New Update is Available");
        builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse
                        ("market://details?id=yourAppPackageName")));
                dialog.dismiss();
            }
        });

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                background.start();
            }
        });

        builder.setCancelable(false);
        dialog = builder.show();
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果您觉得答案有用,请亲自投票 (3认同)
  • 如果他们改变 itemprop 值怎么办? (2认同)

Sco*_*lme 45

新版本发布后,您不应该停止支持旧版本.这将导致糟糕的用户体验.我不知道有任何软件供应商存在这样做,这是有充分理由的.

如果用户当时无法更新或不想要怎么办?他们根本无法使用你的应用程序,这很糟糕.

谷歌不提供任何版本跟踪选项,所以你必须自己动手.一个简单的Web服务可以返回您的应用程序可以检查的当前实时版本就足够了.然后,您可以更新版本,应用程序将知道它已过时.我建议您使用此功能,让您的用户知道有更新的速度比Google Play更快.它不应该用于阻止应用程序工作,只是为了提示用户更新.

  • @ashraful 如果这个或任何答案解决了您的问题,请通过单击复选标记考虑 [接受它](http://meta.stackexchange.com/q/5234/179419)。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己赢得了一些声誉。没有义务这样做。 (2认同)
  • Supercell 只支持他们游戏的最新版本。在他们将新版本推送到 Google Play 后,任何尝试连接的旧客户端都会收到来自服务器的“需要更新”响应并看到连接已关闭。他们每年都这样做多次。因此,除非您不想将“游戏公司”视为“软件供应商”,否则现在您知道了 :) 考虑到他们每天仍在赚取数百万美元,显然这种糟糕的用户体验并不能阻止节目的发展. (2认同)

Kir*_*zin 20

Google 引入了应用内更新库,(https://developer.android.com/guide/app-bundle/in-app-updates)它适用于 Lollipop+ 并让您能够通过一个很好的方式向用户询问更新对话框 (FLEXIBLE) 或带有强制全屏消息 (IMMEDIATE)。

您需要实现后者。这是它的样子: 在此处输入图片说明

我涵盖了这个答案中的所有代码:https : //stackoverflow.com/a/56808529/5502121

  • IMMEDIATE 模式仍然允许用户退出该屏幕:( (3认同)
  • 这是最好的答案! (2认同)
  • 此功能实际上依赖于当用户启动您的应用程序时 Play 缓存是最新的,即如果缓存中应用程序的版本号与 Playstore 上最新部署的版本号不同,则它不会提示用户。 (2认同)

bsa*_*ner 16

斯科特和迈克尔的答案是正确的.托管一项服务,该服务提供您支持的最小版本号,并将其与已安装的版本进行比较.你应该永远不需要使用它,但是如果有一些版本在那里,你必须要因为一些严重的缺陷而必须杀死它.

我只想添加下一步的代码.以下是在您提示用户必须升级之后启动Google Play Intent并将其带到商店中的新版本的方法.

public class UpgradeActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upgrade);
        final String appName = "com.appname";
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id="+appName)));

            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

如果必须在每个版本上强制升级,则应重新考虑您的设计.


Gak*_*ket 15

Google团队的解决方案

从Android 5.0开始,可以通过新的Google Play In App更新机制轻松实现。要求是拥有1.5.0+版本的Play Core库,并使用App Bundles idstribution而不是apks。

该库提供了两种通知用户有关更新的不同方法:

  1. 灵活,当用户在后台对其进行更新时可以继续使用该应用程序时。

  2. 立即-阻止屏幕,直到用户对其进行更新为止,该屏幕不允许用户进入。

有实现它的下一步:

  1. 检查更新可用性
  2. 开始更新
  3. 获取更新状态的回调
  4. 处理更新

所有这些步骤的实现均在官方网站上进行了详细描述:https//developer.android.com/guide/app-bundle/in-app-updates


Chu*_*ulo 8

谷歌官方为此提供了一个Android API。

该 API 目前正在与少数合作伙伴进行测试,并将很快提供给所有开发人员。

更新 API 现已可用 - https://developer.android.com/guide/app-bundle/in-app-updates

  • 另请参阅:https://android-developers.googleblog.com/2018/11/unfolding-right-now-at-androiddevsum​​mit.html (2认同)

Cha*_*ejo 5

我强烈建议您为此检查Firebase的Remote Config功能。

我使用参数app_version_enabled实现了它,条件为“ Disabled Android Versions”,如下所示:

applies if App ID == com.example.myapp and App version regular expression ^(5.6.1|5.4.2) 
Run Code Online (Sandbox Code Playgroud)

参数的默认值为“ true”,但“ Disabled Android Versions”的值为false。在禁用Android版本的正则表达式中,您可以添加更多禁用版本,只需|{version name}在括号内添加另一个即可。

然后,我只是检查配置是否显示版本已启用-我启动了一项活动,该活动会强制用户进行升级。我检查了可以从外部启动应用程序的仅有两个位置(我的默认启动器活动和意图处理活动)。由于Remote Config是基于缓存工作的,因此,如果没有经过必要的时间才能使缓存无效,则它不会立即捕获应用程序的“已禁用”版本,但是如果您经过的时间最多为12个小时,他们推荐的缓存过期值。