app 以前的版本更新使用的自己写的代码从服务器下载,结果出现了下载完成以后,提示解析包错误的问题,但是呢,找到该 apk 点击安装是可以安装成功的,估计就是最后几秒安装包没有下载完成然后点击了安装出现的解析包错误的问题。目前修改为通过 DownloadManager 进行下载。

代码如下:

1. 判断当前是否可以使用 DownloadManager (根据搜索结果,反馈说有些国产手机会把 DownloadManager 进行阉割掉,目前测试在 Nexus6, 华为Mate9, 小米 Note,华为Mate8, HTC D820U, 三星 S7 上可以使用)

     private static boolean canDownloadState(Context ctx) {
try {
int state = ctx.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads"); if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}

2. 出现可以使用和不可以使用的情况。可以使用的话,就使用 DownloadManager 进行下载,不可以使用就交给浏览器进行下载

                 if (canDownloadState(ctx)) {
MLog.d("UpdateVersion", "DownloadManager 可用");
Intent downloadApkIntent = new Intent(ctx, DownApkServer.class);
Bundle bundle = new Bundle();
bundle.putString("downloadUrl", url);
bundle.putString("title", subAppName);
downloadApkIntent.putExtra("download", bundle);
ctx.startService(downloadApkIntent);
} else {
MLog.d("UpdateVersion", "DownloadManager 不可用");
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse(url);
intent.setData(content_url);
ctx.startActivity(intent);
}

3. 启动 DownApkServer 服务

 public class DownApkServer extends Service {
static final String TAG = "DownApkServer";
Context context = this;
SharedPreferences mSp; public DownApkServer() { } @Override
public IBinder onBind(Intent intent) {
return null;
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle downloadBundle = intent.getBundleExtra("download");
if (downloadBundle != null) {
String downloadUrl = downloadBundle.getString("downloadUrl");
String title = downloadBundle.getString("title");
if (!TextUtils.isEmpty(downloadUrl)) {
mSp = context.getSharedPreferences("downloadApk", MODE_PRIVATE);
long downloadId = downloadApk(downloadUrl, title);
mSp.edit().putLong("downloadId", downloadId).commit();
}
}
stopSelf();
return super.onStartCommand(intent, flags, startId);
} private long downloadApk(String url, String title) {
Uri downloadUri = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(downloadUri);
String apkName = title + ".apk";
File file = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS + "/" + apkName);
if (file != null && file.exists()) {
file.delete();
}
request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS,
apkName);
mSp.edit().putString("apkName", apkName).commit();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setVisibleInDownloadsUi(true);
request.setTitle(title);
DownloadManager mDownloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
return mDownloadManager.enqueue(request);
}
}

4. 注册一个广播,DownApkReceiver

 public class DownApkReceiver extends BroadcastReceiver {
private static final String TAG = "DownApkReceiver";
SharedPreferences mSharedP;
DownloadManager mManager;
Context ctx; @Override
public void onReceive(Context context, Intent intent) {
ctx = context;
if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
long downloadApkId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1L);
mSharedP = context.getSharedPreferences("downloadApk", MODE_PRIVATE);
long saveApkId = mSharedP.getLong("downloadId", -1L);
if (downloadApkId == saveApkId) {
checkDownloadStatus(context, downloadApkId);
}
}
} private void checkDownloadStatus(Context context, long downloadId) {
mManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
Cursor cursor = mManager.query(query);
if (cursor.moveToFirst()) {
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (status) {
case DownloadManager.STATUS_SUCCESSFUL:
installApk(context);
break;
case DownloadManager.STATUS_FAILED:
MLog.d("DownApkReceiver", "下载失败.....");
break;
case DownloadManager.STATUS_RUNNING:
MLog.d("DownApkReceiver", "正在下载.....");
break;
default:
break;
}
}
} private void installApk(Context context) {
String apkName = mSharedP.getString("apkName", null);
if (apkName != null) {
MLog.d("DownApkReceiver", "apkName 为" + apkName);
File file = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS + "/" + apkName);
if (file != null) {
Intent install = new Intent("android.intent.action.VIEW");
Uri downloadFileUri = Uri.fromFile(file);
install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(install);
} else {
MLog.d("DownApkReceiver", "下载失败");
}
} else {
MLog.d("DownApkReceiver", "apkName 为 null");
}
}
}

5. 在清单文件中,注册该广播

         <receiver android:name=".subapps.api.utils.DownApkReceiver">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"></action>
</intent-filter>
</receiver>

