使用 Umeng进行App 自定义更新

---恢复内容开始---

写在前面

突然发现CSDN竟然有了MarkDown文本编辑器功能,很开心,一定要学习学习。好了,下面言归正传。

这篇博文将解释我在项目中遇到的两个问题:

  • 如何做到APP强制更新(不能取消)
  • 如何才能做到不同环境在不同地方(umeng)更新apk

1. 实现APP强制更新

需求是如何才能使用Umeng的更新功能在自己的应用中实现强制更新APP的功能?
开始的时候我以为引入Umeng开发者中心提供的那几行代码就能把问题给解决掉,但是在转测时碰到各种各样的问题,就是启动Activity后再开启Umeng自动更新开关。但是不提示对话框(只有点返回键再进入才提示)。
原因就是我们那段代码是在MainActivity的onCreate()中写的,而项目中在只有在点击返回键时这个Activity才销毁。 很自然地我们想到把这一段代码写到onResume()中,虽然是切换到MainActivity中,能够解决掉这个问题,但是我们点击返回键时(应用切换到后台了),那个dialog却停留在手机桌面上。
这个dialog是个Activity,我们不能控制随着我们的Activity销毁而销毁。
最近两天有了一些思路,这个dialog自己从代码中创建,引用Umeng的布局和样式,然后使用Umeng官方提供的下载和更新方法。 同时为了在进入MainActivity后就必须更新,点击返回键直接把应用切到后台。我们必须让dialog跟随MainActivity消失而消失。也很简单,就是给dialog设置一个监听事件。

  1 UmengUpdateAgent.setUpdateAutoPopup(false);
  2         UmengUpdateAgent.setAppkey(CommonUtil.getAppKey(this));
  3         UmengUpdateAgent.setUpdateOnlyWifi(false);
  4         UmengUpdateAgent.setDeltaUpdate(false); // 全量更新
  5 
  6         UmengUpdateAgent.setUpdateListener(new UmengUpdateListener() {
  7 
  8             @Override
  9             public void onUpdateReturned(int updateStatus, UpdateResponse updateInfo) {
 10                 switch (updateStatus) {
 11                 // 有更新
 12                 case UpdateStatus.Yes: 
 13                     showUpdateDialog(updateInfo);
 14                     break;
 15                 }
 16             }
 17         });
 18 
 19 
 20     private void showUpdateDialog(UpdateResponse updateInfo) {
 21         //如果版本已经被忽略,不弹框
 22         if (UmengUpdateAgent.isIgnore(this, updateInfo)) {
 23             return;
 24         }
 25         //获取下载完的文件,如果未下载则为null
 26         final File file = UmengUpdateAgent.downloadedFile(this, updateInfo);
 27         boolean isDownloaded = file != null;
 28         //创建更新对话框
 29         createDialog(updateInfo, isDownloaded, file).show();
 30     }
 31 
 32     /**
 33      * 创建更新对话框
 34      * @param updateInfo 更新信息
 35      * @param isDownloaded 是否已经下载
 36      * @param file 下载完的文件,如果未下载为null
 37      * @return 更新对话框
 38      */
 39     private Dialog createDialog(final UpdateResponse updateInfo,
 40             boolean isDownloaded, final File file) {
 41         final boolean[] isIgnore = { false };
 42         final int[] result = { UpdateStatus.NotNow };
 43         final Context context = this;
 44 
 45         // 如果您的应用是全屏的,可以在这里设置Dialog也为全屏
 46         final Dialog dialog = new Dialog(context, android.R.style.Theme_Translucent_NoTitleBar);
 47         View v = LayoutInflater.from(context).inflate(R.layout.umeng_update_dialog, null);
 48 
 49         // 忽略勾选框的状态回调
 50         OnCheckedChangeListener cl = new OnCheckedChangeListener() {
 51 
 52             @Override
 53             public void onCheckedChanged(CompoundButton buttonView,
 54                     boolean isChecked) {
 55                 isIgnore[0] = isChecked;
 56             }
 57         };
 58         // 点击回调,记录用户的不同选择
 59         OnClickListener ll = new OnClickListener() {
 60 
 61             @Override
 62             public void onClick(View v) {
 63                 if (R.id.umeng_update_id_ok == v.getId()) {
 64                     result[0] = UpdateStatus.Update;
 65                 } else if (R.id.umeng_update_id_ignore == v.getId()) {
 66                     result[0] = UpdateStatus.Ignore;
 67                 } else if (isIgnore[0]) {
 68                     result[0] = UpdateStatus.Ignore;
 69                 }
 70                 dialog.dismiss();
 71             }
 72 
 73         };
 74         // 对话框消失回调,处理用户的不同选择
 75         dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
 76             @Override
 77             public void onDismiss(DialogInterface dialogInterface) {
 78                 switch (result[0]) {
 79                 case UpdateStatus.Update:
 80                     // 用户选择更新
 81                     if (file == null) {
 82                         //开始下载
 83                         UmengUpdateAgent.startDownload(context, updateInfo);
 84                     } else {
 85                         //开始安装
 86                         UmengUpdateAgent.startInstall(context, file);
 87                     }
 88                     break;
 89                 case UpdateStatus.Ignore:
 90                     // 用户选择忽略
 91                     UmengUpdateAgent.ignoreUpdate(context, updateInfo);
 92                     break;
 93                 case UpdateStatus.NotNow:
 94                     // 用户选择取消
 95                     break;
 96                 }
 97             }
 98         });
 99 
