package com.dh.foundation.utils.download; import android.app.DownloadManager; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.provider.MediaStore; import com.dh.foundation.app.ApplicationUtil; import com.dh.foundation.manager.FoundationManager; import com.dh.foundation.observer.DownloadChangeObserver; import com.dh.foundation.receiver.DownloadCompleteReceiver; import com.dh.foundation.utils.DLoggerUtils; import com.dh.foundation.utils.StringUtils; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * 下载工具类 * Created By: Seal.Wu * Date: 2015/8/28 * Time: 18:08 */ public class DownLoadUtil implements Handler.Callback { public final static String OBSERVE_CHANGE_HANDLER = "observeChangeHandler"; public final static String DOWNLOAD_COMPLETE_HANDLER = "downloadCompleteHandler"; public final static String DOWNLOAD_DIR; private final static DownloadManager downloadManager = FoundationManager.getDownloadManager(); private Handler observeChangeHandler = new Handler(Looper.getMainLooper(), this); private Handler downloadCompleteHandler = new Handler(Looper.getMainLooper(), this); private Map<Long, DownloadListener> listenerMap = new HashMap<>(); static { DOWNLOAD_DIR = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ? Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + ApplicationUtil.getAppName() : Environment.getDownloadCacheDirectory().getAbsolutePath() + "/" + ApplicationUtil.getAppName(); } { FoundationManager.getHandleManager().registerHandler(OBSERVE_CHANGE_HANDLER, observeChangeHandler); FoundationManager.getHandleManager().registerHandler(DOWNLOAD_COMPLETE_HANDLER, downloadCompleteHandler); } private final static DownLoadUtil instance = new DownLoadUtil(); private DownLoadUtil() { } public static DownLoadUtil getInstance() { return instance; } @Override public boolean handleMessage(Message msg) { switch (msg.what) { case DownloadCompleteReceiver.DOWNLOAD_COMPLETE: long completeDownloadId = (long) msg.obj; DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(completeDownloadId); Cursor cursor = downloadManager.query(query); cursor.moveToFirst(); if (StringUtils.isNotEmpty(cursor.getColumnName(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE)))) { try { downloadManager.openDownloadedFile(completeDownloadId); } catch (FileNotFoundException e) { DLoggerUtils.e(e); } } int fileUriIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI); String fileUriName = cursor.getString(fileUriIndex); DownloadListener completeListener = listenerMap.get(completeDownloadId); if (completeListener != null) { completeListener.onComplete(completeDownloadId, getRealFilePath(FoundationManager.getContext(), Uri.parse(fileUriName))); listenerMap.remove(completeDownloadId); } cursor.close(); break; default: long downloadId = DownloadChangeObserver.getDownloadId(msg.what); DownloadListener listener = listenerMap.get(downloadId); if (listener != null) { listener.onLoadChange(msg.arg2, msg.arg1, (Integer) msg.obj); } break; } return true; } /** * 启动一个下载任务 * * @param url 待下载文件的地址 * @param downloadListener 下载监听器 * @return 下载任务的标识唯一id */ public long startADownloadTask(String url, DownloadListener downloadListener) { return startADownloadTask(url, null, null, null, false, downloadListener); } /** * 启动一个下载任务 * * @param url 待下载文件的地址 * @param title 若显示通知栏,则对应通知栏的标题 * @param description 若显示通知栏,则对应通知栏的描述 * @param mimeType 文件打开类型 * @param notificationVisibility 是否显示在通知栏及其它下载应用中 * @param downloadListener 下载监听器 * @return 下载任务的标识唯一id */ public long startADownloadTask(String url, String title, String description, String mimeType, boolean notificationVisibility, DownloadListener downloadListener) { Uri uri = Uri.parse(url); // uri 是你的下载地址,可以使用Uri.parse("http://")包装成Uri对象 DownloadManager.Request req = new DownloadManager.Request(uri); // 通过setAllowedNetworkTypes方法可以设置允许在何种网络下下载, // 也可以使用setAllowedOverRoaming方法,它更加灵活 req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); if (notificationVisibility) { // 此方法表示在下载过程中通知栏会一直显示该下载,在下载完成后仍然会显示, // 直到用户点击该通知或者消除该通知。还有其他参数可供选择 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); } else { req.setVisibleInDownloadsUi(false); } // 设置下载文件存放的路径,同样你可以选择以下方法存放在你想要的位置。 // setDestinationUri // setDestinationInExternalPublicDir // req.setDestinationInExternalFilesDir(FoundationManager.getContext(), Environment.DIRECTORY_DOWNLOADS, ApplicationUtil.getAppName()); req.setDestinationUri(Uri.fromFile(getFile(url))); req.setTitle(title); req.setDescription(description); req.setMimeType(mimeType); // Ok go! long downloadId = downloadManager.enqueue(req); if (downloadListener != null) { DownloadChangeObserver.registerDownloadTask(downloadId); listenerMap.put(downloadId, downloadListener); DownloadCompleteReceiver.registerDownloadTask(downloadId); } else if (StringUtils.isNotEmpty(mimeType)) { DownloadCompleteReceiver.registerDownloadTask(downloadId); } return downloadId; } /** * 离开当前activity的时候记得要调用 * * @param downloadId 下载任务的标识唯一id */ public void leaveActivity(long downloadId) { listenerMap.remove(downloadId); } /** * 取消结束当前的下载任务 * * @param downloadId 下载任务的标识唯一id */ public void cancelTask(long downloadId) { downloadManager.remove(downloadId); } // /** // * 重新尝试再次开启任务 // * // * @param downloadId 下载任务的标识唯一id // */ // public void retryTask(long downloadId) { // // downloadManager.restartDownload(downloadId); // } public static File getFile(String url) { File dir = new File(DOWNLOAD_DIR); if (!dir.exists()) { if (!dir.mkdirs()) { throw new RuntimeException("不能创建目录:" + DOWNLOAD_DIR); } } File realFile = new File(dir, url.substring(url.lastIndexOf("/"))); if (!realFile.exists()) { try { if (!realFile.createNewFile()) { throw new RuntimeException("不能创建文件:" + realFile.getAbsolutePath()); } } catch (IOException e) { DLoggerUtils.e(e); } } return realFile; } /** * Try to return the absolute file path from the given Uri * * @param context * @param uri * @return the file path or null */ public static String getRealFilePath(final Context context, final Uri uri) { if (null == uri) return null; final String scheme = uri.getScheme(); String data = null; if (scheme == null) data = uri.getPath(); else if (ContentResolver.SCHEME_FILE.equals(scheme)) { data = uri.getPath(); } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) { Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null); if (null != cursor) { if (cursor.moveToFirst()) { int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); if (index > -1) { data = cursor.getString(index); } } cursor.close(); } } return data; } }