首先扯点别的:清明节回了一趟黄岛,去了学校看了看,也是物是人非了呀。酒也没少喝,前天做了一夜的车早上9点多到上海,然后直接杀奔公司上班,也是没谁了。

完整代码请参考 DownloadManagerActivity

今天记录一下DownloadManager的使用。参考链接会在文章末尾给出。先来个效果图。

以下载一个万能wifi钥匙的安装包为例。下载地址如下所示。

 private String wifiUrl = "http://140.207.247.205/imtt.dd.qq.com/16891/DF6B2FB4A4628C2870C710046C231348.apk?mkey=58d4b294acc7802a&f=8e5d&c=0&fsname=com.snda.wifilocating_4.1.88_3108.apk&csr=1bbd&p=.apk";

下载需要的权限

 <uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

因为WRITE_EXTERNAL_STORAGE权限是危险权限,所以在使用的时候要进行动态权限申请,我们使用easyPermissions来进行动态权限申请。easypermissions的使用介绍可见下面的连接地址。

https://github.com/googlesamples/easypermissions

下面就开始使用DownLoadManager。

DownloadManager 简介:DownloadManager一个是处理长期运行的HTTP下载的系统服务。客户端请求的URI可以被被下载到一个特定的文件。DownloadManager会在后台进行下载,能很好的进行Http交互,在下载失败,或者连接改变,重新启动系统后重新下载。并且可以在Notification中查看进度。DownloadManger有两个内部类,Request 和Query。Request类可设置下载的一些属性。Query类可查询当前下载的进度,下载地址,文件存放目录等数据。

//获取DownloadManager实例

DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);

//新建一个下载请求, wifiUrl就是我们要下载的apk的地址。

DownloadManager.Request request = new DownloadManager.Request(Uri.parse(wifiUrl));
//设置下载的文件存储的地址,我们这里将下载的apk文件存在/Download目录下面
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "wifi.apk");
//设置现在的文件可以被MediaScanner扫描到。
request.allowScanningByMediaScanner();
//设置通知的标题
request.setTitle("下载");
//设置下载的时候Notification的可见性
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
//设置下载文件类型
request.setMimeType("application/vnd.android.package-archive");

关于下载的request一些属性的设置。

/*** 设置下载的文件的存储地址位于公共的外部存储目录,和Environment.getExternalStoragePublicDirectory(String)返回的路径一样。* 下载的文件不能被MediaScanner扫描到,但是可以调用request.allowScanningByMediaScanner()使下载的文件可以被MediaScanner扫描到。* @param dirType 存储目录类型* @param subPath 在外部存储目录下面的路径包括文件名*/public Request setDestinationInExternalPublicDir(String dirType, String subPath)

比如我们在上面设置的存储位置

//下载的apk文件存在/Download目录下面名字叫wifi.apk
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "wifi.apk");
/*** 设置下载的文件的存储地址位于应用下的外部文件目录下,和Context#getExternalFilesDir(String)返回的路径一样。
*/
public Request setDestinationInExternalFilesDir(Context context, String dirType,String subPath)

设置在那种网路条件下可以进行下载

/*** flags取值* NETWORK_MOBILE 使用流量可以下载* NETWORK_WIFI 使用wifi可以下载
*/
public Request setAllowedNetworkTypes(int flags)

控制在下载过程中或者下载完毕以后download manager 发出的系统通知是否可见

/***visibility取值* VISIBILITY_VISIBLE 在下载过程中通知可见,下载完成后不可见* VISIBILITY_VISIBLE_NOTIFY_COMPLETED 在下载过程中和下载完成后都可见* VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION 只有在下载完成后通知才可见* VISIBILITY_HIDDEN 通知不可见,如果使用这个选项需要 * android.permission.DOWNLOAD_WITHOUT_NOTIFICATION.权限
*/
public Request setNotificationVisibility(int visibility)

开始下载

当 download manager准备好而且网络可用的时候就会自动开始下载,并且enqueue方法会返回一个唯一的id,可以用来查询下载的进度,或者取消下载等等。

long id = downloadManager.enqueue(request);

查询下载的进度
如果我们要在应用中显示下载的进度,比如用一个ProgressBar来显示下载的进度,这时候我们就要实时获取的进度这时候就需要用到Query这个类了,这个类是DownloadManager中的一个内部类。

DownloadManager.Query query = new DownloadManager.Query();
//根据id进行查询
Cursor cursor = downloadManager.query(query.setFilterById(id));
if (cursor != null && cursor.moveToFirst()) {//已经下载的字节数
int bytesDownload = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
//文件的总的字节数
int bytesTotal = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));

Query类中还有好多信息可以查询,因为我们这里只关心下载进度的问题,其他的就不查了。

取消下载

//停止下载,并删除下载的相关文件,不管是否已经下载完成。
downloadManager.remove(id);

下载完apk进行安装。要注意的一点就是,如果是7.0及以上的系统要是用FileProvider的方式构建Uri