100         // 获得网络连接服务
101         ConnectivityManager connManager = (ConnectivityManager) context
102                 .getSystemService(Context.CONNECTIVITY_SERVICE);
103         // 获取WIFI网络连接状态
104         State state = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
105                 .getState();
106         // 如果正在使用WIFI网络或已经下载完成不显示无Wifi的图标
107         int visibility = (State.CONNECTED == state) || isDownloaded ? View.GONE
108                 : View.VISIBLE;
109         v.findViewById(R.id.umeng_update_wifi_indicator).setVisibility(
110                 visibility);
111 
112         v.findViewById(R.id.umeng_update_id_ok).setOnClickListener(ll);
113         v.findViewById(R.id.umeng_update_id_cancel).setOnClickListener(ll);
114         v.findViewById(R.id.umeng_update_id_ignore).setOnClickListener(ll);
115         v.findViewById(R.id.umeng_update_id_close).setOnClickListener(ll);
116         ((CheckBox) v.findViewById(R.id.umeng_update_id_check))
117                 .setOnCheckedChangeListener(cl);
118         // 设置对话框显示文本
119         String content = updateContentString(updateInfo, isDownloaded);
120         TextView tv = (TextView) v.findViewById(R.id.umeng_update_content);
121         tv.requestFocus();
122         tv.setText(content);
123 
124         dialog.setContentView(v);
125 
126         **// 在dialog显示时,点击返回键时,让dialog与Activity一起消失**
127         dialog.setOnKeyListener(new OnKeyListener() {
128 
129             @Override
130             public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
131                 if(keyCode == KeyEvent.KEYCODE_BACK) {
132                     dialog.dismiss();
133                     MainActivity.this.finish();
134                     return true;
135                 } else {
136                     return false;
137                 }
138             }
139         });
140 
141         return dialog;
142     }
143 
144 
145     /**
146      * 根据更新信息编排对话框显示文本
147      * 
148      * @param updateInfo
149      *            更新信息
150      * @param isDownloaded
151      *            是否已经下载
152      * @return 更新对话框显示文本
153      */
154     public String updateContentString(UpdateResponse updateInfo,
155             boolean isDownloaded) {
156         String versionPrefix = getString(R.string.UMNewVersion);
157         String sizePrefix = getString(R.string.UMTargetSize);
158         String deltaPrefix = getString(R.string.UMUpdateSize);
159         String updateLogPrefix = getString(R.string.UMUpdateContent);
160         String installApk = getString(R.string.UMDialog_InstallAPK);
161         // 已经下载的情况
162         if (isDownloaded) {
163             return String.format("%s %s\n" + "%s\n\n" + "%s\n" + "%s\n",
164                     versionPrefix, updateInfo.version, installApk,
165                     updateLogPrefix, updateInfo.updateLog);
166         }
167 
168         String deltaContent;
169         // 增量更新和全量更新的情况
170         if (updateInfo.delta) {
171             deltaContent = String.format("\n%s %s", deltaPrefix,
172                     CommonUtil.getFileSizeDescription(updateInfo.size));
173         } else {
174             deltaContent = "";
175         }
176         // 未下载的情况
177         return String.format("%s %s\n" + "%s %s%s\n\n" + "%s\n" + "%s\n",
178                 versionPrefix, updateInfo.version, sizePrefix,
179                 CommonUtil.getFileSizeDescription(updateInfo.target_size), deltaContent,
180                 updateLogPrefix, updateInfo.updateLog);
181     }

 

