1、定义一个下载工具类

public class DownloadManagerUtil {private Context mContext;public DownloadManagerUtil(Context context) {mContext = context;}public long download(String url, String title, String desc) {Uri uri = Uri.parse(url);DownloadManager.Request req = new DownloadManager.Request(uri);//设置WIFI下进行更新//req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);//下载中和下载完后都显示通知栏req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);//使用系统默认的下载路径 此处为应用内 /android/data/packages ,所以兼容7.0String apkName;if(url.endsWith(".apk")){apkName = url.substring(url.lastIndexOf("/"));}else {apkName = "sswl_game_"+System.currentTimeMillis()+".apk";}req.setDestinationInExternalFilesDir(mContext, Environment.DIRECTORY_DOWNLOADS, apkName);req.setVisibleInDownloadsUi(true);//通知栏标题req.setTitle(title);//通知栏描述信息req.setDescription(desc);//设置类型为.apkreq.setMimeType("application/vnd.android.package-archive");//获取下载任务IDDownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);long loadId = dm.enqueue(req);Log.i("min77","loadId = "+loadId);return loadId;}/*** 下载前先移除前一个任务,防止重复下载** @param downloadId*/public void clearCurrentTask(long downloadId) {DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);try {dm.remove(downloadId);} catch (IllegalArgumentException ex) {ex.printStackTrace();}}
}

2、定义一个receiver接收下载进度的广播

public class DownloadReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {//下载完成跳转去安装apklong id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);installApk(context, id);} else if (intent.getAction().equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)) {//处理 如果还未完成下载,用户点击Notification ,跳转到下载中心Intent viewDownloadIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);viewDownloadIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(viewDownloadIntent);}}private static void installApk(Context context, long downloadApkId) {try {DownloadManager dm = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);Intent paramIntent = new Intent("android.intent.action.VIEW");//获取当前下载id数据库游标Cursor cursor = dm.query(new DownloadManager.Query().setFilterById(new long[] { downloadApkId }));cursor.moveToFirst();//获取下载apk文件uri的列数int fileUriIdx = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);//获取下载apk文件uriString fileUri = cursor.getString(fileUriIdx);paramIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);Uri uri;// 7.0+ 需要将file://的uri转换为更安全的content://,并且增加读取uri权限if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){String path="";if (fileUri != null) {path = Uri.parse(fileUri).getPath();}uri = FileProvider.getUriForFile(context, context.getPackageName() + ".sswl.provider", new File(path));paramIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//            //兼容8.0//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//                boolean hasInstallPermission = context.getPackageManager().canRequestPackageInstalls();//                if (!hasInstallPermission) {//                    startInstallPermissionSettingActivity(context);//                    return;//                }//            }}else {uri = Uri.parse(fileUri);}//设置打开apk格式文件paramIntent.setDataAndType(uri, "application/vnd.android.package-archive");if(!TextUtils.isEmpty(DownloadManagerUtil.apkMd5)){//服务端有下发MD5ParcelFileDescriptor parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri, "rw");FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();fileDescriptor.sync();if(fileDescriptor.valid()){//正常获取到fileDescriptor对象FileInputStream fis = new FileInputStream(fileDescriptor);String md5 = Md5Utils.getFileMD5(fis);Log.i("min77","md5 = "+md5);if (DownloadManagerUtil.apkMd5.equalsIgnoreCase(md5)) {//计算出的MD5一致handleDownloadedApk(context, paramIntent);}else {ToastUtils.show(context, ResourceUtil.getString(context,"com_sswl_apk_md5_error"));// 要是系统下载器下载的apk MD5不对,则跳转到外部浏览器下载Uri uri1 = Uri.parse(DownloadManagerUtil.downloadUrl);Intent intent = new Intent(Intent.ACTION_VIEW, uri1);context.startActivity(intent);}}else {handleDownloadedApk(context, paramIntent);Log.e("min77"," fileDescriptor1.valid() = "+fileDescriptor.valid());}}else {handleDownloadedApk(context, paramIntent);}} catch (Exception e) {e.printStackTrace();openLocalDir(context);}}/*** 处理下载好的apk* @param context* @param paramIntent*/private static void handleDownloadedApk(Context context, Intent paramIntent) {if (paramIntent.resolveActivity(context.getPackageManager()) != null) {  //存在安装apk的activity,则打开安装界面context.startActivity(paramIntent);} else {//不存在安装apk的activity,则打开apk所在目录openLocalDir(context);}DownloadManagerUtil.apkMd5 = "";}/*** 跳转到设置-允许安装未知来源-页面*/@TargetApi(Build.VERSION_CODES.O)private static void startInstallPermissionSettingActivity(Context context) {//后面跟上包名,可以直接跳转到对应APP的未知来源权限设置界面。使用startActivityForResult 是为了在关闭设置界面之后,获取用户的操作结果,然后根据结果做其他处理Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:" + context.getPackageName()));intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent);}private static void openLocalDir(Context context){//调用系统文件管理器打开指定路径目录//获取到指定文件夹,这里为:/storage/emulated/0/Android/data/你的包  名/files/DownloadFile file = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);Intent intent = new Intent(Intent.ACTION_GET_CONTENT);//7.0以上跳转系统文件需用FileProvider,参考链接:https://blog.csdn.net/growing_tree/article/details/71190741Uri uri = FileProvider.getUriForFile(context,context.getPackageName() + ".sswl.provider",file);intent.setData(uri);intent.addCategory(Intent.CATEGORY_OPENABLE);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent);}

2、记得在AndroidManifest.xml中声明
1)声明访问网络权限、读写外部存储权限、安装apk权限