private void install(String path) {Uri uri;File file = new File(path);Intent intent = new Intent(Intent.ACTION_VIEW);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//如果是7.0以上的系统,要使用FileProvider的方式构建Uriuri = FileProvider.getUriForFile(this, "com.hm.retrofitrxjavademo.fileprovider", file);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);intent.setDataAndType(uri, "application/vnd.android.package-archive");} else {intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");}startActivity(intent);
}

最后贴一下完整的代码

/*** 使用系统自带的DownloadManager下载*/
public class DownloadManagerActivity extends BaseActivity implements EasyPermissions.PermissionCallbacks {private static final String TAG = "DownloadManagerActivity";public static final String PROGRESS = "progress";private static final String[] PERMISSIONS = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};public static final int REQUEST_CODE = 14;@BindView(R.id.btn_start)Button btnStart;@BindView(R.id.btn_cancel)Button btnCancel;@BindView(R.id.progressBar)ProgressBar progressBar;@BindView(R.id.textProgress)TextView textProgress;private String wifiUrl = "http://140.207.247.205/imtt.dd.qq.com/16891/DF6B2FB4A4628C2870C710046C231348.apk?mkey=58d4b294acc7802a&f=8e5d&c=0&fsname=com.snda.wifilocating_4.1.88_3108.apk&csr=1bbd&p=.apk";private long id;private DownloadManager downloadManager;private DownloadManager.Query query;private String downloadPath;private Timer timer;private TimerTask timerTask;private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {Bundle bundle = msg.getData();int progress = bundle.getInt(PROGRESS);progressBar.setProgress(progress);textProgress.setText(String.valueOf(progress) + "%");if (progress == 100) {timer.cancel();install(downloadPath);}}};public static void launch(Context context) {Intent starter = new Intent(context, DownloadManagerActivity.class);context.startActivity(starter);}@Overrideprotected int bindLayout() {return R.layout.activity_download_manager;}@Overrideprotected void initData() {progressBar.setMax(100);query = new DownloadManager.Query();}@OnClick({R.id.btn_start, R.id.btn_cancel})public void onClick(View view) {switch (view.getId()) {case R.id.btn_start:if (EasyPermissions.hasPermissions(this, PERMISSIONS)) {startDownLoad();} else {EasyPermissions.requestPermissions(this, getString(R.string.rationale), REQUEST_CODE, PERMISSIONS);}break;case R.id.btn_cancel:cancelDownload();btnStart.setClickable(true);timer.cancel();textProgress.setText("");progressBar.setProgress(0);break;}}private void startDownLoad() {timer = new Timer();timerTask = new TimerTask() {@Overridepublic void run() {queryProgress();}};btnStart.setClickable(false);downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);DownloadManager.Request request = new DownloadManager.Request(Uri.parse(wifiUrl));request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "wifi.apk");downloadPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + File.separator + "wifi.apk";request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);request.allowScanningByMediaScanner();request.setTitle("下载");request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);//设置下载文件类型request.setMimeType("application/vnd.android.package-archive");id = downloadManager.enqueue(request);timer.schedule(timerTask, 0, 1000);}private void cancelDownload() {if (id != 0) {downloadManager.remove(id);}}private void queryProgress() {if (downloadManager != null) {Cursor cursor = downloadManager.query(query.setFilterById(id));if (cursor != null && cursor.moveToFirst()) {String address = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));//已经下载的字节数int bytesDownload = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));int bytesTotal = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));String title = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE));String description = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_DESCRIPTION));long downloadId = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID));String uri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_URI));int progress = bytesDownload * 100 / bytesTotal;Log.e(TAG, "progress=" + progress);Message message = Message.obtain();Bundle bundle = new Bundle();bundle.putInt(PROGRESS, progress);message.setData(bundle);handler.sendMessage(message);}if (cursor != null) {cursor.close();}}}private void install(String path) {Uri uri;File file = new File(path);Intent intent = new Intent(Intent.ACTION_VIEW);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//如果是7.0以上的系统,要使用FileProvider的方式构建Uriuri = FileProvider.getUriForFile(this, "com.hm.retrofitrxjavademo.fileprovider", file);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);intent.setDataAndType(uri, "application/vnd.android.package-archive");} else {intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");}startActivity(intent);}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);}@Overridepublic void onPermissionsGranted(int requestCode, List<String> perms) {if (requestCode == REQUEST_CODE) {if (EasyPermissions.hasPermissions(this, PERMISSIONS)) {startDownLoad();} else {Toast.makeText(this, "没有响应的权限,无法进行下载", Toast.LENGTH_SHORT).show();}}}@Overridepublic void onPermissionsDenied(int requestCode, List<String> perms) {if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {new AppSettingsDialog.Builder(this).setRationale("下载需要读写权限").setRequestCode(AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE).setTitle("请求权限").setPositiveButton("设置").setNegativeButton("取消").build().show();}}@Overrideprotected void onDestroy() {super.onDestroy();timer.cancel();}
}

