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

代码如下:

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

  1. private static boolean canDownloadState(Context ctx) {
  2. try {
  3. int state = ctx.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads");
  4.  
  5. if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
  6. || state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
  7. || state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
  8. return false;
  9. }
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. return false;
  13. }
  14. return true;
  15. }

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

  1. if (canDownloadState(ctx)) {
  2. MLog.d("UpdateVersion", "DownloadManager 可用");
  3. Intent downloadApkIntent = new Intent(ctx, DownApkServer.class);
  4. Bundle bundle = new Bundle();
  5. bundle.putString("downloadUrl", url);
  6. bundle.putString("title", subAppName);
  7. downloadApkIntent.putExtra("download", bundle);
  8. ctx.startService(downloadApkIntent);
  9. } else {
  10. MLog.d("UpdateVersion", "DownloadManager 不可用");
  11. Intent intent = new Intent();
  12. intent.setAction("android.intent.action.VIEW");
  13. Uri content_url = Uri.parse(url);
  14. intent.setData(content_url);
  15. ctx.startActivity(intent);
  16. }

3. 启动 DownApkServer 服务

  1. public class DownApkServer extends Service {
  2. static final String TAG = "DownApkServer";
  3. Context context = this;
  4. SharedPreferences mSp;
  5.  
  6. public DownApkServer() {
  7.  
  8. }
  9.  
  10. @Override
  11. public IBinder onBind(Intent intent) {
  12. return null;
  13. }
  14.  
  15. @Override
  16. public int onStartCommand(Intent intent, int flags, int startId) {
  17. Bundle downloadBundle = intent.getBundleExtra("download");
  18. if (downloadBundle != null) {
  19. String downloadUrl = downloadBundle.getString("downloadUrl");
  20. String title = downloadBundle.getString("title");
  21. if (!TextUtils.isEmpty(downloadUrl)) {
  22. mSp = context.getSharedPreferences("downloadApk", MODE_PRIVATE);
  23. long downloadId = downloadApk(downloadUrl, title);
  24. mSp.edit().putLong("downloadId", downloadId).commit();
  25. }
  26. }
  27. stopSelf();
  28. return super.onStartCommand(intent, flags, startId);
  29. }
  30.  
  31. private long downloadApk(String url, String title) {
  32. Uri downloadUri = Uri.parse(url);
  33. DownloadManager.Request request = new DownloadManager.Request(downloadUri);
  34. String apkName = title + ".apk";
  35. File file = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS + "/" + apkName);
  36. if (file != null && file.exists()) {
  37. file.delete();
  38. }
  39. request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS,
  40. apkName);
  41. mSp.edit().putString("apkName", apkName).commit();
  42. request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
  43. request.setVisibleInDownloadsUi(true);
  44. request.setTitle(title);
  45. DownloadManager mDownloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
  46. return mDownloadManager.enqueue(request);
  47. }
  48. }

