Android系统中都包含一个下载管理器(DownloadManager),这个原生的应用作为一个Service来优化长时间下载操作。DownloadManager通过处理HTTP连接、监测连接的变化和系统重新启动来确保每一次下载都成功完成。在我们开发响应的下载任务时,最好都能使用DownloadManager一方面是由于是现成的API我们直接使用就行不需要自己在去实现下载代码,另一方面DownloadManager能够确保下载任务成功完成,即使是系统重启,也会在重启后继续执行下载任务,可以确保任务的完成。
获取DownloadManager:
要访问DownloadManager可以使用getSystemService方法,同时传入Context.DOWNLOAD_SERVICE参数:
DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
下载文件:
想要请求一个下载需要创建一个DownloadManager.Request对象,指定要下载文件的URL已经其他下载设置参数,然后将request作为参数传入到DownloadManager的enqueue方法中进行下载,enqueue是将下载请求Request放入下载队列中依次去下载,示例代码:
/**
* 根据指定的url下载音乐文件
* @param url
*/
public void downLoadMuisc(String url) {
Uri uri = Uri.parse(url);
DownloadManager.Request request = new Request(uri);
// 设置在wifi网络下才进行下载
request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
// 如果手机当前为移动网络,设置为true会阻止下载
request.setAllowedOverRoaming(true);
// 设置MIME请求类型
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
String mimeType = mimeTypeMap.getExtensionFromMimeType(MimeTypeMap
.getFileExtensionFromUrl(url));
request.setMimeType(mimeType);
// 设置通知栏显示
request.setShowRunningNotification(true);
request.setVisibleInDownloadsUi(true);
// 设置在通知栏中的显示,下载完成后仍然现在,知道关闭或清除它
// request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
// 设置通知栏显示标题
request.setTitle("文件下载");
request.setDescription("音乐下载中...");
// 判断SD卡是否存在
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
// SD卡path
String SD_CARD = Environment.getExternalStorageDirectory()
.getPath();
// 设置下载目录
File file = new File(SD_CARD + "/qing_muisc");
if (!file.exists())
file.mkdirs();
request.setDestinationInExternalPublicDir("/qing_muisc/",
"test.mp3");
}
//获取下载文件的应用id,可以使用这个id对下载任务进行查询
long referenceId = downloadManager.enqueue(request);
}
在上面的定义中描述了一些常用的下载参数设定,这些参数都是在DownloadManager.Request中设置的,包括:wifi下载,下载任务在通知栏中显示,自定义下载标题及描述,自定义下载文件的存储目录等。设置完下载参数后将其作为参数传入enqueue方法,放入下载队列中,这个方法会返回一个long型的整数是这个下载任务的id,使用它可以进行相关查询下载状态,下载完成情况等信息。
查询下载文件:
使用DownloadManager.Query对象可以对下载任务进行查询条件的设置,可以根据下载任务的Id也可以使用下载状态作为查询条件。将Query对象作为downloadManager.query(query)的查询参数进行查询,该方法返回一个Cursor,通过遍历Cursor可以得到我们想要的值,查询示例代码:
/**
* 获取下载文件的字节大小以及当前下载状态
* @param downloadId
* @return
*/
public Map<String,Object> getBytesAndStatus(long downloadId) {
Map<String,Object> resultMap = new HashMap<String, Object>();
resultMap.put("fileRefId", downloadId);
//得到Query对象,并传入下载文件ID作为查询条件
DownloadManager.Query query = new DownloadManager.Query()
.setFilterById(downloadId);
Cursor c = null;
try {
//查询指定id的下载任务
c = downloadManager.query(query);
if (c != null && c.moveToFirst()) {
//获取已下载的大小
int download_size = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
//获取文件的总大小
int total_size = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
//获取当前的下载状态
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
resultMap.put("download_size", download_size);
resultMap.put("total_size", total_size);
resultMap.put("status", status);
}
} finally {
if (c != null) {
c.close();
}
}
return resultMap;
}
上面的方法只是查询下载任务的已完成字节大小、总大小以及下载状态,并将这些查询后的值放入map中返回,更多查询值可以查看文档中DownloadManager.COLUMN_*常量,这些常量对应的都是下载任务的属性名称。
注册下载完成监听:
当任务下载完成后DownloadManager会广播一个下载完成的广播,我们通常在Activity或者Fragment对象的onResume()方法中实例化广播接收器以及IntentFilter,并在这个方法中注册广播接收器,在onPause()中注销这个监听器,示例代码:
public class DownLoadManagerActivity extends Activity {
// 注册一个广播接收器接收下载完成的广播
private IntentFilter downIntentFilter;
private BroadcastReceiver downBroadcastReceiver;
@SuppressWarnings("unused")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitle("下载文件..");
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.download_file_layout);
DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
//定义接收下载完成的广播接收器
downBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//得到已下载完成的文件id
long fildId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
//进行相关操作...
}
};
//定义下载完成IntentFilter
downIntentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
//注册下载完成广播接收器
registerReceiver(downBroadcastReceiver, downIntentFilter);
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
//注销注册的下载完成广播接收器
unregisterReceiver(downBroadcastReceiver);
}
}
在onReceive方法中处理具体的操作,在通过intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);拿到下载完成的任务id以后就可以得到任何与这个下载任务相关的信息。