结尾:差不多该睡觉了。其实这段时间一直想跟她说说话,但是也不知道说啥,哎。明天一定找她说话,没话题就制造话题,实在不行就问她最近学习忙不忙!

参考链接

  1. http://blog.csdn.net/u012209506/article/details/56012744
  2. easyPermissions的使用https://github.com/googlesamples/easypermissions
  3. FileProvider的使用http://blog.csdn.net/leilifengxingmw/article/details/57405908

Android 使用系统自带的DownloadManager下载apk相关推荐

  1. 使用Android自带的DownloadManager下载ApK并安装

    一.在 AndroidManifest.xml 中的准备 进行网络请求,需要申请<uses-permission android:name="android.permission.IN ...

  2. android 自动更新 服务端,搭建android版本更新服务器使用android系统自带的DownloadManager下载文件...

    这几天想自己做一个文件更新的功能,但是由于不知道怎样写服务端,所以一直没有去做,后来发现原来服务端编写简直是太简单了,所以今天就实现了 版本更新的这样一个功能. 一搭建版本更新服务器: 搭建这个一个服 ...

  3. android安装自动打开网页,Android调用系统自带浏览器打开网页的实现方法

    Android调用系统自带浏览器打开网页的实现方法 在Android中可以调用自带的浏览器,或者指定一个浏览器来打开一个链接.只需要传入一个uri,可以是链接地址. 启动android默认浏览器 在A ...

  4. [mac]添加系统自带辞典或下载的词典包

    [mac]添加系统自带辞典或下载的词典包 mac上自带的词典虽然说很便利,但词典种类太少了.所以想能否添加下载的词典包呢,果然有.为此整理了下,以防以后忘了,毕竟我是一个经常坏电脑的人.呵呵呵.好了 ...

  5. Android删除系统自带软件对照表

    Android删除系统自带软件对照表 Postedon 2011/04/19 by pop     注:带*号的千万不能删 *AccountAndSyncSettings.apk同步与帐户设定 *Ap ...

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

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

  7. android系统旁边有一个锁,Android中系统自带锁WalkLock与KeyguardLock用法实例详解

    本文实例讲述了Android中系统自带锁WalkLock与KeyguardLock用法.分享给大家供大家参考,具体如下: WalkLock - 顾名思义 唤醒锁 点亮屏幕用的 KeyguardLock ...

  8. 【Android】系统自带的主题与样式(theme and style)

    android中自带的主题(theme)的集锦: •android:theme="@android:style/Theme.Dialog"   将一个Activity显示为对话框模 ...

  9. Android调用系统自带的文件管理器进行文件选择

    这几天在做的项目网盘.上传时需要用到调用系统自带的文件管理器来选择文件,后来就在考虑怎么调用,网上也搜了很久,没有很好的解决方法,后来在一瞬间发现了一篇不错的文章,借鉴了一下代码. [java] vi ...

最新文章

  1. HashMap之微代码解析-总结整理
  2. erp生产管理系统流程_仁和ERP生产制造业ERP管理系统库存管理
  3. 台湾域名总量一周统计:9月第一周新增59个
  4. 学习java第二天 java体系结构与表面执行流程 (one 大白(●—●))
  5. mysql双节点部署_MariaDB GALERA 集群双节点部署
  6. Cache-control
  7. 由帧内8x8预测到MBAFF时相邻块的推导
  8. python 将txt文件转换为excel_Python学习笔记-Txt文件转Excel文件
  9. 激活Window和office工具
  10. Qwins系统工具v1.3.0绿色版
  11. sprintf函数的用法linux,sprintf函数用法解析
  12. python制作脑图_使用Python将xmind脑图转成excel用例(一)
  13. vue 获取当前本机ip_Vue项目启动时自动获取本机IP地址
  14. 面试 11、知识拓展
  15. 看了本文让你laravel安装laravel-queue-rabbitmq一路顺风
  16. php 自己画地图,绘制自己的独家地图
  17. 文件上传,出现400 的错误问题
  18. 如何选择美颜SDK接口?
  19. 超具性价比的学生神器,讯飞智能录音笔给足惊喜
  20. [脑科学]-这才是心理学

热门文章

  1. 三步把数据库读写到elsx里
  2. python层次分析模型_不到70行Python代码,轻松玩转RFM用户分析模型
  3. 设置EditText自动换行
  4. 《短视频,内容设计+营销推广+流量变现》---向登付出,读书笔记
  5. 反常积分敛散性的比较判别法专题(及常用反常积分)
  6. 化妆品软件测试,肌肤测试
  7. GIT 回滚和push库且保留log
  8. 【王喆-推荐系统】评估篇-(task5)Replay和Interleaving评估
  9. React Native入门(七)之列表组件的使用(2)关于FlatList的一切
  10. layui跳转页面传递数据