    <uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- android 8.0+ 需要这个权限才能安装apk --><uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

2)声明receiver下载广播接收器

 <receiver android:name=".receiver.DownloadReceiver"><intent-filter><action android:name="android.intent.action.DOWNLOAD_COMPLETE" /><action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" /></intent-filter></receiver>

Android 利用系统下载管理器下载apk相关推荐

  1. LINE分享android利用系统自带分享实现LINE分享功能

    android利用系统自带分享实现分享功能之LINE分享 最近公司向海外发展,提出了一个国外主流的社交APP分享需求.原来我使用的是第三方分享工具,但是太鸡肋,国内的APP支持的还是不错的,但是国外支 ...

  2. Android 使用系统下载管理器DownloadManager下载文件

    使用系统下载管理器,主要有两个类:DownloadManager, DownloadManager.Request 1.建立一个下载 声明一个DownloadManager对象 private Dow ...

  3. Android 通过 WebView 请求下载 APK

    很少去研究 Webview 的具体使用,之前在项目中遇到,通过点击 H5 中的按钮来进行下载 Apk .刚收到这个需求想到的第一个想法就是调用 JS 来实现.之后实际运用前去看了看 WebView 的 ...

  4. WebView跳转系统浏览器下载apk

    若url为下载apk的链接时,形如https://resource.xxx.net/download/resource/123.apk 在WebView的shouldOverrideUrlLoadin ...

  5. Window 10 使用WSL2下载编译Android 10 系统源码,并用sourceInsight 4 看系统源码

    一.Window 10 安装WSL2 安装教程来自微软官网:https://docs.microsoft.com/zh-cn/windows/wsl/install-win10 步骤 1 - 启用适用 ...

  6. 简单易懂SpringBoot和Android上传和下载文件方案——采用URL

    上传思路 SpringBoot把文件保存在静态资源里,并且开启静态资源访问 数据库保存文件的URL地址(URL地址是一个字符串) Android采用OkHttp上传文件 下载思路 SpringBoot ...

  7. linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件...

    原创,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4555328.html  之前写过一篇<windows下Android利用ant自动编译.修改配置文件.批量 ...

  8. Android 利用广播实现黑名单【指定号码】的短信的拦截 附源码下载链接

    Android 利用广播实现指定号码的短信的拦截 根据最近的学习内容,今天实现了利用广播进行指定号码的拦截 步骤: ①.写一个数据库的帮助类,实现对数据库的创建,总共创建两个数据库psms(受保护的短 ...

  9. Android——下载apk文件,并在通知栏显示下载进度

    如何下载apk文件?这里介绍两种方式:一通过异步任务读取文件,二利用系统方法DownloadManager进行下载. 通过异步任务下载apk 文件 public String downloadAsAp ...

最新文章

  1. Usage and Idioms——Categories
  2. atlas单机模式代码_用代码玩太无聊,这样玩海盗游戏《ATLAS》单机模式才是正确玩法...
  3. python二叉搜索树建立_700. 二叉搜索树的搜索(Python)
  4. MVC+Ninject+三层架构+代码生成 -- 总结(一、數據庫)
  5. python切片语法-Python字符串切片操作知识详解
  6. html如何禁止用户缩放,html如何禁止页面缩放
  7. linux c嵌入汇编语言,Linux 下的C和Intel 汇编语言混用
  8. Autofac框架初识与应用
  9. 什么是DVI光端机?dvi光端机的优势有哪些?
  10. Apache的虚拟主机配置
  11. 大数据_Hbase-内容回顾_知识点补充_线程安全与wait的区别---Hbase工作笔记0019
  12. PCWorld选出52个实用网站
  13. 基于java的飞机大战雷电游戏的开发与设计#毕业设计
  14. 什么是物联网技术?物联网主要技术有哪些?
  15. Java实现HTML页面截图功能
  16. Kaldi中文语音识别:各种开源的已经训练好的语音识别模型
  17. Qt设计的一个图片查看器
  18. JavaScript立即执行函数
  19. Kubernetes K8S之资源控制器Job和CronJob详解
  20. 从val_loss,train_loss,test_loss中产生的问题

热门文章

  1. c语言编程银行利率计算器,c语言写用户从键盘上输入银行利率,本金,存...
  2. mining lorry和mining truck有什么不同。
  3. VS2015+caffe+matlab+python+CPU
  4. python画大象_Python Day21
  5. 究竟什么是前端脚手架?
  6. python获取站长之家素材
  7. 我为什么会性格内向,能不能内向性格?
  8. stagefright 架构分析(四) MediaExtractor
  9. 新手小白学JAVA 泛型 Collection List Set
  10. 便利蜂2022数据分析秋招一面凉经