由于项目需求,需要下载H5网页下的附件文件,最终选择使用DownloadManager系统封装好的下载类来实现该功能,只需轻松设置几行代码即可执行下载了,而且在关闭网络或者出现网络延迟时,网络恢复后可自动执行下载,我们只需监听系统发送的广播回调即可,真的是大大的方便了移动开发者们。由于我是H5网页下载,所以这里我需要监听WebView的DownloadListener下载回调监听,代码如下:
mWebView.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
TipsUtil.log("下载 url=" + url);
ToastFactory.showToast(getActivity(), "开始下载文件");
downloadByLocal(url, contentDisposition, mimetype);
}
});
然后是DownloadManager下载参数设置:
private void downloadByLocal(String url, String contentDisposition, String mimeType) {
// 指定下载地址
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
// 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库
request.allowScanningByMediaScanner();
// 设置通知的显示类型,下载进行时和完成后显示通知
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
// 设置通知栏的标题,如果不设置,默认使用文件名
// request.setTitle("This is title");
// 设置通知栏的描述
request.setDescription("下载成功");
// 允许该记录在下载管理界面可见
request.setVisibleInDownloadsUi(true);
// 允许下载的网路类型 WIFI 和 手机网络流量
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
//是否允许漫游状态下,执行下载操作
request.setAllowedOverRoaming(true);
//是否允许“计量式的网络连接”执行下载操作
request.setAllowedOverMetered(true);
// 设置下载文件保存的路径和文件名
String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType);
String name = null;
try {
name = URLDecoder.decode(fileName, "utf-8"); //这里需要转码获取到中文格式的文件名
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//设置存储路径 这里存储地址可以自己设置
request.setDestinationInExternalFilesDir(getActivity(), "file_download/", name);
final DownloadManager downloadManager = (DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE);
// 下载任务唯一ID
long downloadId = downloadManager.enqueue(request);
}
接着我们需要编写一个广播类用于接收文件下载状态:
public class DownloadReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
//这里拿到下载文件的唯一ID
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
Cursor c = downloadManager.query(query);
if (c.moveToFirst()) {
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (status) {
case DownloadManager.STATUS_PAUSED: //下载暂停
TipsUtil.log("下载暂停");
break;
case DownloadManager.STATUS_PENDING: //下载延迟
TipsUtil.log("下载延迟");
break;
case DownloadManager.STATUS_RUNNING: //正在下载
TipsUtil.log("正在下载");
break;
case DownloadManager.STATUS_SUCCESSFUL: //下载成功
TipsUtil.log("下载成功");
ToastFactory.showToast(context,"下载成功");
//下载成功,自动打开文件
openFile(context,downloadManager,downloadId);
break;
case DownloadManager.STATUS_FAILED: //下载失败
TipsUtil.log("下载失败");
ToastFactory.showToast(context,"下载失败");
//下载失败,移除下载状态
downloadManager.remove(downloadId);
break;
}
}
c.close();
}
}
/**
* 打开下载文件
*/
private void openFile(Context context,DownloadManager dm,long downloadId){
String type = dm.getMimeTypeForDownloadedFile(downloadId);
if (TextUtils.isEmpty(type)) {
type = "*/*";
}
Uri uri = dm.getUriForDownloadedFile(downloadId);
if (uri != null) {
try {
Intent handlerIntent = new Intent(Intent.ACTION_VIEW);
handlerIntent.setDataAndType(uri, type);
//需要设置Flag 要不然会报错 需要动态添加读写权限,否则跳入第三方软件打开文件时会读取不到
handlerIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
context.startActivity(handlerIntent);
} catch (ActivityNotFoundException exception) {
ToastFactory.showToast(context, exception.getMessage());
}
}
}
}
最后我们把编写好的广播注册到Activity或者Fragment中,由于我这里的是Fragment中注册所以需要getActivity()
private DownloadReceiver mReceiver;
/**
* 注册广播
*/
private void registerReceiver(){
mReceiver = new DownloadReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
getActivity().registerReceiver(mReceiver, filter);
}
不要忘记在onDestroy中注销广播
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
好了,今天的分享就到此结束了,喜欢我的朋友们可以点个关注哦!