129

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

4

20 回答 20

118

我同意 Scott Helme 在另一个答案中的观点。但是在某些极端情况下(安全问题、API 重大更改...),您绝对需要用户更新以继续使用应用程序,您可以提供一个简单的版本控制 API。API 如下所示:

版本检查 API:

请求参数:

  • int appVersion

回复

  1. boolean forceUpgrade
  2. boolean recommendUpgrade

当您的应用启动时,您可以调用这个传入当前应用版本的 API,并检查版本控制 API 调用的响应。

如果forceUpgradetrue,则显示一个弹出对话框,其中包含让用户退出应用程序或转到 Google Play 商店升级应用程序的选项。

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

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

于 2013-12-06T06:18:03.337 回答
60

试试这个:首先,您需要对 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();
    }
于 2015-10-05T06:52:41.187 回答
48

新版本一出,你不应该停止支持旧版本。这将导致糟糕的用户体验。我不知道有任何软件供应商这样做,这是有充分理由的。

如果用户当时不能更新或不想更新会发生什么?他们根本无法使用您的应用程序,这很糟糕。

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

于 2013-10-08T09:56:19.630 回答
36

谷歌团队的解决方案

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

该库为您提供了 2 种不同的方式来通知用户更新:

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

  2. 立即 - 阻止用户在更新之前不允许进入应用程序的屏幕。

有以下步骤来实施它:

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

所有这些步骤的实现在官网都有详细描述:https ://developer.android.com/guide/app-bundle/in-app-updates

于 2019-05-08T07:36:26.773 回答
24

谷歌推出了应用内更新库(https://developer.android.com/guide/app-bundle/in-app-updates),它适用于 Lollipop+,并让您能够以不错的方式向用户询问更新对话框 (FLEXIBLE) 或带有强制全屏消息 (IMMEDIATE)。

您需要实现后者。这是它的样子: 在此处输入图像描述

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

于 2019-06-28T14:16:21.513 回答
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)));

            }
        });
    }
}

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

于 2014-01-31T16:31:48.857 回答
9

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

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

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

于 2018-11-09T14:17:34.150 回答
8

我强烈建议为此检查Firebase 的远程配置功能。

我使用参数 app_version_enabled 实现了它,条件是“禁用的 Android 版本”,如下所示:

applies if App ID == com.example.myapp and App version regular expression ^(5.6.1|5.4.2) 

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

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

于 2016-12-13T23:39:59.503 回答
3

检查本地和Play商店apk的版本代码

try {
        versionChecker VersionChecker = new versionChecker();
        String versionUpdated = VersionChecker.execute().get().toString();
        Log.i("version code is", versionUpdated);


        PackageInfo packageInfo = null;
        try {
            packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        int version_code = packageInfo.versionCode;
        String version_name = packageInfo.versionName;
        Log.i("updated version code", String.valueOf(version_code) + "  " + version_name);
        if (version_name != versionUpdated) {
            String packageName = getApplicationContext().getPackageName();//
            UpdateMeeDialog updateMeeDialog = new UpdateMeeDialog();
            updateMeeDialog.showDialogAddRoute(MainActivity.this, packageName);
            Toast.makeText(getApplicationContext(), "please updated", Toast.LENGTH_LONG).show();
        }
    } catch (Exception e) {
        e.getStackTrace();
    }

实现版本检查类

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=+YOR_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();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return newVersion;
}
}

用于更新的对话框

public class UpdateMeeDialog {

ActivityManager am;
TextView rootName;
Context context;
Dialog dialog;
String key1,schoolId;
public void showDialogAddRoute(Activity activity, final String packageName){
    context=activity;
    dialog = new Dialog(context);

    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setCancelable(false);
    dialog.setContentView(R.layout.dialog_update);
    am = (ActivityManager)activity.getSystemService(Context.ACTIVITY_SERVICE);

    Button cancelDialogue=(Button)dialog.findViewById(R.id.buttonUpdate);
    Log.i("package name",packageName);
    cancelDialogue.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent=new Intent(Intent.ACTION_VIEW);                
    intent.setData(Uri.parse("https://play.google.com/store/apps/details?
    id="+packageName+"&hl=en"));
            context.startActivity(intent);
        }
    });
    dialog.show();
}
}

对话框布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#d4e9f2">


<TextView
    android:layout_width="match_parent"
    android:layout_height="40dp"

    android:text="Please Update First..!!"
    android:textSize="20dp"
    android:textColor="#46a5df"
    android:textAlignment="center"
    android:layout_marginTop="50dp"
    android:id="@+id/textMessage"
    />
<LinearLayout
    android:layout_width="match_parent"
    android:orientation="horizontal"
    android:weightSum="1"
    android:layout_marginTop="50dp"
    android:layout_below="@+id/textMessage"
    android:layout_height="50dp">

    <Button
        android:id="@+id/buttonUpdate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Update"
        android:background="#67C6F1"
        android:textAlignment="center" />
</LinearLayout>

于 2017-10-06T09:43:01.807 回答
3

您可以使用 Play Core Library 应用内更新来解决这个问题。您可以检查更新可用性并在可用时无缝安装它们。

应用内更新与使用 APK 扩展文件(.obb 文件)的应用不兼容。您可以选择灵活下载或即时更新,Google Play 会为您下载和安装更新。

dependencies {
    implementation 'com.google.android.play:core:1.5.0'
    ...
}

