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

时间:2013-10-08 09:44:54

标签: android

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

20 个答案:

答案 0 :(得分:77)

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

versionCheck API:

请求参数:

  • int appVersion

响应

  1. boolean forceUpgrade
  2. boolean recommendUpgrade
  3. 当您的应用启动时,您可以调用此API以传递当前应用版本,并检查版本控制API调用的响应。

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

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

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

答案 1 :(得分:46)

试试这个: 首先,您需要调用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();
    }

答案 2 :(得分:45)

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

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

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

答案 3 :(得分: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)));

            }
        });
    }
}

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

答案 4 :(得分:5)

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

答案 5 :(得分:4)

Google正式为此提供了一个Android API。

  

该API目前正在与一些合作伙伴进行测试,并将很快对所有开发人员开放。

答案 6 :(得分:4)

我强烈建议您查看Firebase's Remote Config功能。

我使用参数 - 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小时他们推荐的缓存到期值。

答案 7 :(得分:2)

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

  1. 创建一个Web服务,从我们的服务器为app(ios,android)提供最新版本。
  2. 或者您在应用中使用的任何网络服务(例如登录)都将从服务器返回最新的应用版本。
  3. 一旦应用程序将从#1或2获得版本。应用程序将与本地/ cuurent appversion交叉检查。如果有差异,我们可以显示如下警告,
  4. Android&amp; iOS: 如果最新的应用程序版本可用,那么它将显示警报“具有更多功能的最新版本,升级点击升级按钮”(警报与“Upgarde”和“号码谢谢”按钮。) 然后app将重定向到playstore / Appstore,它将打开最新版本。

     --- we can do upgrade compulsory or optionally.
    

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

答案 8 :(得分:2)

Google引入了应用内更新库(https://developer.android.com/guide/app-bundle/in-app-updates),该库可在Lollipop +上运行,并且使您能够通过优美的对话框(FLEXIBLE)或强制性全屏消息(IMMEDIATE)向用户询问更新)。

您需要实现后者。 它是这样的: enter image description here

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

答案 9 :(得分:1)

检查本地和游戏商店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>

答案 10 :(得分:1)

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

答案 11 :(得分:1)

这里肯定要提到的是即将发布的 In-app Updates API

  

使用此API,您将有两个选择;第一种是当您期望用户等待立即应用更新时对关键更新的全屏体验。第二个选项是灵活的更新,这意味着用户可以在下载更新时继续使用该应用程序。您可以完全自定义更新流程,使它看起来像是您应用程序的一部分。

答案 12 :(得分:1)

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

  1. 创建 Firebase 数据库
  2. 添加您的最新版本
  3. 如果版本与安装的版本不同,则显示安装更新的弹出窗口。它非常适合我......

答案 13 :(得分:0)

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

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

答案 14 :(得分:0)

你可以通过在变量中保存在应用程序上的版本号之间进行匹配来实现这一点,同样当前应用程序版本保留在服务器端,每次用户打开应用程序时,应发送第一个请求以检查如果它发现匹配什么都不做,只需让用户使用你的应用程序,否则向谷歌Playstore发出意图或打开你的应用程序的webview窗口(window.open(&#34; https://play.google.com/store/apps/details?id=package_name&#34;,&# 39; _system&#39;,&#39; location = yes&#39;);)然后,如果您没有自动更新,他们将自动拥有要求更新的按钮,即谷歌Playstore为您做的更新。

答案 15 :(得分:0)

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

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

  1. 只需将您应用的最新版本代码保存在Firebase Remote
    配置面板
  2. 每当应用程序处于运行状态时,获取该版本代码值 打开
  3. 将其与应用程序的当前版本代码进行比较,您可以通过以下代码获得

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

    }

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

因此,每当推出新版本时,都需要将新版本代码放在Firebase远程配置面板中

您可以在how to force users to update the app using Firebase Remote Config

上阅读整个教程。

答案 16 :(得分:0)

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

简单的逻辑快乐编码。

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

答案 17 :(得分:0)

您可以使用Play Core Library应用内更新来解决此问题。您可以检查更新是否可用,如果可以无缝安装,请安装它们。

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

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

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

答案 18 :(得分: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){ 返回false; }

if(!compareArray){ for(var i = 0; i if(activeVersionArr [i]!== currentVersionArr [i]){
if(activeVersionArr [i]> currentVersionArr [i]){ 返回true; }其他{ 返回false; }
} } }

答案 19 :(得分:-2)

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

我实现了一个轻量级的库来轻松实现应用内更新。

https://github.com/dnKaratzas/android-inapp-update