迩来做SDK开发,有个简朴的下载功能,为了方便及不增长第三方库,遂采取了体系的DownloadManager来处理下载任务。
官网的分析:
The download manager is a system service that handles long-running HTTP downloads. Clients may request that a URI be downloaded to a particular destination file. The download manager will conduct the download in the background, taking care of HTTP interactions and retrying downloads after failures or across connectivity changes and system reboots.
Apps that request downloads through this API should register a broadcast receiver for ACTION_NOTIFICATION_CLICKED to appropriately handle when the user clicks on a running download in a notification or from the downloads UI.
Note that the application must have the Manifest.permission.INTERNET permission to use this class.
Instances of this class must be obtained using Context.getSystemService(Class) with the argument DownloadManager.class or Context.getSystemService(String) with the argument Context.DOWNLOAD_SERVICE.
下载状态:
DownloadManager.STATUS_PAUSED:下载停息DownloadManager.STATUS_PENDING:下载耽误DownloadManager.STATUS_RUNNING:正在下载DownloadManager.STATUS_SUCCESSFUL:下载完成DownloadManager.STATUS_FAILED:下载失败文件信息:
DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR:已下载文件巨细DownloadManager.COLUMN_TOTAL_SIZE_BYTES:文件总巨细广播:
DownloadManager.ACTION_NOTIFICATION_CLICKED:下载关照点击事件广播末了代码如下
public class DownloadHelper { private static final String TAG = "DownloadHelper"; private boolean debug = false; private Context context; /** * 体系下载管理器 */ private DownloadManager mDownloadManager; /** * 下载ID */ private long mDownloadId; /** * 文件名 */ private String fileName; /** * 文件下载地址 */ private String downloadUrl; private boolean downloading; /** * 关照栏点击事件,点击进入下载详情 */ private BroadcastReceiver mDownloadDetailsReceiver; private final Runnable mQueryProgressRunnable = new Runnable() { @Override public void run() { queryProgress(); if (downloading) { mHandler.postDelayed(mQueryProgressRunnable, 1000); } } }; private final Handler mHandler = new Handler(Looper.getMainLooper()); private DownloadListener downloadListener; public interface DownloadListener { void onStart(); void onProgress(long soFarSize, long totalSize); void onFinish(String fileFullPath, long totalSize); void onFailed(); } public void setDownloadListener(DownloadListener listener) { this.downloadListener = listener; } private DownloadHelper(Context context, String fileName, String downloadUrl) { this.context = context; this.fileName = fileName; this.downloadUrl = downloadUrl; } public static DownloadHelper getInstance(Context context, String fileName, String downloadUrl) { DownloadHelper helper = new DownloadHelper(context, fileName, downloadUrl); helper.registerReceiver(); return helper; } /** * 注册广播 */ private void registerReceiver() { mDownloadDetailsReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(action)) { showDownloadList(); } } }; context.registerReceiver(mDownloadDetailsReceiver, new IntentFilter(DownloadManager.ACTION_NOTIFICATION_CLICKED)); } /** * 表现下载列表 */ public void showDownloadList() { Intent downloadIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS); if (downloadIntent.resolveActivity(context.getPackageManager()) != null) { context.startActivity(downloadIntent); } } /** * 开始下载 */ public void startDownload(String mimeType) { if (downloadListener != null) downloadListener.onStart(); mDownloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadUrl)); request..setAllowedOverMetered(true) .setAllowedOverRoaming(true) .setTitle("Downloading " + fileName) // 关照栏标题 .setMimeType(mimeType) .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)// .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName) .setDestinationInExternalFilesDir(ContextUtils.getContext(), Environment.DIRECTORY_DOWNLOADS, fileName) .allowScanningByMediaScanner(); try { mDownloadId = mDownloadManager.enqueue(request); // 参加下载队列 if (mDownloadId != 0) { startQueryProgress(); } } catch (IllegalArgumentException e) { if (downloadListener != null) downloadListener.onFailed(); // "更新失败", "请在设置中开启下载管理" Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + "com.android.providers.downloads")); if (intent.resolveActivity(context.getPackageManager()) != null) { context.startActivity(intent); } } } /** * 查询下载进度 */ private void queryProgress() { // 通过ID向下载管理查询下载环境,返回一个cursor Cursor c = mDownloadManager.query(new DownloadManager.Query().setFilterById(mDownloadId)); if (c != null && c.moveToFirst()) { int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)); logDebug("下载状态:" + status); switch (status) { case DownloadManager.STATUS_PAUSED: //下载停息, 由体系触发 case DownloadManager.STATUS_PENDING: //下载耽误, 由体系触发 break; case DownloadManager.STATUS_RUNNING: //正在下载, 由体系触发 long soFarSize = c.getLong(c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); long totalSize = c.getLong(c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); if (totalSize > 0) { logDebug(String.format("total:%s soFar:%s ", totalSize, soFarSize) + soFarSize * 1.0f / totalSize); if (downloadListener != null) { downloadListener.onProgress(soFarSize, totalSize); } } break; case DownloadManager.STATUS_SUCCESSFUL: //下载完成, 由体系触发 stopQueryProgress(); File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); totalSize = c.getLong(c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); if (downloadListener != null) { String fullName = downloadDir.getPath() + File.separator + fileName; logDebug(fullName); downloadListener.onFinish(fullName, totalSize); } break; case DownloadManager.STATUS_FAILED: //下载失败, 由体系触发 if (downloadListener != null) downloadListener.onFailed(); break; } } else { stopQueryProgress(); if (downloadListener != null) downloadListener.onFailed(); } closeCursor(c); } private void closeCursor(Cursor cursor) { if (cursor != null && !cursor.isClosed()) { cursor.close(); } } private void logDebug(String msg) { if (debug) { Log.e(TAG, msg); } } /** * 移除下载并删除下载文件 */ public void removeDownload() { mDownloadManager.remove(mDownloadId); stopQueryProgress(); } /** * 开始查询下载进度 */ private void startQueryProgress() { downloading = true; mHandler.post(mQueryProgressRunnable); } /** * 制止查询下载进度 */ private void stopQueryProgress() { downloading = false; mHandler.removeCallbacks(mQueryProgressRunnable); } public boolean isDownloading() { return downloading; } public void onDestroy() { try { stopQueryProgress(); //制止查询下载进度 context.unregisterReceiver(mDownloadDetailsReceiver); } catch (Exception ex) { //java.lang.IllegalArgumentException: Receiver not registered: } }} |