声明:上面代码并非个人原创,自己参考了网上的一些内容,并加以修改适合项目需求。 我们还是要多看Umeng官方提供的文档和demo。


2. 实现不同的环境到不同的Umeng更新apk

这实际是很简单的,自己如果在想在测试环境更新上线环境的apk,那么可以再申请一个Umeng帐号,获取一个key,在代码中通过标记位控制让它们到不同Umeng帐号下去下载apk文件。

希望上面内容对大家有所帮助~

reference:
[Umeng 官方文档]

 

---恢复内容结束---

写在前面

突然发现CSDN竟然有了MarkDown文本编辑器功能,很开心,一定要学习学习。好了,下面言归正传。

这篇博文将解释我在项目中遇到的两个问题:

  • 如何做到APP强制更新(不能取消)
  • 如何才能做到不同环境在不同地方(umeng)更新apk

1. 实现APP强制更新

需求是如何才能使用Umeng的更新功能在自己的应用中实现强制更新APP的功能?
开始的时候我以为引入Umeng开发者中心提供的那几行代码就能把问题给解决掉,但是在转测时碰到各种各样的问题,就是启动Activity后再开启Umeng自动更新开关。但是不提示对话框(只有点返回键再进入才提示)。
原因就是我们那段代码是在MainActivity的onCreate()中写的,而项目中在只有在点击返回键时这个Activity才销毁。 很自然地我们想到把这一段代码写到onResume()中,虽然是切换到MainActivity中,能够解决掉这个问题,但是我们点击返回键时(应用切换到后台了),那个dialog却停留在手机桌面上。
这个dialog是个Activity,我们不能控制随着我们的Activity销毁而销毁。
最近两天有了一些思路,这个dialog自己从代码中创建,引用Umeng的布局和样式,然后使用Umeng官方提供的下载和更新方法。 同时为了在进入MainActivity后就必须更新,点击返回键直接把应用切到后台。我们必须让dialog跟随MainActivity消失而消失。也很简单,就是给dialog设置一个监听事件。

