使用 DownloadManager 可以在下载一个大的资源时,不要求用户让应用程序一直处于激活状态。DownloadManager 可以让系统完全处理和管理需要长时间运行的下载操作。
使用它的优点:即使下载失败、连接改变甚至设备重启时,DownloadManager依然会继续尝试下载资源。
DownloadManager.Request ,这个类包含请求新的下载所需的所有信息。
例子:
MainActivity.java :
<span style="font-size:18px;">package com.crazy.download;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class MainActivity extends AppCompatActivity {
private static final String DLID = "downloadId";
private SharedPreferences preferences;
private DownloadManager manager;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageView = new ImageView(this);
setContentView(imageView);
preferences = PreferenceManager.getDefaultSharedPreferences(this);
manager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
}
/**
* 所有的示例都是在 onResume() 方法中做,是因为,每次返回 Activity 时,程序都可以确定下载状态。
* 每次返回一个 long 类型的 ID 值,可用来引用管理器中的本次下载
*/
@Override
protected void onResume() {
super.onResume();
if (!preferences.contains(DLID)) {
// 开始下载
Uri resource = Uri.parse("http://img.ivsky.com/img/tupian/pre/201509/02/erhai_shenguang.jpg");
DownloadManager.Request request = new DownloadManager.Request(resource);
// 设置允许的连接来处理下载
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE
| DownloadManager.Request.NETWORK_WIFI);
// 不设置漫游下载
request.setAllowedOverRoaming(false);
// 在通知栏上显示
request.setTitle("下载示例");
long id = manager.enqueue(request);
// 保存唯一的 id
preferences.edit().putLong(DLID, id).commit();
} else {
// 下载已经开始,检查下载状态
queryDownloadStatus();
}
// 用来监听 ACTION_DOWNLOAD_COMPLETE 广播,
// 在下载完后,会将图片设置到 ImageView 以进行响应
registerReceiver(receiver,
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
queryDownloadStatus();
}
};
private void queryDownloadStatus() {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(preferences.getLong(DLID, 0));
Cursor cursor = manager.query(query);
if (cursor.moveToFirst()) {
int status =
cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
switch (status) {
case DownloadManager.STATUS_PAUSED:
case DownloadManager.STATUS_PENDING:
case DownloadManager.STATUS_RUNNING:
// 什么也不做,下载依然进行
break;
case DownloadManager.STATUS_SUCCESSFUL:
// 下载完成,显示图片
try {
ParcelFileDescriptor file =
manager.openDownloadedFile(preferences.getLong(DLID, 0));
FileInputStream fis =
new ParcelFileDescriptor.AutoCloseInputStream(file);
imageView.setImageBitmap(BitmapFactory.decodeStream(fis));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
break;
case DownloadManager.STATUS_FAILED:
// 清除下载并稍后重试
manager.remove(preferences.getLong(DLID, 0));
preferences.edit().clear().commit();
break;
}
}
}
}
</span>
在 AndroidManifest.xml 中注册 :
<uses-permission android:name="android.permission.INTERNET"/>
上面的示例没有指定下载文件的位置,文件会下载到共享下载缓存中,这种下载方式可以很方便地快速获取数据,如果希望长期的存储,可以使用DownloadManager.Request 的如下方法:
Request.setDestinationInExternalFilesDir();设置目标位置为外部存储器中的一个隐藏目录。
Request.setDestinationInExternalPublicDir();设置目标位置为外部存储器中的一个公共目录。
Request.setDestinationUri();设置目标位置为外部存储器中的一个文件 Uri。
这时需要多设置一个权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>