一、使用的时候需要添加权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
二、简介
在android开发中,经常会使用到文件下载的功能,比如app版本更新等。在api level 9之后,android系统为我们提供了DownLoadManager类,这是android提供的系统服务,我们通过这个服务完成文件下载。整个下载过程全部交给系统负责,不需要我们过多的处理。
通过API文档,可以看出DownLoadManager包含两个内部类:
参考:https://developer.android.google.cn/reference/android/app/DownloadManager
三、使用
创建
String fileName = "test.mp4";
Uri uri = Uri.parse(downloadUrl);
DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(uri);
// 设置允许使用的网络类型,这里是移动网络和wifi都可以
request.setAllowedNetworkTypes(request.NETWORK_MOBILE | request.NETWORK_WIFI);
//设置是否允许漫游
request.setAllowedOverRoaming(true);
//设置文件类型
request.setMimeType("video/*");//表示视频类型
//在通知栏中显示
request.setNotificationVisibility(request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle(fileName);
request.setDescription("视频正在下载");
request.setVisibleInDownloadsUi(true);
// 设置为可被媒体扫描器找到
request.allowScanningByMediaScanner();
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
// 将下载请求放入队列
long downloadId = downloadManager.enqueue(request);
注册广播
下载完成后,下载管理会发出DownloadManager.ACTION_DOWNLOAD_COMPLETE这个广播,并传递downloadId作为参数。通过接受广播我们可以打开对下载完成的内容进行操作
// 监听下载成功状态
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
创建广播,监听下载状态
下载完成时,发送的广播。
对应的Action为:ACTION_DOWNLOAD_COMPLETE
Notification被点击时发送的广播。
对应的Action为:ACTION_NOTIFICATION_CLICKED
查看所有下载情况的广播。
对应的Action为:ACTION_VIEW_DOWNLOADS
//广播接受者,接收下载状态
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
//检查下载状态
checkDownloadStatus(downloadId );
}
}
//检查下载状态
private void checkDownloadStatus(long downloadId ) {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId );//筛选下载任务,传入任务ID,可变参数
Cursor c = downloadManager.query(query);
if (c.moveToFirst()) {
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (status) {
case DownloadManager.STATUS_PAUSED:
MLog.i(">>>下载暂停");
case DownloadManager.STATUS_PENDING:
MLog.i(">>>下载延迟");
case DownloadManager.STATUS_RUNNING:
MLog.i(">>>正在下载");// 此处无法监听到
break;
case DownloadManager.STATUS_SUCCESSFUL:
MLog.i(">>>下载完成");
break;
case DownloadManager.STATUS_FAILED:
MLog.i(">>>下载失败");
break;
}
}
}
};
下载进度
- DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR:到目前为止下载的字节数。
- DownloadManager.COLUMN_DESCRIPTION:这个下载的客户端提供的描述
- DownloadManager.COLUMN_ID:特定下载的标识符,在整个系统中是唯一的。
- DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP:上一次修改下载的时间戳,在system.currenttimemillis()(UTC时间)。
- DownloadManager.COLUMN_LOCAL_URI:将存储下载文件的Uri。
- DownloadManager.COLUMN_MEDIAPROVIDER_URI:这个下载条目的MediaProvider对应条目的URI。
- DownloadManager.COLUMN_MEDIA_TYPE:下载文件的网络媒体类型。
- DownloadManager.COLUMN_REASON:提供有关下载状态的更多详细信息。
- DownloadManager.COLUMN_STATUS:下载的当前状态,作为STATUS_ *常量之一。
- DownloadManager.COLUMN_TITLE:这个下载的客户端提供的标题
- DownloadManager.COLUMN_TOTAL_SIZE_BYTES:下载的总大小
- DownloadManager.COLUMN_URI:URI下载
采用时间来实时刷新进度
// 刷新下载进度
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
DownloadManager.Query query = new DownloadManager.Query();
Cursor cursor = downloadManager.query(query.setFilterById(downloadId ));
if (cursor != null && cursor.moveToFirst()) {
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
// 成功后取消监听
task.cancel();
}
int bytesDownloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytesTotal = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
int pro = (bytesDownloaded * 100) / bytesTotal;
MLog.d("下载进度 bytesDownloaded" + bytesDownloaded + "总文件大小:bytesTotal" + bytesTotal);
MLog.d(">>>下载进度 pro" + pro);
}
cursor.close();
}
};
timer.schedule(task, 0, 1000);