UmengUpdateAgent.setUpdateAutoPopup(false);
        UmengUpdateAgent.setAppkey(CommonUtil.getAppKey(this));
        UmengUpdateAgent.setUpdateOnlyWifi(false);
        UmengUpdateAgent.setDeltaUpdate(false); // 全量更新

        UmengUpdateAgent.setUpdateListener(new UmengUpdateListener() {

            @Override
            public void onUpdateReturned(int updateStatus, UpdateResponse updateInfo) {
                switch (updateStatus) {
                // 有更新
                case UpdateStatus.Yes: 
                    showUpdateDialog(updateInfo);
                    break;
                }
            }
        });


    private void showUpdateDialog(UpdateResponse updateInfo) {
        //如果版本已经被忽略,不弹框
        if (UmengUpdateAgent.isIgnore(this, updateInfo)) {
            return;
        }
        //获取下载完的文件,如果未下载则为null
        final File file = UmengUpdateAgent.downloadedFile(this, updateInfo);
        boolean isDownloaded = file != null;
        //创建更新对话框
        createDialog(updateInfo, isDownloaded, file).show();
    }

    /**
     * 创建更新对话框
     * @param updateInfo 更新信息
     * @param isDownloaded 是否已经下载
     * @param file 下载完的文件,如果未下载为null
     * @return 更新对话框
     */
    private Dialog createDialog(final UpdateResponse updateInfo,
            boolean isDownloaded, final File file) {
        final boolean[] isIgnore = { false };
        final int[] result = { UpdateStatus.NotNow };
        final Context context = this;

        // 如果您的应用是全屏的,可以在这里设置Dialog也为全屏
        final Dialog dialog = new Dialog(context, android.R.style.Theme_Translucent_NoTitleBar);
        View v = LayoutInflater.from(context).inflate(R.layout.umeng_update_dialog, null);

        // 忽略勾选框的状态回调
        OnCheckedChangeListener cl = new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                isIgnore[0] = isChecked;
            }
        };
        // 点击回调,记录用户的不同选择
        OnClickListener ll = new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (R.id.umeng_update_id_ok == v.getId()) {
                    result[0] = UpdateStatus.Update;
                } else if (R.id.umeng_update_id_ignore == v.getId()) {
                    result[0] = UpdateStatus.Ignore;
                } else if (isIgnore[0]) {
                    result[0] = UpdateStatus.Ignore;
                }
                dialog.dismiss();
            }

        };
        // 对话框消失回调,处理用户的不同选择
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialogInterface) {
                switch (result[0]) {
                case UpdateStatus.Update:
                    // 用户选择更新
                    if (file == null) {
                        //开始下载
                        UmengUpdateAgent.startDownload(context, updateInfo);
                    } else {
                        //开始安装
                        UmengUpdateAgent.startInstall(context, file);
                    }
                    break;
                case UpdateStatus.Ignore:
                    // 用户选择忽略
                    UmengUpdateAgent.ignoreUpdate(context, updateInfo);
                    break;
                case UpdateStatus.NotNow:
                    // 用户选择取消
                    break;
                }
            }
        });

        // 获得网络连接服务
        ConnectivityManager connManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        // 获取WIFI网络连接状态
        State state = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
                .getState();
        // 如果正在使用WIFI网络或已经下载完成不显示无Wifi的图标
        int visibility = (State.CONNECTED == state) || isDownloaded ? View.GONE
                : View.VISIBLE;
        v.findViewById(R.id.umeng_update_wifi_indicator).setVisibility(
                visibility);

        v.findViewById(R.id.umeng_update_id_ok).setOnClickListener(ll);
        v.findViewById(R.id.umeng_update_id_cancel).setOnClickListener(ll);
        v.findViewById(R.id.umeng_update_id_ignore).setOnClickListener(ll);
        v.findViewById(R.id.umeng_update_id_close).setOnClickListener(ll);
        ((CheckBox) v.findViewById(R.id.umeng_update_id_check))
                .setOnCheckedChangeListener(cl);
        // 设置对话框显示文本
        String content = updateContentString(updateInfo, isDownloaded);
        TextView tv = (TextView) v.findViewById(R.id.umeng_update_content);
        tv.requestFocus();
        tv.setText(content);

        dialog.setContentView(v);

        **// 在dialog显示时,点击返回键时,让dialog与Activity一起消失**
        dialog.setOnKeyListener(new OnKeyListener() {

            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if(keyCode == KeyEvent.KEYCODE_BACK) {
                    dialog.dismiss();
                    MainActivity.this.finish();
                    return true;
                } else {
                    return false;
                }
            }
        });

        return dialog;
    }


    /**
     * 根据更新信息编排对话框显示文本
     * 
     * @param updateInfo
     *            更新信息
     * @param isDownloaded
     *            是否已经下载
     * @return 更新对话框显示文本
     */
    public String updateContentString(UpdateResponse updateInfo,
            boolean isDownloaded) {
        String versionPrefix = getString(R.string.UMNewVersion);
        String sizePrefix = getString(R.string.UMTargetSize);
        String deltaPrefix = getString(R.string.UMUpdateSize);
        String updateLogPrefix = getString(R.string.UMUpdateContent);
        String installApk = getString(R.string.UMDialog_InstallAPK);
        // 已经下载的情况
        if (isDownloaded) {
            return String.format("%s %s\n" + "%s\n\n" + "%s\n" + "%s\n",
                    versionPrefix, updateInfo.version, installApk,
                    updateLogPrefix, updateInfo.updateLog);
        }

        String deltaContent;
        // 增量更新和全量更新的情况
        if (updateInfo.delta) {
            deltaContent = String.format("\n%s %s", deltaPrefix,
                    CommonUtil.getFileSizeDescription(updateInfo.size));
        } else {
            deltaContent = "";
        }
        // 未下载的情况
        return String.format("%s %s\n" + "%s %s%s\n\n" + "%s\n" + "%s\n",
                versionPrefix, updateInfo.version, sizePrefix,
                CommonUtil.getFileSizeDescription(updateInfo.target_size), deltaContent,
                updateLogPrefix, updateInfo.updateLog);
    }

声明:上面代码并非个人原创,自己参考了网上的一些内容,并加以修改适合项目需求。 我们还是要多看Umeng官方提供的文档和demo。


2. 实现不同的环境到不同的Umeng更新apk

这实际是很简单的,自己如果在想在测试环境更新上线环境的apk,那么可以再申请一个Umeng帐号,获取一个key,在代码中通过标记位控制让它们到不同Umeng帐号下去下载apk文件。

希望上面内容对大家有所帮助~

reference:
[Umeng 官方文档]

 

posted on 2015-03-14 21:29  jinfenglee  阅读(744)  评论(0编辑  收藏  举报

导航