首先我们要有以下权限,这个是要求能够上网:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
如何开始下载
现在开始进行下载,按照以下步骤
1.获得DownloadManager的实例,使用getSystemService就可以了,不用自己new,既可以放在UI线程,也可以放在新线程
2.配置DownloadManager.Request ,具体看下面的代码,就是一个简单的参数设置
我的DOWNLOAD_LINK就是下载的String地址;
setDestinationInExternalPublicDic这个就是在/mnt/sdcard 下建立文件夹“Konachan”,里面的文件叫做“image.getTags() + ".jpeg”
setMimeType为打开方式,上网搜索“MimeType表”即可
其余的自行查询API,基本用的不多
3.开始下载 downloadManager.enqueue(request),它的返回值是一个下载ID,下面的接受广播,查询下载都要需要它
所有代码如下:
DownloadManager downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DOWNLOAD_LINK))
.setDestinationInExternalPublicDir("Konachan", image.getTags() + ".jpeg")
.setTitle("title")
.setDescription("下载到SD卡啦")
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI)
.setMimeType("image/jpeg");
final long downloadid = downloadManager.enqueue(request);
如何查询下载进度
这个利用DownloadManager提供的Uri,用ContentObserver进行不断的查询监控,步骤如下:
1.获得ContentResolver,注册ContentObserver ,参数如下
Uri.prase("content://downloads/") 这个地方不用动了
true : 是否查询子元素,这个地方也不用动了,因为我们要查询“downloads”的子元素
ContentObserver: 这个是我构造的一个DownloadObserver,详见下面
getContentResolver().registerContentObserver(Uri.parse("content://downloads/"),true,new DownloadObserver(handler,MyActivity.this,downloadid));
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));
//TODO:handler.sendMessage(xxxx),这样就可以更新UI了
}
}
}
如何下载完成自动打开
自动打开的实质就接受“下载完成”的广播,所以要重写一个BroadcastReceiver,步骤如下:
1.重写onReceive,代码就是判断广播是否为当前ID,然后启动intent
public class DownloadReceiver extends BroadcastReceiver {
final static String MINETYPE = "image/jpeg";
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
long downId = bundle.getLong(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
Log.w(getClass().getSimpleName(),String.valueOf(downId));
DownloadManager downloadManager = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);
Uri filepath = downloadManager.getUriForDownloadedFile(downId);
Log.w(getClass().getSimpleName(),filepath.toString());
if (intent.getAction() == DownloadManager.ACTION_DOWNLOAD_COMPLETE){
//start the activity in new task opening the picture
Intent activityIntent = new Intent(Intent.ACTION_VIEW);
activityIntent.setDataAndType(filepath, MINETYPE);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(activityIntent);
} catch (ActivityNotFoundException ex) {
Log.d(getClass().getName(), "no activity for " + MINETYPE, ex);
}
} else if (intent.getAction().equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)){
try {
Intent dm = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
dm.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(dm);
} catch (ActivityNotFoundException ex){
Log.d(getClass().getName(), "no activity for " + MINETYPE, ex);
}
}
}
}
2.注册AndroidMainFest.xml ,name对应的是刚才的DownloadReceiver的位置
<receiver android:name="com.github.miao1007.konakanwallpaper.receiver.DownloadReceiver" >
<intent-filter>
<!--监听下载完成的那一瞬间-->
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>
3.全部完成,广播接受不需要在Activity中加东西,只用静态注册即可,其生命由系统自动控制
------END