«

android 下载管理器

时间:2024-3-2 17:47     作者:韩俊     分类: 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;
        }

        @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>



标签: android

热门推荐