本文地址:http://blog.csdn.net/whyrjj3/article/details/8000740
在android2.3及以后,系统把内部的下载程序开放出来了。让我们可以使用DownloadManager这个类了。使用方法如下:
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); Uri uri = Uri.parse("fileUrl"); Request request = new Request(uri); //设置允许使用的网络类型,这里是移动网络和wifi都可以 request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE|DownloadManager.Request.NETWORK_WIFI); //禁止发出通知,既后台下载,如果要使用这一句必须声明一个权限:android.permission.DOWNLOAD_WITHOUT_NOTIFICATION //request.setShowRunningNotification(false); //不显示下载界面 request.setVisibleInDownloadsUi(false); /*设置下载后文件存放的位置,如果sdcard不可用,那么设置这个将报错,因此最好不设置如果sdcard可用,下载后的文件 在/mnt/sdcard/Android/data/packageName/files目录下面,如果sdcard不可用,设置了下面这个将报错,不设置,下载后的文件在/cache这个 目录下面*/ //request.setDestinationInExternalFilesDir(this, null, "tar.apk"); long id = downloadManager.enqueue(request); //TODO 把id保存好,在接收者里面要用,最好保存在Preferences里面
这里注意的是这时候程序就必须至少声明两个权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
用这个方法有好处,用户可以控制下载的过程,即如果没有下载完,并且不想下载了,可以终止下载,并且可以注册一个广播接收者,如果文件一下载完,就可以接收到一个广播。然后可以得到下载后的文件的路径:
package cn.dotcreate.testProcess; import android.app.DownloadManager; import android.app.DownloadManager.Query; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.widget.Toast; public class CompleteReceiver extends BroadcastReceiver { private DownloadManager downloadManager; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) { Toast.makeText(context, "下载完成了....", Toast.LENGTH_LONG).show(); long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0); //TODO 判断这个id与之前的id是否相等,如果相等说明是之前的那个要下载的文件 Query query = new Query(); query.setFilterById(id); downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); Cursor cursor = downloadManager.query(query); int columnCount = cursor.getColumnCount(); String path = null; //TODO 这里把所有的列都打印一下,有什么需求,就怎么处理,文件的本地路径就是path while(cursor.moveToNext()) { for (int j = 0; j < columnCount; j++) { String columnName = cursor.getColumnName(j); String string = cursor.getString(j); if(columnName.equals("local_uri")) { path = string; } if(string != null) { System.out.println(columnName+": "+ string); }else { System.out.println(columnName+": null"); } } } cursor.close(); //如果sdcard不可用时下载下来的文件,那么这里将是一个内容提供者的路径,这里打印出来,有什么需求就怎么样处理 if(path.startsWith("content:")) { cursor = context.getContentResolver().query(Uri.parse(path), null, null, null, null); columnCount = cursor.getColumnCount(); while(cursor.moveToNext()) { for (int j = 0; j < columnCount; j++) { String columnName = cursor.getColumnName(j); String string = cursor.getString(j); if(string != null) { System.out.println(columnName+": "+ string); }else { System.out.println(columnName+": null"); } } } cursor.close(); } }else if(action.equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)) { Toast.makeText(context, "点击通知了....", Toast.LENGTH_LONG).show(); } } }
在清单里面注册当前这个receiver:
<receiver android:name=".CompleteReceiver"> <intent-filter> <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/> <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED"/> </intent-filter> </receiver>