4. 注册一个广播,DownApkReceiver

  1. public class DownApkReceiver extends BroadcastReceiver {
  2. private static final String TAG = "DownApkReceiver";
  3. SharedPreferences mSharedP;
  4. DownloadManager mManager;
  5. Context ctx;
  6.  
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. ctx = context;
  10. if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
  11. long downloadApkId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1L);
  12. mSharedP = context.getSharedPreferences("downloadApk", MODE_PRIVATE);
  13. long saveApkId = mSharedP.getLong("downloadId", -1L);
  14. if (downloadApkId == saveApkId) {
  15. checkDownloadStatus(context, downloadApkId);
  16. }
  17. }
  18. }
  19.  
  20. private void checkDownloadStatus(Context context, long downloadId) {
  21. mManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
  22. DownloadManager.Query query = new DownloadManager.Query();
  23. query.setFilterById(downloadId);
  24. Cursor cursor = mManager.query(query);
  25. if (cursor.moveToFirst()) {
  26. int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
  27. switch (status) {
  28. case DownloadManager.STATUS_SUCCESSFUL:
  29. installApk(context);
  30. break;
  31. case DownloadManager.STATUS_FAILED:
  32. MLog.d("DownApkReceiver", "下载失败.....");
  33. break;
  34. case DownloadManager.STATUS_RUNNING:
  35. MLog.d("DownApkReceiver", "正在下载.....");
  36. break;
  37. default:
  38. break;
  39. }
  40. }
  41. }
  42.  
  43. private void installApk(Context context) {
  44. String apkName = mSharedP.getString("apkName", null);
  45. if (apkName != null) {
  46. MLog.d("DownApkReceiver", "apkName 为" + apkName);
  47. File file = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS + "/" + apkName);
  48. if (file != null) {
  49. Intent install = new Intent("android.intent.action.VIEW");
  50. Uri downloadFileUri = Uri.fromFile(file);
  51. install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");
  52. install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  53. context.startActivity(install);
  54. } else {
  55. MLog.d("DownApkReceiver", "下载失败");
  56. }
  57. } else {
  58. MLog.d("DownApkReceiver", "apkName 为 null");
  59. }
  60. }
  61. }

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

  1. <receiver android:name=".subapps.api.utils.DownApkReceiver">
  2. <intent-filter>
  3. <action android:name="android.intent.action.DOWNLOAD_COMPLETE"></action>
  4. </intent-filter>
  5. </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系统yum源配置修改、yum安装软件包源码包出错解决办法!

    yum安装包时报错: Could not retrieve mirrorlist http://mirrorlist.repoforge.org/el6/mirrors-rpmforge error ...

  2. Java远程方法协议(JRMP)

    Java远程方法协议(英语:Java Remote Method Protocol,JRMP)是特定于Java技术的.用于查找和引用远程对象的协议.这是运行在Java远程方法调用(RMI)之下.TCP ...

  3. CPU profiling

    http://gernotklingler.com/blog/gprof-valgrind-gperftools-evaluation-tools-application-level-cpu-prof ...

  4. Ajax学习(二):模仿jQuery的Ajax封装工具

    通过上一节的学习,基本了解Ajax的使用, 但是这样使用很麻烦,这里封装ajax为一个方法,作为一个ajax工具,传入相应参数就可以实现ajax的使用. 模仿jQuery的Ajax. 如下是jQuer ...

  5. memcache使用方法测试

    <?php //php操作memcache的使用测试总结--学习 //1 Memcache::connect; //$memcache = new Memcache; //$memcache-& ...

  6. stm32点亮LED 测试代码及目录结构

    . main.c - 使用PB12, PB13, PB14, PB15, PB5, PB6, PB7 这七个PB口点亮LED. 注意PB3和PB4是特殊口, 直接调用无效. #include &quo ...

  7. 使用badblocks检测坏块

    命令格式 badblocks [-svw][-b <区块大小>][-o <输出文件>][磁盘装置][磁盘区块数 [启始区块]] 典型的命令如下 # 写测试, 数据安全 -c - ...

  8. Oracle用分区表分区交换做历史数据迁移

    一. 说明: OLTP库中有些表数据量大,且每月有持续的大量数据添加.因为历史数据在此库中不再做訪问,而是在另1个OLAP库中做分析.所以会对历史数据迁移至OLAP库中.对这样的历史数据迁移的操作.较 ...

  9. 【bootstrapV3】移动端和PC端的 滚动监听

    1.本代码适用于 bootstrap V3 的 页面滚动监听 2.效果: 3.代码: <!DOCTYPE html> <html lang="zh-CN"> ...

  10. HBase Go客户端Row构造注意事项

    1. Hbase 的Go客户端语言使用方法 2. Hbase的Row使用注意事项 2.1. Row的前几个字段尽量散列 2.2. Row的排序是把所有Row中的字符做字典排序 我们最近在一个项目中使用 ...