android系统怎么才能让qq升级快他升级

87被浏览34,075分享邀请回答16044 条评论分享收藏感谢收起82 条评论分享收藏感谢收起Android检查版本升级应该怎么做? - 简书
Android检查版本升级应该怎么做?
加菲猫.jpeg
demo演示:
今年年初项目终于上线,到目前为止发布了4个版本。经历了3.8节,整体表现稳定。在第三个版本我们加入了版本检查升级,发布第四版本,用户就直接体验到了这个功能。
我们开发一个APP,应该是发布第一个版本之后,后续不断的更新迭代。现在大部分APP都是发布到各大应用市场市场,然后用户去搜索我们的应用并下载安装。如果有新的版本,你不可能让每个用户去应用市场重新下载新的版本,又或者用户没注意应用市场的更新提醒导致没有安装最新版本等,所以我们有必要让我们的应用自己检查是否有新的版本。
升级流程图
在APP首页自动触发向服务端请求最新的版本信息,如果服务端返回的版本信息中versionCode与当前版本不一致,就弹出升级提示框让用户选择。流程图如下:
检查更新流程图.png
“立即更新”:直接启动下载
“稍后提醒”:什么都不处理
“忽略该版本”:当前版本不再提醒,如有更新版本还是要提醒。例如:用户版本是1.0,当前检查到的版本是2.0,用户选择了“忽略该版本”,则2.0的版本不再提示,到下个版本时,仍然要提示版本更新。
首先看下app module的build.gradle
每次发布一个新版本时,一般都会修改versionCode以及versionName。
defaultConfig {
applicationId "com.jemlin.app"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0.0"
其中versionCode是整型,这里定义从1开始,每次迭代一个版本就加1;versionName是字符类型,从1.0.0开始,每次更新可以改为1.0.1、1.1.0、2.0.0等等。
接着判断是否有升级版本
通过和后端定好的http api从服务器端请求最新版本的versionCode,然后与当前版本的versionCode比较,如果服务端返回版本信息的versionCode大于当前版本的versionCode,就说明有新的版本需要更新。
1、http api检查版本更新接口response数据格式(仅供参考):
"downloadUrl": "http://a5.pc6.com/cx3/weixin.pc6.apk",
"version": "1.0.1",
"versionCode": 2,
"versionDesc": "主要修改:\n1.增加多项新功能;\n2.修复已知bug。"
"errCode": 0,
"errMsg": "",
"success": true
其中,downloadUrl是最新版本的下载地址。
2、定义VersionInfo模型,用于GSon解析服务端返回的数据:
public class VersionInfo {
private int versionC
private String downloadU
private String versionD
3、如果有升级版本,随时弹窗提示用户。没有升级版本,就不用提示。
我的做法是把用户忽略更新的版本号versionCode存储到sharePreference中,每次发现有升级版本时,在给用户提示之前,先取忽略版本号versionCode与最新版本号versionCode比较是否一样,如果一样就什么都不做,检查更新结束;如果不一样,还是照样给用户提示。
//取sp中保存的versionCode
int versionCode = mAppUpgradePersistent.getIgnoreUpgradeVersionCode(appContext);
if (versionCode == latestVersion.getVersionCode()) {
//用户之前已经选择"忽略该版本",不更新这个版本。
Timber.d("[AppUpgradeManager] ignore upgrade version====");
最简单,什么都不做。
1、项目中我们直接使用系统提供的服务,同时注册两个广播:
下载完成广播DownloadManager.ACTION_DOWNLOAD_COMPLETE以及
点击下载通知栏广播DownloadManager.ACTION_NOTIFICATION_CLICKED
代码片段如下:
public void init(Context context) {
Timber.d("[AppUpgradeManager] init====");
if (isInit) {
appContext = context.getApplicationContext();
mAppUpgradePersistent = new AppUpgradePersistent();
appContext.registerReceiver(downloaderReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
appContext.registerReceiver(notificationClickReceiver, new IntentFilter(DownloadManager.ACTION_NOTIFICATION_CLICKED));
public void unInit() {
Timber.d("[AppUpgradeManager] unInit====");
if (!isInit) {
appContext.unregisterReceiver(downloaderReceiver);
appContext.unregisterReceiver(notificationClickReceiver);
mAppUpgradePersistent =
appContext =
2、如果可以的话,在用户选择立即更新之后,您的应用应该判断当前的网络环境,如果是非wifi环境应该弹窗提示用户类似“您当前使用的不是wifi,更新会产生一些网络流量,是否继续下载?”
代码片段如下:
// 非wifi网络下,再次提示用户是否继续
MaterialDialog.Builder builder = new MaterialDialog.Builder(activity);
final MaterialDialog dialog = builder.title("流量提醒")
.theme(Theme.LIGHT)
.titleGravity(GravityEnum.CENTER)
.content("您当前使用的不是wifi,更新会产生一些网络流量,是否继续下载?")
.positiveText("确定")
.negativeText("取消")
.onPositive(new MaterialDialog.SingleButtonCallback() {
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.dismiss();
.onNegative(new MaterialDialog.SingleButtonCallback() {
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
dialog.dismiss();
dialog.show();
3、真正调用DownloadManager下载前,我们可以判断下本地是否已经过了最新版本,有就直接启动安装界面安装;下载的不是最新版本,就直接删除。
代码片段如下:
//先检查本地是否已经有需要升级版本的安装包,如有就不需要再下载
File targetApkFile = new File(downloadApkPath);
if (targetApkFile.exists()) {
PackageManager pm = appContext.getPackageManager();
PackageInfo info = pm.getPackageArchiveInfo(downloadApkPath, PackageManager.GET_ACTIVITIES);
if (info != null) {
String versionCode = String.valueOf(info.versionCode);
//比较已下载到本地的apk安装包,与服务器上apk安装包的版本号是否一致
if (String.valueOf(latestVersion.getVersionCode()).equals(versionCode)) {
//弹出框提示用户安装
mHandler.obtainMessage(WHAT_ID_INSTALL_APK, downloadApkPath).sendToTarget();
//要检查本地是否有安装包,有则删除重新下
File apkFile = new File(downloadApkPath);
if (apkFile.exists()) {
boolean isDelSuc = apkFile.delete();
4、创建下载Reuqst,开始下载。
代码片段如下:
Request task = new Request(Uri.parse(latestVersion.getDownloadUrl()));
//定制Notification的样式
String title = "应用名称:" + latestVersion.getVersion();
task.setTitle(title);
task.setDescription(latestVersion.getVersionDesc());
//如果我们希望下载的文件可以被系统的Downloads应用扫描到并管理,我们需要调用Request对象的setVisibleInDownloadsUi方法,传递参数true
task.setVisibleInDownloadsUi(true);
//设置是否允许手机在漫游状态下下载
task.setAllowedOverRoaming(false);
//限定在WiFi下进行下载
task.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
task.setMimeType("application/vnd.android.package-archive");
// 在通知栏通知下载中和下载完成
// 下载完成后该Notification才会被显示
if (Build.VERSION.SDK_INT & Build.VERSION_CODES.HONEYCOMB) {
// 3.0(11)以后才有该方法
//在下载过程中通知栏会一直显示该下载的Notification,在下载完成后该Notification会继续显示,直到用户点击该Notification或者消除该Notification
task.allowScanningByMediaScanner();
task.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
// 可能无法创建Download文件夹,如无sdcard情况,系统会默认将路径设置为/data/data/com.android.providers.downloads/cache/xxx.apk
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String apkName = UpgradeHelper.downloadTempName(appContext.getPackageName());
task.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkName);
downloadTaskId = downloader.enqueue(task);
mAppUpgradePersistent.saveDownloadTaskId(appContext, downloadTaskId);
下载完成广播
在public void init(Context context)方法中已经注册了监听下载完成广播,一旦我们知道下载完成的时机,就可以调用系统安装界面安装我们的APK啦~
切记,不可在广播的onReceive中做耗时操作,时间不能超过10秒,否则将ANR卡死!
下载完成广播定义如下:
* 下载完成的广播
class DownloadReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (downloader == null) {
long completeId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
long downloadTaskId = mAppUpgradePersistent.getDownloadTaskId(context);
if (completeId != downloadTaskId) {
Query query = new Query();
query.setFilterById(downloadTaskId);
Cursor cur = downloader.query(query);
if (!cur.moveToFirst()) {
int columnIndex = cur.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == cur.getInt(columnIndex)) {
String uriString = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
mHandler.obtainMessage(WHAT_ID_INSTALL_APK, uriString).sendToTarget();
ToastHelper.showToast("xxxApp最新版本失败!");
// 下载任务已经完成,清除
mAppUpgradePersistent.removeDownloadTaskId(context);
cur.close();
点击通知栏响应广播
如果还未下载完成,点击后进入系统默认的下载界面;下载完成后再点击,就直接调用系统安装界面安装。
* 点击通知栏下载项目,下载完成前点击都会进来,下载完成后点击不会进来。
public class NotificationClickReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
long[] completeIds = intent.getLongArrayExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS);
//正在下载的任务ID
long downloadTaskId = mAppUpgradePersistent.getDownloadTaskId(context);
if (completeIds == null || completeIds.length &= 0) {
openDownloadsPage(appContext);
for (long completeId : completeIds) {
if (completeId == downloadTaskId) {
openDownloadsPage(appContext);
* Open the Activity which shows a list of all downloads.
* @param context 上下文
private void openDownloadsPage(Context context) {
Intent pageView = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
pageView.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(pageView);
大家会发现,在这个广播中我们并没有看到直接处理下载完成点击通知栏的代码。这个功能我一开始也是无法实现,下载完成后点击一直都是进入系统默认的下载页面。后面google查阅了一些资料,发现系统会调用View action根据mimeType去查询。所以我们要在一开始创建DownloadManager.Request时候调用Requset.setMimeType方法来设置文件类型。
request.setMimeType("application/vnd.android.package-archive");
ok,看到这边,想必让你来实现检查版本升级已然心中有数。
那接下来我把遇到的坑,以及是如何埋坑的一一列出来,一定要努力接着往下看哦。。。
需求:进入首页后,开启自动检测升级,检测到有升级的版本就随时弹框提示用户,但此时用户可能已经在操作APP进入其他页面,怎么保证弹框可以正常弹出?(APP不会出现异常或者崩溃)
升级提示弹框设置为:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
同时在AndroidAmanifest.xml加入权限:
&uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /&
我在华为P9上(7.0)上验证测试没有问题,找了谷歌Nexus 5(4.4)验证也没有问题,以为大功告成!
后面我谷歌上找了下,竟然有很多文章爆出小米会有问题而且解决方案也是麻烦不是很靠谱,鬼知道是不是还有其他品牌机型会有适配问题,没办法android厂商太多了&系统各种定制!
靠谱的解决方案
项目中为了解决这个适配问题,达到一劳永逸的目的,我们设计了一个背景透明的UpgradeActivity,当需要弹出升级提示框时,就启动这个UpgradeActivity然后再显示这个弹框。
public class UpgradeActivity extends BaseActivity {
boolean isShowDialog =
public static void startInstance(Context context) {
Intent intent = new Intent(context, UpgradeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upgrade);
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && !isShowDialog) {
isShowDialog =
//升级提示框
AppUpgradeManager.getInstance().foundLatestVersion(this);
有个需要注意的地方就是弹出框关闭的时候要记得同时销毁UpgradeActivity!!这里没有给出代码,相信你有办法自己解决(广播啊、接口listener啊、EventBus啊等等只要能及时正常关闭都可以)
我把下载的apk文件存放在sd卡下 Download目录里面,绝对路径变量命名为uriDownload,启动安装界面安装,代码如下:
Intent installIntent = new Intent();
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
installIntent.setAction(Intent.ACTION_VIEW);
Uri apkFileUri = Uri.fromFile(apkFile);
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
installIntent.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
appContext.startActivity(installIntent);
} catch (ActivityNotFoundException e) {
Timber.d("installAPKFile exception:%s", e.toString());
一切完成后开始在真机上测试,7.0以下的真机测试都没有问题。我也以为任务完成可以交差了,刚好手头有一部华为P9已经升级到7.0,安装后测试下载完成升级版本然后调用系统安装界面安装直接崩溃了,查看log有这么一句:
android.os.FileUriExposedException: file:///storage/emulated/0/xxx exposed beyond app through Intent.getData()
认真一看,异常FileUriExposedException之前从来没碰到过。赶紧google发现原来是Android N之后,
Android 框架执行的 ,API 禁止向您的应用外公开 file://URI。如果一项包含文件 URI 的 Intent 离开您的应用,应用失败并出现 FileUriExposedException异常。
若要在应用间共享文件,您应发送一项 ,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 类。 如需有关权限和共享文件的更多信息,请参阅。也就是说,对于应用间共享文件这块,中做了强制性要求。
既然我们知道了是什么问题,那就开始解决问题吧。
1、首先在你的manifest里面增加&provider&元素
&manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jemlin.app"&
&application
android:name="android.support.v4.content.FileProvider"
android:authorities="com.jemlin.app.provider"
android:exported="false"
android:grantUriPermissions="true"&
&meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" /&
&/provider&
&/application&
&/manifest&
2、res下创建xml目录,在xml下创建provider_paths.xml资源文件
&?xml version="1.0" encoding="utf-8"?&
&!--path:需要临时授权访问的路径(.代表所有路径) name:就是你给这个访问路径起个名字--&
&external-path
name="external_files"
path="." /&
3、修改我们刚才调用安装界面的代码,最终如下:
Intent installIntent = new Intent();
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
installIntent.setAction(Intent.ACTION_VIEW);
Uri apkFileU
// 在24及其以上版本,解决崩溃异常:
// android.os.FileUriExposedException: file:///storage/emulated/0/xxx exposed beyond app through Intent.getData()
if (Build.VERSION.SDK_INT &= Build.VERSION_CODES.N) {
apkFileUri = FileProvider.getUriForFile(appContext, BuildConfig.APPLICATION_ID + ".provider", apkFile);
apkFileUri = Uri.fromFile(apkFile);
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
installIntent.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
appContext.startActivity(installIntent);
} catch (ActivityNotFoundException e) {
Timber.d("installAPKFile exception:%s", e.toString());
抹一把汗水 囧!Android检查版本升级就介绍这些。如您有问题请留言;如您觉得好,就给个赞吧~~
做过C/C++/Android,现在从事Android APP开发工作。。
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金相信有很多朋友...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金 相信有很多...
Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线)。分布式系统的协调导致了样板模式, 使用Spring Cloud开发人员可以快速地支持实现这些模式的服务和应用程序。他们将在任何分布式...
公司开发时候,应该最常用的就是APP升级功能,倒不是说的是热修复等技术,而是普通的检测到服务器版本比本地手机版本高的时候,手机会询问用户是否要下载最新的app,然后下载apk下来,然后进行安装,我以前用的都是别人封装好的。也没仔细看过,这次又正好有这个需求,就老老实实自己写...
github地址 https://github.com/zhouxu88/APPUpgrade.git 一、简介: 在APP开发中,应用上线后公司肯定后期会对应用进行维护对一些Bug修复,这种情况就需要版本迭代了。检测到服务器版本比本地手机版本高的时候,手机会询问用户是否要...
今天要去拍毕业照 起的早 吃的也简单 要搬砖,搬到机票钱才能旅游
七秒钟之后依然是38.6℃原来涸辙之鱼终在不同的江湖ps:姚贝娜—鱼
《白天里的黑夜》
文/白传英 一想到你 我就会笑 仿佛生活就是那么奇妙 你是否能感觉到 你在我心里 还像过去那样骄傲 每次想到你 我都会很自豪 轰轰烈烈的爱情我不想要 我只是想和你变老 给我的爱像别人一样多 我就已经阿弥陀佛 你是我生命里得白天 有你我不会孤单 可...
又一个女大学生因为传销死亡
政府社会有关部门 一定要加大对传销组织的打击力度
彻底消灭它
为了你我他的安全
请多个心眼' 保护好自己
一 作者:杨斐 文章:复活 点评:王雪梅 脑洞大开的一篇文章。 金句: 链接: http://www.jianshu.com/p/ce?utm_campaign=haruki&utm_content=note&utm_medium=reader_shar...帖子很冷清,卤煮很失落!求安慰
手机签到经验翻倍!快来扫一扫!
突然让升级 Android System Webview ,可以升吗?
35浏览 / 11回复
忽然让升级 Android System Webview ,不知是什么东西,不敢冒然升级,有知道的介绍一下,是不是可以升级,谢谢!
就是安卓系统内置的浏览器,实质就是使用webkit内核的chromium(Chrome来自的开源项目)浏览器。如果你的浏览器调用系统浏览器内核的,建议升级。
注,微信内部是用QQ X5浏览器内核的,升级这个不会让微信浏览网页或者公众号,小程序等体验变好
我的没什么问题
楼主,Webview是chrome浏览器的内核,所有安卓手机必须预装的重要系统组件,用于显示网页,手机的APP可以调用它显示网页而不需要浏览器,升级以提升系统整体集成应用的网页性能。建议升级呢~~
志理名言 发表于
就是安卓系统内置的浏览器,实质就是使用webkit内核的chromium(Chrome来自的开源项目)浏览器。如果你的浏览 ...
请问不升级会不会有影响手机操作和使用?
就是安卓系统内置的浏览器,实质就是使用webkit内核的chromium(Chrome来自的开源项目)浏览器。如果你的浏览 ...!
朐忍趣叟 发表于
10:40请问不升级会不会有影响手机操作和使用?
除了占储存空间外没有什么问题的啊
楼主你知道的太多了
大王叫我来巡山
看看效果怎样
可能感兴趣的板块:
用户名/注册邮箱/注册手机号
其他第三方号登录内容字号:
段落设置:
字体设置:
精准搜索请尝试:
谷歌Project Treble让Android告别升级慢,还让刷机更好玩
来源:作者:刘罕责编:守一
话题和问题不断的Google Pixel 2手机,Google的新硬件似乎赚足了人们的眼球。而除了让“亲儿子”党渴求的新机,擅长做软件的Google也从这一代Android系统开始,带来了可以说是有史以来最大和最实际的改变。这个改变就是Android系统新的升级机制Project Treble。几乎所有的Android手机用户这么多年一直都有一个不知道该求谁的诉求,那就是希望自己手中的Android机系统升级的速度能快点。原生Android用户还好,我见过不少拿着Nexus和Pixel的用户在国内外各种坛子炫耀每次系统更新和安全更新之神速,殊不知OEM厂商的手机用户却在各自的坛子里询问两个月前的更新为啥还没有。而在最新的Android版本系统的统计中,Android 8.0只有0.3%,2015年的系统Android 6.0还有30%的占有率,而更早的Android 5.0还有27%。但这种情况,这一次或许真的可以有效的改善了。Google新的系统更新机制Project Treble随着Android 8.0一起到来。简单来讲,Android 8.0中的Project Treble将所有的低级驱动程序,也就是OEM厂商定制的部分,与原生Android系统的其余部分分离开来。同时,这意味着在更新Android设备之前,不再需要等待更新芯片组的驱动程序,只要驱动程序支持Treble就可以。换言之,就是未来的Android系统无需等待把原生ROM改的体无完肤的OEM厂商从芯片到软件层面的适配,等待新系统到来的时间会大幅缩短。下图就是Project Treble机制的简易示意图。在XDA论坛上,已经有大神开始挖掘Project Treble的妙用了。这位大神以华为Mate 9试水,Mate 9出厂系统是Android 7.0,在上个月华为已经释出了Android 8.0 beta版。而Mate 9上的Android 8.0支持Project Treble,XDA的开发者&Phhusson只用了不到一天的时间就为Mate 9刷上了AOSP ROM,也就是原生Android系统,而且并未修改内核,在此之前也没有过适配Mate 9原生ROM。Phhusson还发现,他在修改了一个AOSP ROM后,这个ROM可以刷在当前支持Treble的任何一个设备上。包括Essential Phone,Huawei Mate 9,Honor 8 Pro,Xperia XZ1,和Xperia XZ1 Compact都可以安装并启动同一个系统。当然,不同设备使用同一个ROM会存在各种Bug,但在Project Treble前,还没有出现过同一个ROM不经过特定的修改而支持不同设备的情况。目前来看,未来Project Treble不只能帮助OEM厂商更快的为自家手机提供最新的系统更新,还可以开发者更加便利的定制和修改自己的系统,而无须等待厂商适配,但前提是,这些手机要支持Project Treble才可以。此外,令人稍感疑惑的是,一直最贴近原生Android的一加近期表示,旗下的几款手机不会支持Project Treble,即便他们已经升级到了Android 8.0。Android 8.0已经提供了很好的更新机制,如果未来OEM厂商们勤奋些,或许那些论坛里的抱怨声能少一些,Android更新慢和碎片化的老问题也可以不被一遍又一遍的提及了。
软媒旗下软件:
IT之家,软媒旗下科技门户网站 - 爱科技,爱这里。
Copyright (C) , All Rights Reserved.他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 怎样才能让眼睛变大 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信