android 下载管理器
android 自带了下载管理器,我们可以获取到下载的进度大小以及下载完成等等的状态,但是android自带的DownLoadManager却没有实现比如暂停,继续等功能也就是不能断点续传,这几天在总下载管理器,写了以后总是 感觉还是不是太好,因为下载要考虑的情况是比较多的
1、我们要考虑下载的时候要有下载情况的回调,
2、下载的文件是否已经下载
3、是否已经下载完成
4、下载速度
5、下载的进度
6、下载的过程中暂停,继续,取消等操作
7、可能有些人还要把下载的列表分为a 已经下载完成 b 正在下载
8、还有要加下载完成的通知,或是提示
9、还有listView经常遇到的进度条显示错乱
等等。。。。上网查找了很多的资料,网上有现成的第三方DownloadProvider这个,功能相当的齐全,但是我还是希望自己能写一个
下边是我自己的实现思路
首先 1 、要有一个service 来进行后台下载
2、需要有一个存放下载信息的一个实体类downLoadInfo 包含下载的文件大小,每次下载的大小,下载的速度等
private long id;
@Transient
private HttpHandler<File> handler;
private HttpHandler.State state
private String downloadUrl;
private String fileName;
private String fileSavePath;
private long progress;
private long fileLength;
private boolean autoResume;
private boolean autoRename;
private float speed;
3、一个下载管理器;进行下载的管理,已经下载进度的回调
下载我使用的是第三方的xutils
4 、一个DownLoadAdapter用来给listView填充数据
整体来讲就是这么多。
下载管理器代码如下
package cn.com.huahuawifi.android.guest.download;import android.content.Context;import android.database.Cursor;import android.util.Log;import cn.com.huahuawifi.android.guest.util.Utils;import cn.com.huahuawifi.android.guest.util.XUtilsHttpUtil;import com.lidroid.xutils.DbUtils;import com.lidroid.xutils.HttpUtils;import com.lidroid.xutils.db.converter.ColumnConverter;import com.lidroid.xutils.db.converter.ColumnConverterFactory;import com.lidroid.xutils.db.sqlite.ColumnDbType;import com.lidroid.xutils.db.sqlite.Selector;import com.lidroid.xutils.exception.DbException;import com.lidroid.xutils.exception.HttpException;import com.lidroid.xutils.http.HttpHandler;import com.lidroid.xutils.http.HttpHandler.State;import com.lidroid.xutils.http.ResponseInfo;import com.lidroid.xutils.http.callback.RequestCallBack;import com.lidroid.xutils.util.LogUtils;import java.io.File;import java.util.ArrayList;import java.util.List;/** * 下载管理器 */public class DownloadManager {private List<DownloadInfo> downloadInfoList; // 下载列表private List<DownloadInfo> alreadyDownLoadList; // 已经下载完成的private List<DownloadInfo> downLoadingList; // 正在下载private int maxDownloadThread = 3; // 最大下载线程数private Context mContext;private DbUtils db;private long mLastTime;private long mLastFileSize;/* package */DownloadManager(Context appContext) {ColumnConverterFactory.registerColumnConverter(HttpHandler.State.class,new HttpHandlerStateConverter());mContext = appContext;db = DbUtils.create(mContext);alreadyDownLoadList = new ArrayList<DownloadInfo>();downLoadingList = new ArrayList<DownloadInfo>();try {downloadInfoList = db.findAll(Selector.from(DownloadInfo.class)); // 查询所有的下载} catch (DbException e) {LogUtils.e(e.getMessage(), e);}if (downloadInfoList == null) {downloadInfoList = new ArrayList<DownloadInfo>();} else {for (int i = 0; i < downloadInfoList.size(); i++) {if (downloadInfoList.get(i).getState().equals(com.lidroid.xutils.http.HttpHandler.State.SUCCESS)) {alreadyDownLoadList.add(downloadInfoList.get(i));} else {downLoadingList.add(downloadInfoList.get(i));}}}}public int getDownloadInfoListCount() {return downloadInfoList.size();}public DownloadInfo getDownloadInfo(int index) {return downloadInfoList.get(index);}public int getDownloadInfoLoadingCount() {return downLoadingList.size();}public List<DownloadInfo> getDownLoadingList() {return downLoadingList;}public DownloadInfo getDownLoadinginfo(int index) {downLoadingList.get(index);return downLoadingList.get(index);}public int getAlreadyDownLoadCount() {return alreadyDownLoadList.size();}public List<DownloadInfo> getAlreadyDownLoadList() {return alreadyDownLoadList;}public DownloadInfo getAlreadyDownLoadInfo(int index) {alreadyDownLoadList.get(index);return alreadyDownLoadList.get(index);}/** * 获取当前url的文件是否在下载列表里,或去的时候想确保把改下载添加到了下载列表中 * @param downloadUrl * @return */public DownloadInfo getDownLoadInfo(String downloadUrl){DownloadInfo downloadInfo =null;for (DownloadInfo doInfo : downloadInfoList) {if (doInfo.getDownloadUrl().equals(downloadUrl)) {downloadInfo =doInfo;return downloadInfo;}}return downloadInfo;}/** * 添加下载任务 * * @param url * 下载链接 * @param fileName * 文件名 * @param target * 文件存放路径 * @param autoResume * @param autoRename * @param callback * 回调 * @throws DbException */public void addNewDownload(String url, String fileName, String target,boolean autoResume, boolean autoRename,final RequestCallBack<File> callback) throws DbException {if (Utils.fileIsExists(target)) {// 下载文件已经存在不在添加下载任务} else {final DownloadInfo downloadInfo = new DownloadInfo();downloadInfo.setDownloadUrl(url);downloadInfo.setAutoRename(autoRename);downloadInfo.setAutoResume(autoResume);downloadInfo.setFileName(fileName);downloadInfo.setFileSavePath(target);HttpUtils http = new HttpUtils();http.configRequestThreadPoolSize(maxDownloadThread);HttpHandler<File> handler = http.download(url, target, autoResume,autoRename, new ManagerCallBack(downloadInfo, callback));downloadInfo.setHandler(handler);downloadInfo.setState(handler.getState());downloadInfoList.add(downloadInfo);db.saveBindingId(downloadInfo);}}public void resumeDownload(int index, final RequestCallBack<File> callback)throws DbException {final DownloadInfo downloadInfo = downloadInfoList.get(index);resumeDownload(downloadInfo, callback);}/** * 重新下载 * * @param downloadInfo * downLoadinfo信息 * @param callback * 回调 * @throws DbException */public void resumeDownload(DownloadInfo downloadInfo,final RequestCallBack<File> callback) throws DbException {HttpUtils http = new HttpUtils();http.configRequestThreadPoolSize(maxDownloadThread);HttpHandler<File> handler = http.download(downloadInfo.getDownloadUrl(), downloadInfo.getFileSavePath(),downloadInfo.isAutoResume(), downloadInfo.isAutoRename(),new ManagerCallBack(downloadInfo, callback));downloadInfo.setHandler(handler);downloadInfo.setState(handler.getState());db.saveOrUpdate(downloadInfo);}/** * 移除下载任务 * * @param index * 要移除的下表 * @throws DbException */public void removeDownload(int index) throws DbException {DownloadInfo downloadInfo = downloadInfoList.get(index);removeDownload(downloadInfo);}/** * 移除下载任务 * * @param downloadInfo * 下载的downloadInfo对象 * @throws DbException */public void removeDownload(DownloadInfo downloadInfo) throws DbException {HttpHandler<File> handler = downloadInfo.getHandler();if (handler != null && !handler.isCancelled()) {handler.cancel();}downloadInfoList.remove(downloadInfo);downLoadingList.remove(downloadInfo);alreadyDownLoadList.remove(downloadInfo);db.delete(downloadInfo);}public void removeAlreadyDownLoad(DownloadInfo downloadInfo) throws DbException{HttpHandler<File> handler = downloadInfo.getHandler();if (handler != null && !handler.isCancelled()) {handler.cancel();}alreadyDownLoadList.remove(downloadInfo);Utils.deleteFile(downloadInfo.getFileSavePath());db.delete(downloadInfo);}/** * 停止下载 * * @param index * 下载的下表 * @throws DbException */public void stopDownload(int index) throws DbException {DownloadInfo downloadInfo = downloadInfoList.get(index);stopDownload(downloadInfo);}/** * 停止下载 * * @param downloadInfo * 下载的downloadInfo对象 * @throws DbException */public void stopDownload(DownloadInfo downloadInfo) throws DbException {HttpHandler<File> handler = downloadInfo.getHandler();if (handler != null && !handler.isCancelled()) {handler.cancel();} else {downloadInfo.setState(HttpHandler.State.CANCELLED);}db.saveOrUpdate(downloadInfo);}/** * 停止所有的下载任务 * * @throws DbException */public void stopAllDownload() throws DbException {for (DownloadInfo downloadInfo : downloadInfoList) {HttpHandler<File> handler = downloadInfo.getHandler();if (handler != null && !handler.isCancelled()) {handler.cancel();} else {downloadInfo.setState(HttpHandler.State.CANCELLED);}}db.saveOrUpdateAll(downloadInfoList);}/** * 改变数据库中下载状态 * * @throws DbException */public void backupDownloadInfoList() throws DbException {for (DownloadInfo downloadInfo : downloadInfoList) {HttpHandler<File> handler = downloadInfo.getHandler();if (handler != null) {switch (handler.getState()) {case WAITING:downloadInfo.setState(State.CANCELLED);break;case SUCCESS:break;case FAILURE:break;case LOADING:downloadInfo.setState(State.CANCELLED);break;case CANCELLED:downloadInfo.setState(State.CANCELLED);break;case STARTED:downloadInfo.setState(State.CANCELLED);break;default:break;}}}db.saveOrUpdateAll(downloadInfoList);}public int getMaxDownloadThread() {return maxDownloadThread;}/** * 设置最大下载线程 * * @param maxDownloadThread */public void setMaxDownloadThread(int maxDownloadThread) {this.maxDownloadThread = maxDownloadThread;}public class ManagerCallBack extends RequestCallBack<File> {private DownloadInfo downloadInfo;private RequestCallBack<File> baseCallBack;public RequestCallBack<File> getBaseCallBack() {return baseCallBack;}public void setBaseCallBack(RequestCallBack<File> baseCallBack) {this.baseCallBack = baseCallBack;}private ManagerCallBack(DownloadInfo downloadInfo,RequestCallBack<File> baseCallBack) {this.baseCallBack = baseCallBack;this.downloadInfo = downloadInfo;}@Overridepublic Object getUserTag() {if (baseCallBack == null)return null;return baseCallBack.getUserTag();}@Overridepublic void setUserTag(Object userTag) {if (baseCallBack == null)return;baseCallBack.setUserTag(userTag);}@Overridepublic void onStart() {HttpHandler<File> handler = downloadInfo.getHandler();if (handler != null) {downloadInfo.setState(handler.getState());}try {db.saveOrUpdate(downloadInfo);if (downLoadingList.size() == 0) {downLoadingList.add(downloadInfo);}} catch (DbException e) {LogUtils.e(e.getMessage(), e);}if (baseCallBack != null) {baseCallBack.onStart();}}@Overridepublic void onCancelled() {HttpHandler<File> handler = downloadInfo.getHandler();if (handler != null) {downloadInfo.setState(handler.getState());}try {db.saveOrUpdate(downloadInfo);} catch (DbException e) {LogUtils.e(e.getMessage(), e);}if (baseCallBack != null) {baseCallBack.onCancelled();}}@Overridepublic void onLoading(long total, long current, boolean isUploading) {HttpHandler<File> handler = downloadInfo.getHandler();if (handler != null) {downloadInfo.setState(handler.getState());}long nowTime = System.currentTimeMillis();Log.e("SPEED1", nowTime + "");Log.e("SPEED2", mLastTime + "");Log.e("SPEED1_file", current + "");Log.e("SPEED2_file", mLastFileSize + "");float speed = 0;float speedContent = current - mLastFileSize;float speedTimer = nowTime - mLastTime;if (mLastTime > 0 && current != 0) {if (speedContent >= 1024) {speedContent = (float) ((speedContent) / (1024 + 0.0));speedContent = (float) (((int) (speedContent * 10) % 10 + 0.0) / 10 + (int) speedContent);speedTimer = (float) ((speedTimer) / (1000 + 0.0));speed = speedContent / speedTimer;}Log.e("SPEED", speed + "");}mLastTime = nowTime;mLastFileSize = current;downloadInfo.setSpeed(speed);downloadInfo.setFileLength(total);downloadInfo.setFileAllSize(((float) total) / ((float) 1048576));;downloadInfo.setProgress(current);try {db.saveOrUpdate(downloadInfo);} catch (DbException e) {LogUtils.e(e.getMessage(), e);}if (baseCallBack != null) {baseCallBack.onLoading(total, current, isUploading);}}@Overridepublic void onSuccess(ResponseInfo<File> responseInfo) {HttpHandler<File> handler = downloadInfo.getHandler();if (handler != null) {downloadInfo.setState(handler.getState());downLoadingList.remove(downloadInfo);alreadyDownLoadList.add(downloadInfo);}try {db.saveOrUpdate(downloadInfo);} catch (DbException e) {LogUtils.e(e.getMessage(), e);}if (baseCallBack != null) {baseCallBack.onSuccess(responseInfo);}}@Overridepublic void onFailure(HttpException error, String msg) {HttpHandler<File> handler = downloadInfo.getHandler();if (handler != null) {downloadInfo.setState(handler.getState());}try {db.saveOrUpdate(downloadInfo);} catch (DbException e) {LogUtils.e(e.getMessage(), e);}if (baseCallBack != null) {baseCallBack.onFailure(error, msg);}}}private class HttpHandlerStateConverter implementsColumnConverter<HttpHandler.State> {@Overridepublic HttpHandler.State getFieldValue(Cursor cursor, int index) {return HttpHandler.State.valueOf(cursor.getInt(index));}@Overridepublic HttpHandler.State getFieldValue(String fieldStringValue) {if (fieldStringValue == null)return null;return HttpHandler.State.valueOf(fieldStringValue);}@Overridepublic Object fieldValue2ColumnValue(HttpHandler.State fieldValue) {return fieldValue.value();}@Overridepublic ColumnDbType getColumnDbType() {return ColumnDbType.INTEGER;}}}
DownLoadInfo
<span style="font-size:10px;">package cn.com.huahuawifi.android.guest.download;import com.lidroid.xutils.db.annotation.Transient;import com.lidroid.xutils.http.HttpHandler;import java.io.File;public class DownloadInfo { public DownloadInfo() { } private long id; @Transient private HttpHandler<File> handler; private HttpHandler.State state; private String downloadUrl; private String fileName; private String fileSavePath; private long progress; //下载的长度 private long fileLength; //文件的总长度 private boolean autoResume; private boolean autoRename; private float speed; private float fileAllSize; public float getFileAllSize() {return fileAllSize;}public void setFileAllSize(float fileAllSize) {this.fileAllSize = fileAllSize;}public float getSpeed() {return speed;}public void setSpeed(float speed) {this.speed = speed;}public long getId() { return id; } public void setId(long id) { this.id = id; } public HttpHandler<File> getHandler() { return handler; } public void setHandler(HttpHandler<File> handler) { this.handler = handler; } public HttpHandler.State getState() { return state; } public void setState(HttpHandler.State state) { this.state = state; } public String getDownloadUrl() { return downloadUrl; } public void setDownloadUrl(String downloadUrl) { this.downloadUrl = downloadUrl; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public String getFileSavePath() { return fileSavePath; } public void setFileSavePath(String fileSavePath) { this.fileSavePath = fileSavePath; } public long getProgress() { return progress; } public void setProgress(long progress) { this.progress = progress; } public long getFileLength() { return fileLength; } public void setFileLength(long fileLength) { this.fileLength = fileLength; } public boolean isAutoResume() { return autoResume; } public void setAutoResume(boolean autoResume) { this.autoResume = autoResume; } public boolean isAutoRename() { return autoRename; } public void setAutoRename(boolean autoRename) { this.autoRename = autoRename; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof DownloadInfo)) return false; DownloadInfo that = (DownloadInfo) o; if (id != that.id) return false; return true; } @Override public int hashCode() { return (int) (id ^ (id >>> 32)); }}</span><span style="font-size:18px;font-weight: bold;"></span>
下载的service
<span style="font-size:10px;">package cn.com.huahuawifi.android.guest.download;import android.app.ActivityManager;import android.app.Service;import android.content.Context;import android.content.Intent;import android.os.IBinder;import com.lidroid.xutils.exception.DbException;import com.lidroid.xutils.util.LogUtils;import java.util.List;public class DownloadService extends Service { private static DownloadManager DOWNLOAD_MANAGER; public static DownloadManager getDownloadManager(Context appContext) { if (!DownloadService.isServiceRunning(appContext)) { Intent downloadSvr = new Intent("download.service.action"); appContext.startService(downloadSvr); } if (DownloadService.DOWNLOAD_MANAGER == null) { DownloadService.DOWNLOAD_MANAGER = new DownloadManager(appContext); } return DOWNLOAD_MANAGER; } public DownloadService() { super(); } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); } @Override public void onDestroy() { if (DOWNLOAD_MANAGER != null) { try { DOWNLOAD_MANAGER.stopAllDownload(); DOWNLOAD_MANAGER.backupDownloadInfoList(); } catch (DbException e) { LogUtils.e(e.getMessage(), e); } } super.onDestroy(); } public static boolean isServiceRunning(Context context) { boolean isRunning = false; ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningServiceInfo> serviceList = activityManager.getRunningServices(Integer.MAX_VALUE); if (serviceList == null || serviceList.size() == 0) { return false; } for (int i = 0; i < serviceList.size(); i++) { if (serviceList.get(i).service.getClassName().equals(DownloadService.class.getName())) { isRunning = true; break; } } return isRunning; }}</span><span style="font-size:18px;font-weight: bold;"></span>
更多相关文章
- Android中自定义SeekBar的背景颜色,进度条颜色,以及滑块的图片
- 批量处理ios破解后的资源文件为android所用
- Android中的R.java文件你知多少
- 如何给你的Android 安装文件(APK)瘦身(一)
- 在Android使用XML文件控制按钮文字在各种状态下的颜色