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;
        }
        @Override
        public Object getUserTag() {
            if (baseCallBack == null)
                return null;
            return baseCallBack.getUserTag();
        }
        @Override
        public void setUserTag(Object userTag) {
            if (baseCallBack == null)
                return;
            baseCallBack.setUserTag(userTag);
        }
        @Override
        public 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();
            }
        }
        @Override
        public 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();
            }
        }
        @Override
        public 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);
            }
        }
        @Override
        public 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);
            }
        }
        @Override
        public 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 implements
            ColumnConverter<HttpHandler.State> {
        @Override
        public HttpHandler.State getFieldValue(Cursor cursor, int index) {
            return HttpHandler.State.valueOf(cursor.getInt(index));
        }
        @Override
        public HttpHandler.State getFieldValue(String fieldStringValue) {
            if (fieldStringValue == null)
                return null;
            return HttpHandler.State.valueOf(fieldStringValue);
        }
        @Override
        public Object fieldValue2ColumnValue(HttpHandler.State fieldValue) {
            return fieldValue.value();
        }
        @Override
        public 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>