请参阅此答案https://stackoverflow.com/a/58212818/7579041

于 2019-10-03T05:25:13.577 回答
2

最好定义我们自己的升级流程。

  1. 从我们的服务器创建一个为应用程序(ios、android)提供最新版本的 Web 服务。
  2. 或者您在应用程序中使用的任何网络服务(例如登录)将从服务器返回最新的应用程序版本。
  3. 一旦应用程序将从 #1 或 2 获取版本。应用程序将与本地/当前应用程序版本进行交叉检查。如果有差异,那么我们可以如下显示警报,

Android & iOS : 如果最新的应用程序版本可用,那么它会显示警报为“最新版本提供更多功能,要升级点击升级按钮”(警报与“升级”和“不。谢谢”按钮。)然后应用程序将重定向到playstore/Appstore,它将打开最新版本。

 --- we can do upgrade compulsory or optionally.

如果有任何数据库架构更改,请确保在升级过程之前处理正确的数据库迁移过程。

于 2015-05-26T10:22:47.617 回答
1

我使用了一种简单的方法来完成这项工作:

  1. 创建 Firebase 数据库
  2. 添加您的最新版本
  3. 如果版本与安装的版本不同,则显示安装更新的弹出窗口。它对我来说非常有效......
于 2020-12-30T07:25:01.097 回答
1

对应用程序版本使用远程配置是个好主意,如果不强制从应用程序商店更新,则始终检查启动活动是否当前应用程序版本与远程版本相同。

简单的逻辑快乐编码..

https://firebase.google.com/docs/remote-config/android

于 2019-06-21T11:15:29.180 回答
1

What should definitely be mentioned here is the soon-to-be released In-app Updates API.

You'll have two options with this API; the first is a full-screen experience for critical updates when you expect the user to wait for the update to be applied immediately. The second option is a flexible update, which means the user can keep using the app while the update is downloaded. You can completely customize the update flow so it feels like part of your app.

于 2019-01-29T09:09:51.163 回答
1

如果市场上有更新,则强制应用用户更新,您应该首先检查市场上的应用版本,并将其与设备上的应用版本进行比较。如果它们不同,则可能是可用的更新。在这篇文章中,我写下了获取当前市场版本和设备上当前版本的代码,并将它们放在一起进行比较。我还展示了如何显示更新对话框并将用户重定向到更新页面。请访问此链接:https ://stackoverflow.com/a/33925032/5475941只需确保在对话框中只显示用户更新按钮而不显示取消按钮。在这种情况下,他将被迫更新,然后才能使用该应用程序。

于 2016-02-13T19:24:11.420 回答
1

Google 发布了 Play Core 库的应用内更新。

我实现了一个轻量级库来轻松实现应用内更新。您可以在以下链接中找到有关如何强制用户执行更新的示例。

https://github.com/dnKaratzas/android-inapp-update#forced-updates

于 2019-07-21T13:15:39.743 回答
0

好吧,这个问题可能有很多解决方案,比如从应用页面(Google Play 应用页面)抓取版本代码等。

但我将向您展示最终解决方案,它不会花费一分钱,并且会像魔术一样工作。


  1. 只需在 Firebase 远程配置面板上保存您应用的最新版本代码
  2. 每当打开应用程序时获取该版本代码值
  3. 与应用当前版本代码对比,可以通过以下代码获取

    private int getCurrentVersionCode() {
    try {
        return getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
    } catch (NameNotFoundException e) {
        e.printStackTrace();
    }
    return -1;
    

    }

如果获取的版本代码大于当前版本,则显示一个 AlertDialog 要求更新应用程序。否则,应用程序已经更新。

因此,无论何时推出新版本,都需要将新版本代码放入 Firebase 远程配置面板

您可以阅读有关如何强制用户使用 Firebase 远程配置更新应用程序的整个教程

于 2019-06-21T10:38:34.197 回答
0
var activeVersion = "3.9.2";

var currentVersion = "3.9.1";

var activeVersionArr = activeVersion.split(".");
var currentVersionArr = currentVersion.split(".");

var compareArray =JSON.stringify(activeVersionArr)==JSON.stringify(currentVersionArr);
   
if(compareArray){
  return false;
}

if(!compareArray){
  for(var i=0;i<activeVersionArr.length;i++){      
      if(activeVersionArr[i]!==currentVersionArr[i]){            
        if(activeVersionArr[i] > currentVersionArr[i]){
          return true;
        }else{
          return false;
        }          
      }
  }
}
于 2020-09-10T04:41:12.883 回答
0

您可以通过在变量中保存在应用程序中的版本号与类似地保存在服务器端的当前应用程序版本之间进行匹配来做到这一点,并且每次用户打开应用程序时都应发送第一个请求以检查是否找到匹配什么都不做,只是让用户使用您的应用程序,否则会向 google playstore 触发意图或打开您的应用程序的 webview 窗口(window.open(“ https://play.google.com/store/apps/details?id= package_name ", '_system', 'location=yes');) 如果你没有自动更新,他们会自动有按钮要求更新,这就是谷歌 Playstore 为你做的事情。

于 2016-03-06T07:49:32.667 回答
0

您可以通知您的用户当前应用程序有新版本可供更新。此外,如果此条件为真,您可以在应用程序中阻止登录。

请看看是否为您提供了解决方案。

于 2016-10-12T18:45:10.867 回答