DownloadManager从android2.3开始添加到sdk里面,当时用户要求minSdkVersion=8,没有考虑使用。现在minSdkVersion=11了,应该好好研究一下,尝试这个改善一下APP的下载服务了。作为一个初学者,没有那么多理论讲解,这里通过几个小例子来探究DownloadManager的使用方式!
1.下载&&展示网络图片
1.调用DownloadManager.enque(request),即可开始下载
2.注册广播监听图片下载完成
3.展示图片
package com.hang.downloadmanagerdemo;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
public static final String URL_IMAGE = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3741636297,2352266532&fm=116&gp=0.jpg";
private long myDownloadReference;
private DownloadManager downloadManager;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageView = new ImageView(this);
setContentView(imageView);
//1.download a file
String serviceNameInString = Context.DOWNLOAD_SERVICE;
downloadManager = (DownloadManager) getSystemService(serviceNameInString);
Uri uri = Uri.parse(URL_IMAGE);
DownloadManager.Request request = new DownloadManager.Request(uri);
//设置下载的网络连接方式 1.明确指定下载时的网络类型
//only mobile network download
// request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE);
// only wifi download
// request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
//设置是否允许,在移动网络漫游时进行下载
request.setAllowedOverRoaming(true);
//设置下载的网络连接方式 2.api11引入,让系统自动判断下载的网络连接方式
downloadManager.getRecommendedMaxBytesOverMobile(this);
//默认情况下,下载的内容会保存在共享下载缓存中&&使用系统自定的文件名,可以通过如下方式进行修改
//define download file sd location&&file name
File destFile = new File(Environment.getExternalStorageDirectory(), "test.png");
if (destFile.exists()) {
destFile.delete();
}
//be careful add file:// prefix && apply read&&write external storage permission
request.setDestinationUri(Uri.parse("file://" + destFile.getAbsolutePath()));
applyPermission();
//使图库APP,可以扫描到他,这里还要注意一点,不要放到APP的私有路径下
request.setVisibleInDownloadsUi(true);
//不想在通知栏显示下载,可以按照如下方式隐藏通知栏
//download without notification (be careful about permission——DOWNLOAD_WITHOUT_NOTIFICATION)
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
//加入DownloadManager下载队列,开始下载图片
myDownloadReference = downloadManager.enqueue(request);
}
@Override
protected void onResume() {
super.onResume();
//2.通过注册广播,监听DownloadManager下载行为的变化
IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(broadcastReceiver, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long downloadCompleteReference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (myDownloadReference == downloadCompleteReference) {
//3.下载完成,加载图片
try {
ParcelFileDescriptor parcelFileDescriptor = downloadManager.openDownloadedFile(myDownloadReference);
Bitmap bitmap = BitmapFactory.decodeFileDescriptor(parcelFileDescriptor.getFileDescriptor());
imageView.setImageBitmap(bitmap);
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
}
2.监听下载进度
1.需要一个ContentObserver
public class DownloadObserver extends ContentObserver {
private long downid;
private Handler handler;
private Context context;
public DownloadObserver(Handler handler, Context context, long downid) {
super(handler);
this.handler = handler;
this.downid = downid;
this.context = context;
}
@Override
public void onChange(boolean selfChange) {
//每当/data/data/com.android.providers.download/database/database.db变化后,触发onCHANGE,开始具体查询
Log.w("onChangeID", String.valueOf(downid));
super.onChange(selfChange);
//实例化查询类,这里需要一个刚刚的downid
DownloadManager.Query query = new DownloadManager.Query().setFilterById(downid);
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
//这个就是数据库查询啦
Cursor cursor = downloadManager.query(query);
while (cursor.moveToNext()) {
int mDownload_so_far = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int mDownload_all = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
int mProgress = (mDownload_so_far * 99) / mDownload_all;
Log.w(getClass().getSimpleName(), String.valueOf(mProgress));
handler.sendEmptyMessage(mProgress);
}
}
}
2.监听变化
getContentResolver().registerContentObserver(Uri.parse("content://downloads/"),
true, new DownloadObserver(handler, MainActivity.this, downloadid));
这样就可以监听DownloadManager的下载进度了。
参考地址:
http://blog.csdn.net/qw3752258/article/details/39134749
APP私有路径
String externalFileString = this.getExternalFilesDir("").getAbsolutePath();
Log.d(TAG, "getExternalFilesDir: " + externalFileString);
String eternalCacheString = this.getExternalCacheDir().getAbsolutePath();
Log.d(TAG, "getExternalCacheDir: " + eternalCacheString);
String filesString = this.getFilesDir().getAbsolutePath();
Log.d(TAG, "getFilesDir: " + filesString);
String cacheString = this.getCacheDir().getAbsolutePath();
Log.d(TAG, "getCacheDir: " + cacheString);
D MainActivity: getExternalFilesDir: /storage/emulated/0/Android/data/com.hang.downloadmanagerdemo/files
D MainActivity: getExternalCacheDir: /storage/emulated/0/Android/data/com.hang.downloadmanagerdemo/cache
D MainActivity: getFilesDir: /data/user/0/com.hang.downloadmanagerdemo/files
D MainActivity: getCacheDir: /data/user/0/com.hang.downloadmanagerdemo/cache
this.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
//路径为:/sdcard/Android/data/packageName/files/Pictures
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
//路径为:/sdcard/Pictures
查询下载结果
除了上面,查询下载结果的方法,还可以这样做:
DownloadManager.Query myQuery = new DownloadManager.Query();
myQuery.setFilterById(myDownloadReference);
Cursor myDownload = downloadManager.query(myQuery);
if (myDownload.moveToFirst()) {
//获取文件名&&下载到的本地路径对应的key
int fileNameIdx = myDownload.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
int fileUriIdx = myDownload.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);
//获取文件名&&下载到的本地路径
String fileName = myDownload.getString(fileNameIdx);
String fileUri = myDownload.getString(fileUriIdx);
Log.d(TAG, fileName);
Log.d(TAG, fileUri);
String filePath = fileUri.substring("file://".length());
imageView.setImageBitmap(BitmapFactory.decodeFile(filePath));
}
myDownload.close();
还可以通过
myQuery.setFilterById(DownloadManager.STATUS_PAUSED);
查询暂停下载的文件,设置可以分析一下原因哦
获取文件下载暂停的原因
1.下载文件,这里故意制造一个小问题,我们偏偏使用4g网络
//设置条件为,仅仅在wifi下下载
downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
request = new DownloadManager.Request(Uri.parse(URL_IMAGE0));
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
myDownloadReference = downloadManager.enqueue(request);
2.对文件没有下载的原因进行分析
//获取下载暂停的原因
DownloadManager.Query query = new DownloadManager.Query();
// 注意,使用DownloadManager.STATUS_PAUSED字段进行过滤时,无效 query.setFilterById(DownloadManager.STATUS_PAUSED);
query.setFilterById(myDownloadReference);
Cursor myDownload = downloadManager.query(query);
while (myDownload.moveToNext()) {
int failReasonIdIndix = myDownload.getColumnIndex(DownloadManager.COLUMN_REASON);
int titleIdIndex = myDownload.getColumnIndex(DownloadManager.COLUMN_TITLE);
int downloadedIdIndex = myDownload.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
int totalIdIndex = myDownload.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
int failReason = myDownload.getInt(failReasonIdIndix);
String titleSting = myDownload.getString(titleIdIndex);
int downloadedSize = myDownload.getInt(downloadedIdIndex);
int totalSize = myDownload.getInt(totalIdIndex);
Log.d(TAG, "" + failReason);
Log.d(TAG, titleSting);
Log.d(TAG, "" + downloadedSize);
Log.d(TAG, "" + totalSize);
switch (failReason) {
case DownloadManager.PAUSED_WAITING_FOR_NETWORK:
Log.d(TAG, "reason wait for connectivity");
break;
case DownloadManager.PAUSED_QUEUED_FOR_WIFI:
Log.d(TAG, "reason wait for wifi");
break;
case DownloadManager.PAUSED_WAITING_TO_RETRY:
Log.d(TAG, "reason wait for retry");
}
}
}
ok!