Android:使用 DownloadManager 进行版本更新的更多相关文章

  1. Android 使用DownloadManager进行版本更新的完整方案

    在Android App都会有版本更新的功能,以前我们公司是用友盟SDK更新功能,自己服务器没有这样的功能.版本检测.Apk下载都是使用友盟.最近看到友盟的版本更新SDK文档:十月份更新功能将会停止服 ...

  2. Android:使用 DownloadManager 进行版本更新,出现 No Activity found to handle Intent 及解决办法

    项目中,进行版本更新的时候,用的是自己写的下载方案,最近看到了使用系统服务 DownloadManager 进行版本更新,自己也试试. 在下载完成以后,安装更新的时候,出现了一个 crash,抓取的 ...

  3. android SDK与ADT版本更新问题

    android SDK与ADT版本更新问题 问题:This Android SDK requires Android Developer Toolkit version 14.0.0 or above ...

  4. Android 演示 DownloadManager——Android 下载 apk 包并安装

    本文内容 环境 项目结构 演示下载 参考资料 本文是 github 上 Trinea-Android-common 和 Trinea-Android-Demo 项目的一部分,将下载部分分离出来,看看如 ...

  5. Android 使用 DownloadManager 管理系统下载任务的方法,android管理系统

    从Android 2.3(API level 9)开始Android用系统服务(Service)的方式提供了Download Manager来优化处理长时间的下载操作.Download Manager ...

  6. [置顶] Android应用开发之版本更新你莫愁

    传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 今天我们学习如何实现Android应用的自动更新版本功能,这是在各种语言编写的应用中都 ...

  7. Android 全局弹出版本更新 Dialog 思考和解决办法

    Android 针对版本更新,需要做全局的弹出(需求:版本更新只需要在 App 内全局弹出就可以),思路是使用 AlertDialog ,然后设置 setType 为 TYPE_ALERT_WINDO ...

  8. Android 使用 DownloadManager 管理系统下载任务的方法

    在红黑联盟上看到的.这几天一直考虑做一个Notification 的带下载功能的自己定义通知.但没搞出来.无意中在论坛看到这个.先Mark,明天试试. 从Android 2.3(API level 9 ...

  9. Android中实现app版本更新

    1,获取本地程序apk版本,并开启服务(下面这段代码一般在主Activity中的onCreate()方法中执行的,并开启后台服务下载新版本的apk) //获取apk包文件的管理者对象 PackageM ...

随机推荐

  1. CentOS静默安装Oracle 11gR2(x64)

    环境 OS: CentOS 7.4; hosts: L134; IP: 192.168.1.134 DB: linux.x64_11gR2_database 安装依赖包 yum install -y ...

  2. Java Singleton的3种实现方式

    1.通过静态成员字段来实例化 public class Elvis { /** * 通过final的静态成员字段来调用私有的构造函数实例化对象 */ public static final Elvis ...

  3. excel 妙用选择性粘贴

    需要注意的是转置功能,是经常会用到的功能.

  4. codevs 1576 最长严格上升子序列

    题目链接:http://codevs.cn/problem/1576/ 题目描述 Description 给一个数组a1, a2 ... an,找到最长的上升降子序列ab1<ab2< .. ...

  5. redis配置笔记

    #cd /opt#tar -zxvf redis-4.0.6.tar.gz#cd redis-4.0.6#make #cd src#make install PREFIX=/usr/local/red ...

  6. 转:Ogre源码剖析 - 场景管理之Octree

    由于本人的引擎ProjectGaia服务于08年创新杯的游戏项目 – 3D太空游戏,所以理所应当加入Octree(八叉树 – 已经周宁学长发帖介绍过)场景管理器.参考了无数Octree的代码,发现还是 ...

  7. UVM:8.4.3 用factory 机制创建实例的接口

    1.create_object_by_name,依据类名字创建object,原型: 一般仅仅用第一个: 2.create_object_by_type.依据类型创建一个object,原型: 一般仅仅用 ...

  8. Ubuntu 13.04有线连接异常

    最近安装了Ubuntu 13.04 64位版,发现有线连接经常会掉线,通常在连接上一段时间(或长或短)就无法上网,ping不通,但是ifconfig显示一切正常,重启NetworkManager也不行 ...

  9. ajax, jQuery, jQueryeasyUI

    1.ajax与jQueryajax是jquery库里面的一个被封装好的函数,可以拿来直接使用.没有jquery的话,ajax的使用就得用原生的javascript去写,比较麻烦. 2.jQuery E ...

  10. k8s实战读书笔记

    一.概述 kubernetes中Service是真实应用的抽象,将用来代理Pod,对外提供固定IP作为访问入口,这样通过访问Service便能访问到相应的Pod,而对访问者来说只需知道Service的 ...