序言

相信很多做SDK或者应用都有这个需求,强更游戏或者应用,但是网上又鱼龙混珠,代码混乱可能也对不上需求,这里我就想做一个简单的功能:

在判断需要强更的时候,弹出窗口提示更新,点击更新随后就是进度条显示下载进度,最后跳转安装页面,搞定!


示例图

这里提供了两套方案。

方案一:采用系统自带的Dialog和ProgressDialog

优雅地更新Android Apk_android

方案二:采用自定义UI布局文件来写弹框:

优雅地更新Android Apk_适配_02

两套方案都可以,做SDK的话推荐采用第一种,这样可以减少资源文件的引入和索引,节省SDK资源开销。

实现步骤

  1. 自定义UI布局
UpdateTipsDialog dialog = new UpdateTipsDialog(MainActivity.this);
dialog.show("发现更新", "全新3.8版本 「清夏!乐园?大秘境!」现已推出!\n"
    + "\n" + "【限时区域】琉形蜃境\n"
    + "一切都是在小小的琉璃瓶子中发生的故事。传言在沙漠的中心有一处神奇的秘境,进入秘境的人就能实现他们的愿望。\n"
    + "而事实真相又是如何呢,无人知悉,在那小小的瓶中世界之中,又装着多少旅人犹如蜃影般的热望?\n"
    + "\n" + "【新活动】版本主题活动 「清夏!乐园?大秘境!」、阶段性活动「传心同视」、「险途勘探」、「冒险家试炼·进阶篇」\n"
    + "炽烈的夏日阳光渐渐笼罩大地,在派蒙的建议下,你们回到了西风骑士团的总部,意外得知了某件奇妙之事,一场特别的冒险即将拉开帷幕…\n"
    + "完成主题活动任务,可邀请四星角色「绮思晚星 · 莱依拉(冰)」。\n" + "\n"
    + "【新剧情】邀约任务更新\n" + "邀约事件 · 凯亚 第一幕 「鬼话与甜酒」\n" + "\n"
    + "【新衣装】可莉衣装「琪花星烛」、凯亚衣装「帆影游风」\n"
    + "全新角色衣装「琪花星烛」是可莉出演关键剧目时所穿的精致服装,色彩明丽,如同点缀着奶油花朵和明红蜡烛的蛋糕,能将快乐与笑容带往冒险所至的每个角落。\n"
    + "「帆影游风」是凯亚在舞台上饰演「短刀大盗」时的装扮,以「吸睛」为设计原则的华丽服装。不过衣服穿起来并不麻烦,最花时间打理的是饰品与短刀。\n"
    + "\n" + "【七圣召唤更新】全新角色牌、全新行动牌\n" + "全新角色牌、行动牌开放获取。", false, editDownloadUrl.getText().toString());

int screenHeight = displayMetrics.heightPixels;
int maxHeight = (int) (screenHeight * 0.8); // 设置为屏幕高度的80%
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, maxHeight);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
dialog.getWindow().setLayout(layoutParams.WRAP_CONTENT, maxHeight);

dialog的show方法,它接受四个参数:title(标题)、tips(提示信息)、isForced(是否强制显示)和url(更新的URL地址)。isForced你可以设置是否强制更新,若强制更新,用户默认无法通过后退按钮关闭更新对话框。你可以设置其中的标题title和提示信息tips,以及需要更新的apk地址url,点击确认更新后会采用后台文件下载(更新的URL地址),下载完成后弹出安装页面,进行强更APK。


  1. 系统自带布局
updateUtil.setOnUpdateStatusChangeListener(null)
.showDownloadNotification("正在更新", "正在下载更新包...")
.showDownloadProgressDialog("正在下载", "后台下载", "取消")
.start(editDownloadUrl.getText().toString(), "发现更新",
    "全新3.8版本 「清夏!乐园?大秘境!」现已推出!\n" + "\n"
    + "【限时区域】琉形蜃境\n" + "一切都是在小小的琉璃瓶子中发生的故事。传言在沙漠的中心有一处神奇的秘境,进入秘境的人就能实现他们的愿望。\n"
    + "而事实真相又是如何呢,无人知悉,在那小小的瓶中世界之中,又装着多少旅人犹如蜃影般的热望?\n"
    + "\n" + "【新活动】版本主题活动 「清夏!乐园?大秘境!」、阶段性活动「传心同视」、「险途勘探」、「冒险家试炼·进阶篇」\n"
    + "炽烈的夏日阳光渐渐笼罩大地,在派蒙的建议下,你们回到了西风骑士团的总部,意外得知了某件奇妙之事,一场特别的冒险即将拉开帷幕…\n"
    + "完成主题活动任务,可邀请四星角色「绮思晚星 · 莱依拉(冰)」。\n" + "\n" + "【新剧情】邀约任务更新\n"
    + "邀约事件 · 凯亚 第一幕 「鬼话与甜酒」\n" + "\n" + "【新衣装】可莉衣装「琪花星烛」、凯亚衣装「帆影游风」\n"
    + "全新角色衣装「琪花星烛」是可莉出演关键剧目时所穿的精致服装,色彩明丽,如同点缀着奶油花朵和明红蜡烛的蛋糕,能将快乐与笑容带往冒险所至的每个角落。\n"
    + "「帆影游风」是凯亚在舞台上饰演「短刀大盗」时的装扮,以「吸睛」为设计原则的华丽服装。不过衣服穿起来并不麻烦,最花时间打理的是饰品与短刀。\n"
    + "\n" + "【七圣召唤更新】全新角色牌、全新行动牌\n" + "全新角色牌、行动牌开放获取。",
    "开始", "取消", "", 2, "com.xiaomi.market", "点击安装", false);

默认过程中,会先显示一个系统对话框提示用户有新的版本,用户可以选择开始下载、取消下载和去商店更新,其中去商店更新。文本传值为 null 时不显示此按钮。你可以设置是否强制更新,若强制更新,用户默认无法通过后退按钮关闭更新对话框,且你可以在状态回调接口 OnUpdateStatusChangeListener 的 onDownloadCancel 事件中做用户点击 “取消” 按钮时的相应处理。此版本代码中的注释非常详尽,建议阅读 UpdateUtil 类中各方法的注释信息,了解更多细节。


一些接入配置

  1. 本工具提供下载、安装步骤,因网络请求框架不确定,本工具不包含从您服务器的检查 APP 版本过程的网络请求。
  2. 添加权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
  1. 对于非 https 的地址,建议在 AndroidManifest.xml 中的 标签添加以下属性:
...
<application
    android:networkSecurityConfig="@xml/network_security_config"
    ...
    >
    ...
    
</application>

然后在项目 res 下新建 xml 目录,添加文件 network_security_config.xml,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>
  1. 在 AndroidManifest.xml 中 标签作用域内添加以下属性,注意将文中“{你的 APP 包名}”替换为你的 APP 真实包名。
<provider
    android:name="com.momo.sdk.update.custom.UpdateFileProvider"
    android:authorities="{你的 APP 包名}.fileProvider"
    android:grantUriPermissions="true"
    android:exported="false">
    <!--元数据-->
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_path"/>
</provider>

然后在 res 的 xml 目录中新建 file_path.xml,并添加如下代码:

<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <paths>
        <external-path path="" name="download"/>
    </paths>
</resources>

参考资料以及Demo示例