android 多线程下载器 源码解析

               以前一直没有时间整理自己封装的类库。本篇博文跟大家介绍下之前自己写的一款android 平台的下载器。

               先介绍下下载器实现的功能,多线程下载,断点续传,多任务通知栏排队下载,wifi 拉包,联网自动恢复下载任务,非wifi 状态预定下载任务,定期清理下载缓存,多数据库存储之间的数据迁移。

              demo 的运行效果。

            

demo 代码解读

首先先分析下demo 的代码:

       

package com.downloader.sdk.dlplugin.demo;


import android.app.Activity;
import android.net.Proxy;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;

import com.downloader.sdk.dlplugin.DownLoadCallback;
import com.downloader.sdk.dlplugin.DownloadManager;
import com.downloader.sdk.dlplugin.DownloadStrategy;
import com.downloader.sdk.dlplugin.DownloadTask;
import com.downloader.sdk.dlplugin.DownloadTaskStatus;
import com.downloader.sdk.dlplugin.demo.adapter.DownloadedListAdapter;
import com.downloader.sdk.dlplugin.demo.adapter.DownloadingListAdapter;
import com.downloader.sdk.dlplugin.demo.data.DownloadUrls;

import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;


public class DownLoadPluginActivtiy extends Activity {

    private Button addButton = null;
    private Button resetButton = null;
    private Button stopButton = null;
    private DownloadingListAdapter downloadListAdapter;
    private DownloadedListAdapter downloadedListAdapter;

    private int urlIndex = 0;


    //pageInditator

    private View v_downloading, v_downloaded;// 需要显示的View
    private ListView lv_downloading, lv_downloaded;
    private LinearLayout ll_downloading, ll_downloaded;
    private ViewPager viewPager;
    private TranslateAnimation transAnima;
    private ImageView indicator = null;
    private ArrayList<View> views;
    private int currentIndex = 0;
    int width;
    private DownloadManager downloadManager;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dlface);
        downloadManager = DownloadManager.getInstance(this);
        initView();

    }


    private void initView() {
        DisplayMetrics dms = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dms);
        width = dms.widthPixels / 2 - 50;
        indicator = (ImageView) findViewById(R.id.iv_line);
        LayoutInflater lf = getLayoutInflater().from(this);
        v_downloading = lf.inflate(R.layout.downloading_tab, null);
        v_downloaded = lf.inflate(R.layout.downloaded_tab, null);

        views = new ArrayList<View>();
        views.add(v_downloading);
        views.add(v_downloaded);

        ll_downloading = (LinearLayout) findViewById(R.id.ll_downloading);
        ll_downloaded = (LinearLayout) findViewById(R.id.ll_downloaded);

        ll_downloading.setOnClickListener(tabClickHandler);
        ll_downloaded.setOnClickListener(tabClickHandler);

        lv_downloading = (ListView) v_downloading.findViewById(R.id.lv_downloading);
        lv_downloaded = (ListView) v_downloaded.findViewById(R.id.lv_downloaded);


        downloadListAdapter = DownloadingListAdapter.getInstance().init(this, lv_downloading);
        downloadedListAdapter = DownloadedListAdapter.getInstance().init(this, lv_downloaded);

        lv_downloading.setAdapter(downloadListAdapter);
        lv_downloaded.setAdapter(downloadedListAdapter);

        addButton = (Button) v_downloading.findViewById(R.id.btn_add);
        resetButton = (Button) v_downloading.findViewById(R.id.btn_reset);

        addButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                /*
                 * 入口
             * 1、生成taskId
             * 2、插入数据库记录
             * 3、添加下载任务
             *
             */


                try {
                    JSONObject downloadSteategyJsonObj = new JSONObject();
                    downloadSteategyJsonObj.put(DownloadStrategy.SEGMENT_KEY, 5);
                    downloadSteategyJsonObj.put(DownloadStrategy.VISIBILITY_KEY, 0);
                    DownloadTask task = downloadManager.postTask(DownloadUrls.url[urlIndex], DownloadUrls.apkName[urlIndex], null, downloadSteategyJsonObj);
                    if (task != null && task.getId() >= 0 && task.getStatus() == DownloadTaskStatus.WAITING) {
                        downloadListAdapter.addItem(task.getId(), DownloadUrls.url[urlIndex], false);
                    }
                    urlIndex++;
                    downloadManager.setDownLoadCallback(new DownLoadCallback() {
                        @Override
                        public void onStart(long taskId, String url) {
                            super.onStart(taskId, url);
                            Log.e("YCW", "onStart-taskId--->" + taskId + ";url--->" + url);
                        }


                        @Override
                        public void onFailure(long taskId, String url, int erro) {
                            super.onFailure(taskId, url, erro);
                            Log.e("YCW", "onFailure-taskId--->" + taskId + ";url--->" + url);
                        }


                        @Override
                        public void onLoading(long taskId, String url, long totalSize, long currentSize, long speed, int percent) {
                            super.onLoading(taskId, url, totalSize, currentSize, speed, percent);
                            Log.e("YCW", "onLoading-taskId--->" + taskId + ";url--->" + url + ";percent--->" + percent);
                            downloadListAdapter.setDownLoaderProgress(url, totalSize, currentSize, speed);
                        }


                        @Override
                        public void onFinish(long taskId, String url) {
                            super.onFinish(taskId, url);
                            Log.e("YCW", "onFinish-taskId--->" + taskId + ";url--->" + url);
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }


            }
        });
        resetButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
        /*
          * 0、清空数据库
           * 1、清空队列
          * 2、重置url索引
           * 3、清空下载文件
           *
        */


                downloadListAdapter.reInit();
                downloadListAdapter = DownloadingListAdapter.getInstance().init(v.getContext(), lv_downloading);
                lv_downloading.setAdapter(downloadListAdapter);

                downloadManager.deleteAllHandler();

                downloadListAdapter.reInit();
                downloadedListAdapter.reset();

                deleteAllFiles(new File("/sdcard/adsagedlplugin/"));
                urlIndex = 0;
                long a = 10L;
                int bb = new Long(a).intValue();

                String proxyHost = Proxy.getHost(v.getContext());
                int proxyPort = Proxy.getPort(v.getContext());


            }
        });

        viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(new MyPageAdapter());

        viewPager.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int arg0) {

                initAnimation(arg0);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {


            }

            @Override
            public void onPageScrollStateChanged(int arg0) {


            }
        });
    }

    OnClickListener tabClickHandler = new OnClickListener() {
        @Override
        public void onClick(View v) {
            int tempIdx = 0;
            if (v == ll_downloading) {
                tempIdx = 0;
            } else if (v == ll_downloaded) {
                tempIdx = 1;
            }
            if (currentIndex != tempIdx) {
                initAnimation(tempIdx);
                viewPager.setCurrentItem(currentIndex);
            }
        }
    };

    private void initAnimation(int moveto) {
        transAnima = new TranslateAnimation(currentIndex * width, moveto
                * width, 0, 0);
        transAnima.setFillAfter(true);
        transAnima.setDuration(200);
        indicator.startAnimation(transAnima);
        currentIndex = moveto;
    }

    private void deleteAllFiles(File root) {
        File files[] = root.listFiles();
        if (files != null)
            for (File f : files) {
                if (f.isDirectory()) { // 判断是否为文件夹  
                    deleteAllFiles(f);
                    try {
                        f.delete();
                    } catch (Exception e) {
                    }
                } else {
                    if (f.exists()) { // 判断是否存在  
                        deleteAllFiles(f);
                        try {
                            f.delete();
                        } catch (Exception e) {
                        }
                    }
                }
            }
    }


    private class MyPageAdapter extends PagerAdapter {
        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            container.addView(views.get(position));
            return views.get(position);
        }

        @Override
        public int getCount() {

            return views.size();
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {

            return arg0 == arg1;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {

            container.removeView(views.get(position));
        }

        @Override
        public int getItemPosition(Object object) {

            return super.getItemPosition(object);
        }


    }
}

 

该demo 主要演示了如何获取DownLoadManager 的实例,如何设置回调监听,

 

downloadManager = DownloadManager.getInstance(this);

获取DownloadManager 实例。

 

JSONObject downloadSteategyJsonObj = new JSONObject();
downloadSteategyJsonObj.put(DownloadStrategy.SEGMENT_KEY, 5);
downloadSteategyJsonObj.put(DownloadStrategy.VISIBILITY_KEY, 0);
DownloadTask task = downloadManager.postTask(DownloadUrls.url[urlIndex], DownloadUrls.apkName[urlIndex], null, downloadSteategyJsonObj);

通过postTask 添加下载任务

 

 downloadManager.setDownLoadCallback(new DownLoadCallback() {
        @Override
        public void onStart(long taskId, String url) {
            super.onStart(taskId, url);
            Log.e("YCW", "onStart-taskId--->" + taskId + ";url--->" + url);
        }


        @Override
        public void onFailure(long taskId, String url, int erro) {
            super.onFailure(taskId, url, erro);
            Log.e("YCW", "onFailure-taskId--->" + taskId + ";url--->" + url);
        }


        @Override
        public void onLoading(long taskId, String url, long totalSize, long currentSize, long speed, int percent) {
            super.onLoading(taskId, url, totalSize, currentSize, speed, percent);
            Log.e("YCW", "onLoading-taskId--->" + taskId + ";url--->" + url + ";percent--->" + percent);
            downloadListAdapter.setDownLoaderProgress(url, totalSize, currentSize, speed);
        }


        @Override
        public void onFinish(long taskId, String url) {
            super.onFinish(taskId, url);
            Log.e("YCW", "onFinish-taskId--->" + taskId + ";url--->" + url);
        }
    });
} catch (Exception e) {
    e.printStackTrace();
}

设置回调监听。

onLoading 进度回调,onFinish 下载完成回调,onFailure 下载错误回调。

下载器的目录结构:

              

   下载器共包含32个类。

   DownLoaderManager 是下载器的对外接口类,和下载worker 工作队列,线程并发的处理类。

   DownLoadCallBack 下载器的下载监听回调

   DownLoadConfig  常量配置

   DownloadStrategy 下载策略,包括进度的部长,下载根目录,下载是否显示通知栏进度条等

   DownLoadTask   下载任务,数据库sqlite 的实体bean

 

DownloadTaskStatus  下载状态

   下面看着源码讲解下这个类:

 

package com.downloader.sdk.dlplugin;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.MimeTypeMap;
import android.widget.Toast;

import com.downloader.sdk.dlplugin.util.common.ApkUtil;
import com.downloader.sdk.dlplugin.util.common.FileInfoUtils;
import com.downloader.sdk.dlplugin.util.common.SdCardUtil;
import com.downloader.sdk.dlplugin.util.common.StringUtils;
import com.downloader.sdk.dlplugin.util.db.DBUtil;
import com.downloader.sdk.dlplugin.util.http.AsyncHttpClient;
import com.downloader.sdk.dlplugin.util.http.AsyncHttpResponseHandler;
import com.downloader.sdk.dlplugin.util.http.FileHttpResponseHandler;
import com.downloader.sdk.dlplugin.util.log.Logger;
import com.downloader.sdk.dlplugin.util.netstate.NetChangeObserver;
import com.downloader.sdk.dlplugin.util.netstate.NetWorkUtil;
import com.downloader.sdk.dlplugin.util.netstate.NetWorkUtil.netType;
import com.downloader.sdk.dlplugin.util.netstate.NetworkStateReceiver;
import com.downloader.sdk.dlplugin.util.notification.NotificationHelper;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.ProtocolException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.RedirectHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * @author ycw
 */

public class DownloadManager extends Thread {
    private HandlerQueue mhandlerQueue;// queue for waiting task
    private static List<AsyncHttpResponseHandler> mDownloadinghandlers;// store
    private static List<AsyncHttpResponseHandler> mPausinghandlers;// store
    private AsyncHttpClient mAsyncHttpClient;
    private Boolean isRunning = false;
    private DownLoadCallback mDownLoadCallback;
    private String mRootPath = "";
    // cache all realtime task status
    private ArrayList<DownloadTaskStatus> mDownloadTaskStatusData;
    private HashMap<Long, DownloadStrategy> mDownloadStrategyHashMap;

    private NotificationHelper mNotificationHelper;

    private Context mContext;
    private DBUtil mDbutil;
    private static DownloadManager mDownloadManager;
    private final static String TAG = "DownloadManager";
    public static final String NOTIFICATION_CLICK_ACTION = "com.downloader.notification_click_action";

    public static final String NOFINISH_NOTIFICATION_CLICK_ACTION = "com.downloader.notification_nofinishclick_action";

    private static BroadcastReceiver mNotifactionClickReceiver;

    private boolean mIsWorking = true;

    private static BroadcastReceiver sSdCardReceiver;
    private static String mDataBaseName;
    private static boolean mIsSaveOldData;
    private static int mDbHashCode;
    private static Handler myHandler;


    public static DownloadManager getInstance(Context context) {
        if (mDownloadManager == null) {
            mDownloadManager = new DownloadManager(context,
                    DownLoadConfig.FILE_ROOT, "mftour_download", false);
            mDataBaseName = "mftour_download";
        }
        return mDownloadManager;

    }

    /**
     * @param context
     * @param dataBaseName
     * @param downLoadPath
     * @param isSaveOldData
     * @return
     */
    public static DownloadManager getInstance(Context context,
                                              String dataBaseName, String downLoadPath, boolean isSaveOldData) {
        Logger.d(TAG, "getInstance(" + "context," + dataBaseName + "," + downLoadPath + ","
                + isSaveOldData + ")");
        if (!TextUtils.isEmpty(downLoadPath)) {
            DownLoadConfig.FILE_ROOT = downLoadPath;
        }

        if (mDownloadManager == null) {
            mDownloadManager = new DownloadManager(context,
                    DownLoadConfig.FILE_ROOT, dataBaseName, isSaveOldData);
            mDataBaseName = dataBaseName;
        }
        return mDownloadManager;
    }

    private DownloadManager(Context context, String rootPath, String dataBaseName,
                            boolean isSaveOldDataBase) {
        initParams(context, rootPath, dataBaseName, isSaveOldDataBase);
        // 获取cup颗数,动态设置并发数
        setWorkerCount();
        sSdCardReceiver = getSdReceiver();
        // 注册sd 监听器
        registerSdReceiver(sSdCardReceiver);
        // sd 卡监听
        // register network state receiver
        NetworkStateReceiver.registerNetworkStateReceiver(mContext);
        NetworkStateReceiver.registerObserver(new NetChangeObserver() {
            @SuppressWarnings("static-access")
            @Override
            public void onConnect(netType type) {
                mIsWorking = true;
                if (null != NetWorkUtil.getAPNType(mContext)
                        && NetWorkUtil.getAPNType(mContext) != type.wifi) {
                    // 说明是移动网络,延时,改变重试次数
                    if (mAsyncHttpClient != null) {
                        mAsyncHttpClient
                                .setTimeout(DownLoadConfig.unWifiTimeOut);
                    }

                } else {
                    if (mAsyncHttpClient != null) {
                        mAsyncHttpClient.setTimeout(DownLoadConfig.wifiTimeOut);
                    }
                }
                showToast("网络已连接");
                continueAllHandler();
            }

            @Override
            public void onDisConnect() {
                mIsWorking = false;
                showToast("网络已断开");
                pauseAllHandler();
            }

        });

        // register notification click action recevier
        if (mNotifactionClickReceiver == null) {
            mNotifactionClickReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (intent.getAction().equalsIgnoreCase(
                            NOTIFICATION_CLICK_ACTION)) {
                        Bundle extras = intent.getExtras();
                        long mTaskId = extras.getLong("taskid");
                        String mTaskUrl = extras.getString("taskurl");
                        sendOnClickMessageToCallback(mTaskId, mTaskUrl);

                    } else if (intent.getAction().equalsIgnoreCase(
                            NOFINISH_NOTIFICATION_CLICK_ACTION)) {
                        Bundle extras = intent.getExtras();
                        long taskId = extras.getLong("taskid");
                        String taskUrl = extras.getString("taskurl");
                        pauseOrContinue(taskId, taskUrl);
                    }
                }
            };
        }

        registerNotificationClickReceiver(mNotifactionClickReceiver);

        if (!StringUtils.isEmpty(rootPath)) {
            File rootFile = new File(rootPath);
            if (!rootFile.exists()) {
                rootFile.mkdir();
            }
        }
        cleanOutdatedDownloadedRecords();
    }

    private BroadcastReceiver getSdReceiver() {
        sSdCardReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String actionStr = intent.getAction();
                Logger.d(TAG, "sdAction--->" + actionStr);
                // if (Intent.ACTION_MEDIA_UNMOUNTED.equals(actionStr)) {
                // List<DownloadTask> downloadingTaskList = mDbutil
                // .findDownLoadingTask();
                // if (downloadingTaskList != null
                // && downloadingTaskList.size() > 0) {
                // for (DownloadTask mTask : downloadingTaskList) {
                // if (mDownLoadCallback != null) {
                // mDownLoadCallback.sendFailureMessage(
                // mTask.getId(), mTask.getUrl(),
                // Erros.NO_SD);
                // Logger.d(TAG, "sdAction--->" + actionStr
                // + ";;mTaskId-->" + mTask.getId());
                // }
                //
                // }
                // }
                //
                // }

            }

        };
        return sSdCardReceiver;
    }

    private void registerSdReceiver(BroadcastReceiver sdCardReceiver) {
        IntentFilter intentFilter = new IntentFilter(
                Intent.ACTION_MEDIA_MOUNTED);
        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
        intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
        intentFilter.addDataScheme("file");
        if (mContext != null) {
            mContext.registerReceiver(sdCardReceiver, intentFilter);
        }

    }

    private void unRegisterSdReceiver() {
        if (mContext != null) {
            mContext.unregisterReceiver(sSdCardReceiver);

        }

    }

    private void setWorkerCount() {
        // int processNum = 0;
        int processNum = Runtime.getRuntime().availableProcessors();
        DownLoadConfig.MAX_DOWNLOAD_THREAD_COUNT = processNum + 1;
        Logger.d(TAG, "processNum-->" + processNum);
    }

    private void initParams(Context context, String rootPath, String dataBaseName,
                            boolean isSaveOldData) {
        this.mDbHashCode = dataBaseName.hashCode();
        this.mRootPath = rootPath;
        this.mIsSaveOldData = isSaveOldData;
        this.mContext = context.getApplicationContext();
        if (!TextUtils.isEmpty(dataBaseName) && !"dlplugin_database".equals(dataBaseName)) {
            this.mDbutil = DBUtil.getInstance(mContext, dataBaseName, isSaveOldData);
        } else {
            this.mDbutil = DBUtil.getInstance(mContext, "dlplugin_database", isSaveOldData);
        }
        mhandlerQueue = new HandlerQueue();
        mDownloadinghandlers = new ArrayList<AsyncHttpResponseHandler>();
        mPausinghandlers = new ArrayList<AsyncHttpResponseHandler>();
        mDownloadTaskStatusData = new ArrayList<DownloadTaskStatus>();
        mDownloadStrategyHashMap = new HashMap<Long, DownloadStrategy>();
        mNotificationHelper = new NotificationHelper(mContext);
        mNotificationHelper.cancelAllNotifactions();
        mAsyncHttpClient = new AsyncHttpClient();
        myHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);
                if (msg.what == -1) {
                    mNotificationHelper.cancelNotification(msg.arg1 + mDbHashCode);
                }
            }
        };
    }

    private void pauseOrContinue(long taskId, String url) {
        DownloadTask mDownloadTask = mDbutil.fetchOneDownload(taskId);
        if (mDownloadTask != null) {
            if (mDownloadTask.getStatus() == DownloadTaskStatus.DOWNLOADING
                    && DownLoadConfig.isClickable) {
                pauseTask(taskId);
                mNotificationHelper.updateNotificationTicker(taskId + mDbHashCode, "暂停下载");
            } else if (mDownloadTask.getStatus() == DownloadTaskStatus.PAUSEING
                    && DownLoadConfig.isClickable) {
                String postFix = FileInfoUtils.getPostFix(url);
                continueHandler(url, mDownloadTask.getVisibility());
                mNotificationHelper.updateNotificationTicker(taskId + mDbHashCode, "继续下载");
            }

        }

    }

    public void sendOnClickMessageToCallback(long taskId, String url) {
        if (mDownLoadCallback != null)
            mDownLoadCallback.sendClickNotifationMesage(taskId, url);
    }

    public void registerNotificationClickReceiver(BroadcastReceiver mreceiver) {
        IntentFilter mFilter = new IntentFilter();
        // filter.addAction(DL_ANDROID_NET_CHANGE_ACTION);
        mFilter.addAction(NOTIFICATION_CLICK_ACTION);
        mFilter.addAction(NOFINISH_NOTIFICATION_CLICK_ACTION);
        mContext.getApplicationContext().registerReceiver(mreceiver, mFilter);
    }

    public String getRootPath() {
        if (StringUtils.isEmpty(mRootPath)) {
            mRootPath = DownLoadConfig.FILE_ROOT;
        }
        return mRootPath;
    }

    public void setDownLoadCallback(DownLoadCallback downLoadCallback) {
        this.mDownLoadCallback = downLoadCallback;
    }

    public void toStartMananger() {

        isRunning = true;
        this.start();
        if (mDownLoadCallback != null) {
            mDownLoadCallback.sendStartMangerMessage();
        }
        // checkUncompletehandlers();
    }

    public void close() {
        isRunning = false;
        pauseAllHandler();
        if (mDownLoadCallback != null) {
            mDownLoadCallback.sendStopMessage();
        }
        this.stop();
    }

    @Override
    public void run() {

        super.run();
        while (isRunning) {
            if (mIsWorking) {
                toRequestDownLoad();
            }
        }
    }

    private void toRequestDownLoad() {
        FileHttpResponseHandler handler = (FileHttpResponseHandler) mhandlerQueue
                .poll();
        if (handler.isFirstStart()) {
            Logger.d(TAG,
                    "taskId--->" + handler.getTaskId() + ";" + handler.getUrl()
                            + ";开始下载");
            if (mDownLoadCallback != null) {
                mDownLoadCallback.sendStartDownLoading(handler.getTaskId(),
                        handler.getUrl());
            }
        }

        if (handler != null) {
            mDownloadinghandlers.add(handler);
            DownloadTaskStatus status = getTaskRealtimeStatus(
                    handler.getTaskId(), handler.getUrl());
            if (status != null) {
                status.setCurrentStatus(DownloadTaskStatus.DOWNLOADING);
            }
            handler.setInterrupt(false);
            String url = handler.getUrl();
            DefaultHttpClient httpClient = new DefaultHttpClient();
            String[] redirectArrays;
            try {
                redirectArrays = handleRedirect(handler, httpClient, url);

                String redirectUrl = redirectArrays[0];
                String mineTypePostFix = MimeTypeMap.getSingleton()
                        .getExtensionFromMimeType(redirectArrays[1]);
                String postFix = FileInfoUtils.getPostFix(redirectUrl);
                try {
                    toDownLoad(handler, redirectUrl, mineTypePostFix, postFix);
                } catch (Exception e) {
                    cancelNotifactionByFileResponseHandler(handler);
                    if (mDownLoadCallback != null) {
                        mDownLoadCallback.sendFailureMessage(
                                handler.getTaskId(), url, Erros.URL_EXECEPTION);
                    }
                    Logger.e(TAG, e.toString());
                }
            } catch (ClientProtocolException e) {
                cancelNotifactionByFileResponseHandler(handler);
                if (mDownLoadCallback != null) {
                    mDownLoadCallback.sendFailureMessage(handler.getTaskId(),
                            url, Erros.URL_EXECEPTION);
                }
                Logger.e(TAG, e.toString());
            } catch (MyRedirectException e) {
                cancelNotifactionByFileResponseHandler(handler);
                if (mDownLoadCallback != null) {
                    mDownLoadCallback.sendFailureMessage(handler.getTaskId(),
                            url, Erros.URL_EXECEPTION);
                }
                Logger.e(TAG, e.toString());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                cancelNotifactionByFileResponseHandler(handler);
                if (mDownLoadCallback != null) {
                    mDownLoadCallback.sendFailureMessage(handler.getTaskId(),
                            url, Erros.URL_EXECEPTION);
                }
                Logger.e(TAG, e.toString());
            }

        }

        // saveFailedTask(handler);
        // cancelNotifactionByFileResponseHandler(handler);
        // if (mDownLoadCallback != null) {
        // mDownLoadCallback.sendFailureMessage(handler.getTaskId(),
        // url, Erros.URL_EXECEPTION);
        // }
    }

    private void cancelNotifactionByFileResponseHandler(
            FileHttpResponseHandler handler) {
        if (handler != null) {
            mNotificationHelper.cancelNotification(handler.getTaskId() + mDbHashCode);

        }
    }

    private void saveFailedTask(FileHttpResponseHandler handler) {
        if (mDownloadinghandlers.contains(handler)) {
            mDownloadinghandlers.remove(handler);
        }
        mhandlerQueue.offer(handler);
    }

    private void toDownLoad(FileHttpResponseHandler handler,
                            String redirectUrl, String mineTypePostFix, String postFix)
            throws Exception {
        if (TextUtils.isEmpty(mineTypePostFix) && !TextUtils.isEmpty(postFix)) {
            handler.setContextTypePostFix(mineTypePostFix);
            RenameTempFileByUrlPostFix(handler, redirectUrl);
        } else if (!TextUtils.isEmpty(mineTypePostFix)
                && TextUtils.isEmpty(postFix)) {
            String filePath = handler.getFile().getAbsolutePath();
            File tempFile = new File(filePath + "." + mineTypePostFix
                    + FileHttpResponseHandler.getTempSuffix());
            File file = new File(filePath + "." + mineTypePostFix);
            handler.setTempFile(tempFile);
            handler.setFile(file);
            mDbutil.updateDownload(handler.getTaskId(), null,
                    handler.getCnname(), null, DownloadTaskStatus.DOWNLOADING,
                    0, filePath, null);
        } else if (!TextUtils.isEmpty(mineTypePostFix)
                && !TextUtils.isEmpty(postFix)) {
            handler.setContextTypePostFix(mineTypePostFix);
            RenameTempFileByUrlPostFix(handler, redirectUrl);
        }
        mAsyncHttpClient.download(redirectUrl, handler);
    }

    /**
     * 根据url 的后缀名命名
     *
     * @param handler
     * @param url
     */
    private void RenameTempFileByUrlPostFix(FileHttpResponseHandler handler,
                                            String url) {
        String fileName = StringUtils.getOriginalFileNameFromUrl(url);
        if (TextUtils.isEmpty(fileName)) {
            fileName = System.currentTimeMillis() + "."
                    + handler.getContextTypePostFix();
        }
        String mFilePath = handler.getBaseDirFile() + File.separator + fileName;
        File tempFile = new File(mFilePath
                + FileHttpResponseHandler.getTempSuffix());
        File file = new File(mFilePath);
        handler.setTempFile(tempFile);
        handler.setFile(file);
        mDbutil.updateDownload(handler.getTaskId(), null, handler.getCnname(),
                null, DownloadTaskStatus.DOWNLOADING, 0, mFilePath, null);
    }

    private static class MyRedirectException extends RuntimeException {
        /**
         *
         */
        private static final long serialVersionUID = 1L;

        public MyRedirectException() {
            super();
        }

    }

    private static class MyRedirectHandler implements RedirectHandler {
        private String mFinalUrl = null;
        private int mRedirectCount = 0;
        private String mContentType = null;

        public MyRedirectHandler(String url) {
            mFinalUrl = url;
        }

        @Override
        public boolean isRedirectRequested(HttpResponse response,
                                           HttpContext context) {
            int statueCode = response.getStatusLine().getStatusCode();
            if (statueCode == HttpStatus.SC_MOVED_TEMPORARILY
                    || statueCode == HttpStatus.SC_MOVED_PERMANENTLY) {
                if (mRedirectCount > DownLoadConfig.REDIRECT_COUNT) {
                    throw new MyRedirectException();
                }
                mRedirectCount++;
                return true;
            }
            mContentType = response.getFirstHeader("Content-Type").getValue();
            Logger.d(TAG, "contentType--->" + mContentType);

            return false;
        }

        @Override
        public URI getLocationURI(HttpResponse response, HttpContext context)
                throws ProtocolException {
            URI uri = null;
            Header locationHeader = response.getFirstHeader("location");
            if (locationHeader != null) {
                String url = locationHeader.getValue();
                try {
                    uri = new URI(url);
                    mFinalUrl = uri.toString();
                } catch (URISyntaxException e) {
                }
            }
            return uri;
        }

        public String getFinalUrl() {
            return mFinalUrl;
        }

        public String getContentType() {
            return mContentType;
        }

    }

    private String[] handleRedirect(FileHttpResponseHandler handler,
                                    DefaultHttpClient httpClient, String url)
            throws ClientProtocolException, IOException, MyRedirectException {
        String[] mResult = new String[2];
        try {
            HttpGet request = new HttpGet(url);
            HttpParams params = httpClient.getParams();
            HttpClientParams.setRedirecting(params, true);
            request.setParams(params);
            httpClient.setParams(params);
            MyRedirectHandler redirectHandler = new MyRedirectHandler(url);
            httpClient.setRedirectHandler(redirectHandler);
            httpClient.execute(request);
            if (!TextUtils.isEmpty(redirectHandler.getFinalUrl())) {
                mResult[0] = redirectHandler.getFinalUrl();
                mResult[1] = redirectHandler.getContentType();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            Logger.e(TAG, e.toString());
            if (e != null) {
                Message message = new Message();
                message.arg1 = (int) handler.getTaskId();
                message.what = -1;
                myHandler.sendMessage(message);
            }
        }
        return mResult;
    }

    /*
     * remove outdated download records
     */
    public void cleanOutdatedDownloadedRecords() {
        long latestUpdateTime = mDbutil.getLatestCleanTime();
        if ((System.currentTimeMillis() - latestUpdateTime) >= DownLoadConfig.CLEAN_HISTORY_INTERVAL) {
            mDbutil.removeCompletedDownloadTask();
        }

    }

    /**
     * 7天清除apk 和临时文件
     */
    public void cleanOutDateApkFile() {
        if (mDbutil != null) {
            ArrayList<DownloadTask> downloadTasksList = mDbutil
                    .findAllTask();
            for (DownloadTask task : downloadTasksList) {
                Logger.d(TAG, "savePath--->" + task.getSavepath()
                        + ";createTime--->" + task.getCreatetime());
                long createTime = task.getCreatetime();
                if (System.currentTimeMillis() - createTime >= DownLoadConfig.CLEAN_APK_OUTDATE) {
                    String path = task.getSavepath();
                    String tempPath = task.getSavepath()
                            + FileHttpResponseHandler.TEMP_SUFFIX;
                    if (!TextUtils.isEmpty(path)) {
                        File apkFile = new File(path);
                        if (apkFile.exists()) {
                            apkFile.delete();
                        } else {
                            File apkTempFile = new File(tempPath);
                            apkTempFile.delete();
                        }
                    }
                }
            }
        }
    }

    /**
     * @param type=0 恢复 有通知 条的任务 ,type =1 恢复 静默 任务 .type=2 恢复所有 未完成的任务
     */
    public void restartUnCompletedTask(int type) {
        List<DownloadTask> taskList = mDbutil.findUnCompletedTask();
        if (type == DownloadStrategy.ALL_UNCOMPELETED) {
            if (taskList != null) {
                int listSize = taskList.size();
                if (listSize > 0) {
                    for (DownloadTask task : taskList) {
                        if (task.getVisibility() == DownloadStrategy.VISIBILITY) {
                            mNotificationHelper.addNotification(task.getId() + mDbHashCode, -1,
                                    StringUtils.getOriginalFileNameFromUrl(task
                                            .getUrl()), task.getCnname(), task
                                            .getUrl());

                        }

                        DownloadStrategy downloadStrategy = DownloadStrategy
                                .parseFromJsonString(task.getDownloadStrategy());

                        addHandler(task.getId(), task.getUrl(),
                                downloadStrategy != null ? downloadStrategy : null,
                                task.getCnname(), false);
                    }
                }
            }
        } else if (type == DownloadStrategy.VISIBILITY) {
            if (taskList != null) {
                int listSize = taskList.size();
                if (listSize > 0) {
                    for (DownloadTask task : taskList) {
                        if (task.getVisibility() == DownloadStrategy.VISIBILITY) {
                            mNotificationHelper.addNotification(task.getId() + mDbHashCode, -1,
                                    StringUtils.getOriginalFileNameFromUrl(task
                                            .getUrl()), task.getCnname(), task
                                            .getUrl());
                            DownloadStrategy downloadStrategy = DownloadStrategy
                                    .parseFromJsonString(task.getDownloadStrategy());

                            addHandler(task.getId(), task.getUrl(),
                                    downloadStrategy != null ? downloadStrategy : null,
                                    task.getCnname(), false);

                        }

                    }
                }
            }

        } else if (type == DownloadStrategy.GONE) {
            if (taskList != null) {
                int listSize = taskList.size();
                if (listSize > 0) {
                    for (DownloadTask task : taskList) {
                        if (task.getVisibility() == DownloadStrategy.GONE) {
                            DownloadStrategy downloadStrategy = DownloadStrategy
                                    .parseFromJsonString(task.getDownloadStrategy());

                            addHandler(task.getId(), task.getUrl(),
                                    downloadStrategy != null ? downloadStrategy : null,
                                    task.getCnname(), false);

                        }

                    }
                }
            }
        }

    }

    public void addHandler(long taskId, String url,
                           DownloadStrategy mDownLoadStrategy, String cnname,
                           boolean isFirstStart) {

        if (getTotalhandlerCount() >= DownLoadConfig.MAX_handler_COUNT) {
            return;
        }
        if (TextUtils.isEmpty(url) || hasHandler(taskId, url)) {
            Logger.d(TAG, "任务中存在这个任务,或者任务不满足要求");
            return;
        }

        try {
            if (isFirstStart) {
                addHandler(
                        newcHttpResponseHandler(mDownLoadStrategy, taskId, url,
                                cnname, true), mDownLoadStrategy);
            } else {
                addHandler(
                        newcHttpResponseHandler(mDownLoadStrategy, taskId, url,
                                cnname, false), mDownLoadStrategy);
            }

            // Logger.d(TAG, "下载完成!!");

        } catch (MalformedURLException e) {
            Logger.e(TAG, e.toString());
        }

    }

    private void addHandler(AsyncHttpResponseHandler handler,
                            DownloadStrategy downLoadStrategy) {
        FileHttpResponseHandler fhandler = (FileHttpResponseHandler) handler;
        fhandler.setmDownLoadCallback(mDownLoadCallback);
        broadcastAddHandler(fhandler.getTaskId(), fhandler.getUrl());
        mhandlerQueue.offer(handler);
        mDownloadTaskStatusData.add(new DownloadTaskStatus(
                fhandler.getTaskId(), fhandler.getUrl())
                .setCurrentStatus(DownloadTaskStatus.WAITING));
        if (downLoadStrategy != null)
            mDownloadStrategyHashMap
                    .put(fhandler.getTaskId(), downLoadStrategy);
        if (!this.isAlive()) {
            this.toStartMananger();
            Logger.d(TAG, "toStartMananger()");
        }
    }

    private void broadcastAddHandler(long taskId, String url)

    {
        broadcastAddHandler(taskId, url, false);
    }

    private void broadcastAddHandler(long taskId, String url,
                                     boolean isInterrupt) {

        if (mDownLoadCallback != null) {
            mDownLoadCallback.sendAddMessage(taskId, url, false);
        }

    }

    /**
     * by robin public void reBroadcastAddAllhandler() { FileHttpResponseHandler
     * handler; for (int i = 0; i < mDownloadinghandlers.size(); i++) { handler
     * = (FileHttpResponseHandler) mDownloadinghandlers.get(i);
     * broadcastAddHandler(handler.getTaskId(),handler.getUrl(),
     * handler.isInterrupt()); } for (int i = 0; i < mhandlerQueue.size(); i++)
     * { handler = (FileHttpResponseHandler) mhandlerQueue.get(i);
     * broadcastAddHandler(handler.getTaskId(),handler.getUrl()); } for (int i =
     * 0; i < mPausinghandlers.size(); i++) { handler =
     * (FileHttpResponseHandler) mPausinghandlers.get(i);
     * broadcastAddHandler(handler.getTaskId(),handler.getUrl()); } }
     */
    public boolean hasHandler(long taskId, String url) {
        boolean mResult = false;
        try {
            FileHttpResponseHandler handler;
            if (mDownloadinghandlers != null && mDownloadinghandlers.size() > 0) {
                for (int i = 0; i < mDownloadinghandlers.size(); i++) {
                    handler = (FileHttpResponseHandler) mDownloadinghandlers
                            .get(i);
                    if (handler.getUrl().equals(url)) {
                        mResult = true;
                    }
                }
            }
            if (mhandlerQueue != null && mhandlerQueue.size() > 0) {
                for (int i = 0; i < mhandlerQueue.size(); i++) {
                    handler = (FileHttpResponseHandler) mhandlerQueue.get(i);
                    if (handler.getUrl().equals(url)) {
                        mResult = true;
                    }
                }

            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            Logger.e(TAG, e.toString());
        }
        return mResult;
    }

    public AsyncHttpResponseHandler gethandler(int postion) {

        if (postion >= mDownloadinghandlers.size()) {
            return mhandlerQueue.get(postion - mDownloadinghandlers.size());
        } else {
            return mDownloadinghandlers.get(postion);
        }
    }

    /**
     * ycw 判断文件状态
     *
     * @param url
     * @return
     */
    public DownloadTask getDownloadTask(String url) {
        if (mDbutil != null) {
            if (!TextUtils.isEmpty(url)) {
                DownloadTask downloadTask = mDbutil.findDownloadByUrl(url);
                if (downloadTask == null) {
                    return null;
                }
                if (downloadTask.getStatus() == DownloadTaskStatus.COMPLETED) {
                    String filePath = downloadTask.getSavepath();
                    File file = new File(filePath);
                    if (TextUtils.isEmpty(filePath) || !file.exists()) {
                        downloadTask.setStatus(DownloadTaskStatus.UNCOMPLETED);
                    }
                }

                return downloadTask;
            } else {
                return null;
            }
        } else {
            return null;
        }

    }

    public int getTotalhandlerCount() {

        // by robin return getQueuehandlerCount() + getDownloadinghandlerCount()
        // + getPausinghandlerCount();
        return mDownloadTaskStatusData.size();
    }

    public synchronized void pauseAllHandler() {

        AsyncHttpResponseHandler handler;
        if (mhandlerQueue.size() > 0) {
            for (int i = 0; i < mhandlerQueue.size(); i++) {
                handler = mhandlerQueue.get(i);
                handler.setFirstStart(false);
                mhandlerQueue.remove(handler);
                mPausinghandlers.add(handler);
            }
        }
        if (mDownloadinghandlers.size() > 0) {
            for (int i = 0; i < mDownloadinghandlers.size(); i++) {
                handler = mDownloadinghandlers.get(i);
                if (handler != null) {
                    handler.setFirstStart(false);
                    pausehandler(handler);
                }
            }
        }

    }

    public synchronized void deleteHandler(long taskId) {

        FileHttpResponseHandler handler;
        for (int i = 0; i < mDownloadinghandlers.size(); i++) {
            handler = (FileHttpResponseHandler) mDownloadinghandlers.get(i);
            if (handler != null && handler.getTaskId() == taskId) {
                File file = handler.getFile();
                if (file.exists())
                    file.delete();
                File tempFile = handler.getTempFile();
                if (tempFile.exists()) {
                    tempFile.delete();
                }
                handler.setInterrupt(true);
                completehandler(handler);
                return;
            }
        }
        for (int i = 0; i < mhandlerQueue.size(); i++) {
            handler = (FileHttpResponseHandler) mhandlerQueue.get(i);
            if (handler != null && handler.getTaskId() == taskId) {
                mhandlerQueue.remove(handler);
            }
        }
        for (int i = 0; i < mPausinghandlers.size(); i++) {
            handler = (FileHttpResponseHandler) mPausinghandlers.get(i);
            if (handler != null && handler.getTaskId() == taskId) {
                mPausinghandlers.remove(handler);
            }
        }
    }

    public synchronized void deleteAllHandler() {
        // pauseAllHandler();
        FileHttpResponseHandler handler;
        for (int i = 0; i < mDownloadinghandlers.size(); i++) {
            handler = (FileHttpResponseHandler) mDownloadinghandlers.get(i);
            handler.setmDownLoadCallback(mDownLoadCallback);
            if (handler != null) {
                File file = handler.getFile();
                if (file.exists())
                    file.delete();
                File tempFile = handler.getTempFile();
                if (tempFile.exists()) {
                    tempFile.delete();
                }
                handler.setInterrupt(true);
                completehandler(handler);
                return;
            }
        }
        for (int i = 0; i < mhandlerQueue.size(); i++) {
            handler = (FileHttpResponseHandler) mhandlerQueue.get(i);
            if (handler != null) {
                mhandlerQueue.remove(handler);
            }
        }
        for (int i = 0; i < mPausinghandlers.size(); i++) {
            handler = (FileHttpResponseHandler) mPausinghandlers.get(i);
            if (handler != null) {
                mPausinghandlers.remove(handler);
            }
        }
    }

    private synchronized void pausehandler(AsyncHttpResponseHandler response) {

        try {
            FileHttpResponseHandler fileHttpResponseHandler = (FileHttpResponseHandler) response;
            if (response != null) {
                // move to pausing list
                long taskId = fileHttpResponseHandler.getTaskId();
                String url = fileHttpResponseHandler.getUrl();
                fileHttpResponseHandler.setInterrupt(true);
                DownloadTask downloadTask = mDbutil.fetchOneDownload(taskId);
                if (downloadTask != null) {
                    DownloadStrategy downloadStrategy = DownloadStrategy
                            .parseFromJsonString(downloadTask
                                    .getDownloadStrategy());
                    if (mDownLoadCallback != null
                            && !NetWorkUtil.isNetworkAvailable(mContext)) {
                        mDownLoadCallback.sendFailureMessage(taskId, url,
                                Erros.NO_NETWORK);
                    }
                    if (mDownloadinghandlers != null) {
                        mDownloadinghandlers.remove(response);
                        String cname = getCName(url);
                        response = newcHttpResponseHandler(downloadStrategy,
                                taskId, url, cname, false);
                        mPausinghandlers.add(response);
                    }

                    DownloadTaskStatus downloadTaskStatus = getTaskRealtimeStatus(
                            taskId, url);
                    if (downloadTaskStatus != null) {
                        downloadTaskStatus
                                .setCurrentStatus(DownloadTaskStatus.PAUSEING);

                    }
                    syncDownloadStatusWithDB(taskId,
                            DownloadTaskStatus.PAUSEING, null, null, null);

                }
            }

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            Logger.e(TAG, e.toString());
        }

    }

    private String getCName(String url) {
        DownloadTask mDownloadTask = mDbutil.findDownloadByUrl(url);
        String cname = "";
        if (mDownloadTask != null) {
            cname = mDownloadTask.getCnname();
        }
        return cname;
    }

    /**
     * ycw 添加是否显示进度条参数
     *
     * @param url
     *
     * @param visibility
     */
    public synchronized void continueHandler(String url,
                                             int visibility) {
        FileHttpResponseHandler handler;
        Logger.e("ydp", "add:" + url);
        for (int i = 0; i < mDownloadinghandlers.size(); i++) {
            handler = (FileHttpResponseHandler) mDownloadinghandlers.get(i);
            Logger.e("ydp", "url:" + i + handler.getUrl());
        }
        for (int i = 0; i < mDownloadinghandlers.size(); i++) {
            String cnname = getCName(url);
            handler = (FileHttpResponseHandler) mDownloadinghandlers.get(i);
            if (handler != null && handler.getUrl().equals(url)) {
                long taskId = handler.getTaskId();
                Logger.d(TAG, "准备改变正在下载的进度条状态" + ";taskId-->" + taskId
                        + ";url-->" + url);
                if (visibility == DownloadStrategy.VISIBILITY) {
                    mNotificationHelper.addNotification(handler.getTaskId() + mDbHashCode,
                            -1, StringUtils.getOriginalFileNameFromUrl(url),
                            cnname, url);
                    Logger.d(TAG, "添加正在下载的进度条状态为显示" + ";taskId-->" + taskId
                            + ";url-->" + url);
                } else {
                    mNotificationHelper.cancelNotification(taskId + mDbHashCode);
                    Logger.d(TAG, "将正在下载的进度条状态为隐藏" + ";taskId-->" + taskId
                            + ";url-->" + url);
                }
                // 更新数据库
                DownloadTask downloadTask = mDbutil.fetchOneDownload(taskId);
                String downloadStrategyStr = downloadTask.getDownloadStrategy();
                try {
                    if (!TextUtils.isEmpty(downloadStrategyStr)) {
                        JSONObject  downLoadStrateObj = new JSONObject(
                                downloadStrategyStr);
                        downLoadStrateObj.put(DownloadStrategy.VISIBILITY_KEY,
                                visibility);
                        Logger.d(TAG, "dbDownloadStrategy--->"
                                + downLoadStrateObj);
                        mDbutil.updateDownloadStrategyById(taskId,
                                downLoadStrateObj.toString());

                        Logger.d(TAG, "改变正在下载的进度条数据库状态" + ";taskId-->" + taskId
                                + ";url-->" + url + ";visibility--->"
                                + visibility);
                    }
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    Logger.e(TAG, e.toString());
                }
            }
        }

        for (int i = 0; i < mPausinghandlers.size(); i++) {
            handler = (FileHttpResponseHandler) mPausinghandlers.get(i);
            Logger.d(TAG,
                    "准备改变缓存队列里的进度条状态" + ";taskId-->" + handler.getTaskId()
                            + ";url-->" + handler.getUrl());
            if (handler != null && handler.getUrl().equals(url)) {
                String cnname = getCName(url);
                if (visibility == DownloadStrategy.VISIBILITY) {
                    mNotificationHelper.addNotification(handler.getTaskId() + mDbHashCode,
                            -1, StringUtils.getOriginalFileNameFromUrl(url),
                            cnname, url);
                    Logger.d(TAG, "已经将缓存队列里的进度条状态改为addNotification"
                            + ";taskId-->" + handler.getTaskId() + ";url-->"
                            + handler.getUrl());
                } else {
                    cancelNotifactionByFileResponseHandler(handler);
                    Logger.d(TAG, "隐藏缓存下载的进度条状态为隐藏cancelNotification"
                            + ";taskId-->" + handler.getTaskId() + ";url-->"
                            + url);
                }
                long taskId = handler.getTaskId();
                DownloadTask downloadTask = mDbutil.fetchOneDownload(taskId);
                String downloadStrategyStr = downloadTask.getDownloadStrategy();
                try {
                    if (!TextUtils.isEmpty(downloadStrategyStr)) {
                        JSONObject downLoadStrateObj = new JSONObject(
                                downloadStrategyStr);
                        downLoadStrateObj.put(DownloadStrategy.VISIBILITY_KEY,
                                visibility);
                        Logger.d(TAG, "dbDownloadStrategy--->"
                                + downLoadStrateObj);
                        mDbutil.updateDownloadStrategyById(taskId,
                                downLoadStrateObj.toString());

                        Logger.d(TAG, "改变缓存的进度条数据库状态" + ";taskId-->" + taskId
                                + ";url-->" + url + ";visibility--->"
                                + visibility);
                    }
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    Logger.e(TAG, e.toString());
                }

                continuehandler(handler);
                break;
            }
        }
    }

    public synchronized void continuehandler(
            AsyncHttpResponseHandler responseHandler) {

        if (responseHandler != null) {
            if (mPausinghandlers == null || mhandlerQueue == null) {
                Logger.d(TAG,
                        "mPausinghandlers == null || mhandlerQueue == null");
                return;

            }
            mPausinghandlers.remove(responseHandler);
            mhandlerQueue.offer(responseHandler);
            FileHttpResponseHandler fileHttpResponseHandler = (FileHttpResponseHandler) responseHandler;
            fileHttpResponseHandler.setmDownLoadCallback(mDownLoadCallback);
            DownloadTaskStatus status = getTaskRealtimeStatus(
                    fileHttpResponseHandler.getTaskId(),
                    fileHttpResponseHandler.getUrl());
            if (status != null) {
                status.setCurrentStatus(DownloadTaskStatus.DOWNLOADING);

            }
            syncDownloadStatusWithDB(fileHttpResponseHandler.getTaskId(),
                    DownloadTaskStatus.DOWNLOADING, null, null, null);

        }
    }

    public synchronized void continueAllHandler() {
        if (mPausinghandlers == null || mPausinghandlers.size() == 0) {
            return;
        }
        FileHttpResponseHandler handler;
        int count = mPausinghandlers.size();
        if (count == 0) {
            return;
        }
        for (int i = 0; i < count; i++) {
            handler = (FileHttpResponseHandler) mPausinghandlers.get(0);
            handler.setmDownLoadCallback(mDownLoadCallback);
            String cnname = getCName(handler.getUrl());
            String url = handler.getUrl();
            DownloadTask downloadTask = mDbutil.fetchOneDownload(handler
                    .getTaskId());
            if (downloadTask != null) {
                if (downloadTask.getVisibility() == DownloadStrategy.VISIBILITY) {
                    mNotificationHelper.addNotification(handler.getTaskId() + mDbHashCode,
                            -1, StringUtils.getOriginalFileNameFromUrl(url),
                            cnname, handler.getUrl());
                }
            }
            continuehandler(handler);

        }
    }

    public synchronized void completehandler(
            AsyncHttpResponseHandler mAsyncHttpResponseHandler) {
        long taskId = -1;
        String url = null;
        String apkSavePath = null;
        try {
            if (mDownloadinghandlers.contains(mAsyncHttpResponseHandler)) {
                // by robin
                // DownLoadConfigUtil.clearURL(mDownloadinghandlers.indexOf(handler));
                mDownloadinghandlers.remove(mAsyncHttpResponseHandler);
                if (mDownLoadCallback != null) {
                    FileHttpResponseHandler fhandler = (FileHttpResponseHandler) mAsyncHttpResponseHandler;
                    taskId = fhandler.getTaskId();
                    url = fhandler.getUrl();
                    removeRealtimeStatus(taskId, url);
                    // 说明下载完成
                    if (fhandler != null
                            && fhandler.getDownloadSize() == fhandler
                            .getTotalSize()
                            && fhandler.getDownloadSize() > 0
                            && fhandler.getTotalSize() > 0) {
                        apkSavePath = fhandler.getFile().getAbsolutePath();
                        //Object[] apkinfos = null;
                        // syncDownloadStatusWithDB(taskId,DownloadTaskStatus.COMPLETED,apkSavePath,apkinfos!=null?(String)apkinfos[0]:null,apkinfos!=null?(String)apkinfos[2]:null);
                        String packageName = mDbutil.fetchOneDownload(taskId)
                                .getPackageName();
                        String postFix = FileInfoUtils.getPostFix(apkSavePath);
                        if (SdCardUtil.isMounted()) {
                            if (postFix != null
                                    && postFix.equalsIgnoreCase("apk")) {
//                                apkinfos = ApkUtil.fetchApkFileInfo(mContext,
//                                        apkSavePath);
                                // 若传递了包名,者不更改
                                if (!TextUtils.isEmpty(packageName)) {
                                    syncDownloadStatusWithDB(taskId,
                                            DownloadTaskStatus.COMPLETED,
                                            apkSavePath, packageName, null);
                                } else {
                                    syncDownloadStatusWithDB(
                                            taskId,
                                            DownloadTaskStatus.COMPLETED,
                                            apkSavePath,
                                            null, null);
                                }
                            } else {
                                syncDownloadStatusWithDB(taskId,
                                        DownloadTaskStatus.COMPLETED,
                                        apkSavePath, null, null);
                            }
                            if (mDownLoadCallback != null) {
                                mDownLoadCallback
                                        .sendFinishMessage(taskId, url);
                                mDownLoadCallback.sendLoadMessage(taskId,url, fhandler.getTotalSize(), fhandler.getTotalSize(),0,100);
                            }
                            mNotificationHelper.updateNotification(taskId + mDbHashCode, 100,
                                    100);


                        }

                    }

                }
            }
        } catch (Exception exception) {
            Log.e("YCW", "e.toString--->" + exception.toString());
            if (taskId != -1 && url != null) {
                if (mDownLoadCallback != null) {
                    mNotificationHelper.updateNotification(taskId + mDbHashCode, 100, 100);
                    mDownLoadCallback.sendFailureMessage(taskId, url,
                            Erros.APK_UNINSTALLABLE);
                    mNotificationHelper
                            .updateNotificationTicker(taskId + mDbHashCode, "文件损坏");
                    DownloadTask mDownloadTask = mDbutil.findDownloadByUrl(url);
                    if (mDownloadTask != null) {
                        if (!TextUtils.isEmpty(apkSavePath)) {
                            // mDbutil.deleteDownload(taskId);

                            File apkFile = new File(apkSavePath);
                            if (apkFile.exists()) {
                                apkFile.delete();
                            }
                        }

                    }
                    mNotificationHelper.cancelNotification(taskId + mDbHashCode);

                }
            }

        }
    }

    private void testSavepath(long taskId, String tag) {
        String savaPaths = getDownloadedTaskInfo(taskId).getSavepath();
        Logger.d(TAG, tag + "():" + "savaPaths---->" + savaPaths);
    }

    private AsyncHttpResponseHandler newcHttpResponseHandler(
            DownloadStrategy temDownLoadStrategy, long taskId, String url,
            String cnname, boolean isFirstStart) throws MalformedURLException {
        String rootPathStrategy = null;
        if (temDownLoadStrategy != null) {
            if (!TextUtils.isEmpty(temDownLoadStrategy.rootpath)) {
                rootPathStrategy = temDownLoadStrategy.rootpath;
                Logger.d(TAG, "mRootPathStrategy---->" + rootPathStrategy);
            }

        }

        FileHttpResponseHandler handler = new FileHttpResponseHandler(taskId,
                url, rootPathStrategy == null ? mRootPath : rootPathStrategy,
                StringUtils.getOriginalFileNameFromUrl(url), cnname,
                isFirstStart, mContext, mDataBaseName, mIsSaveOldData) {
            private int times = 0;
            private int step = 1;
            private int stepCount = 0;
            private int stepMax = 100;
            private DownloadStrategy downloadStrategy = null;
            private int lastPercent = 0;

            @Override
            public void onProgress(long totalSize, long currentSize, long speed) {

                // super.onProgress(totalSize, currentSize, speed);
                int downloadPercent = Long.valueOf(
                        currentSize * 100 / totalSize).intValue();

                if ((times == 20) || (currentSize == totalSize)) {
                    mNotificationHelper.updateNotification(this.getTaskId() + mDbHashCode,
                            Long.valueOf(downloadPercent).intValue(), Long
                                    .valueOf(downloadPercent).intValue());

                    Logger.d(TAG, "notifaction--->" + this.getTaskId());
                    times = 0;
                }
                times++;

                if (mDownLoadCallback != null && downloadPercent > 0) {
                    if (downloadStrategy == null) {
                        downloadStrategy = mDownloadStrategyHashMap.get(this
                                .getTaskId());
                    }

                    if (downloadStrategy != null && downloadStrategy.step >= 1
                            && downloadStrategy.step < 100
                            && 100 % downloadStrategy.step == 0) {
                        step = downloadStrategy.step;
                        Logger.d(TAG, "step---->" + step);
                        stepMax = 100 / step;
                        if (stepCount < stepMax
                                && downloadPercent >= step * stepCount
                                && downloadPercent % step == 0
                                && lastPercent != downloadPercent) {
                            lastPercent = downloadPercent;
                            mDownLoadCallback.sendLoadMessage(this.getTaskId(),
                                    this.getUrl(), totalSize, currentSize,
                                    speed, downloadPercent);
                            Logger.d(TAG, "stepCount:" + stepCount
                                    + ";taskId--->" + this.getTaskId()
                                    + ";precent--->" + downloadPercent);
                            stepCount++;
                        }
                    }

                }

            }

            @Override
            public void onSuccess(String content) {
                if (mDownLoadCallback != null) {
                    mDownLoadCallback.sendSuccessMessage(this.getTaskId(),
                            this.getUrl());
                }
            }

            @Override
            public void onFinish() {
                completehandler(this);

            }

            @Override
            public void onStart() {
                // 注意这暂停重新开始也走这里
                // 从缓存查找,如果缓存
                if (mDownLoadCallback != null) {
                    mDownLoadCallback.sendStartMessage(this.getTaskId(),
                            this.getUrl());
                }

                DownloadTask downloadTask = getDownloadedTaskInfo(this
                        .getTaskId());
                if (downloadTask != null) {
                    DownloadStrategy downloadStrategy = DownloadStrategy
                            .parseFromJsonString(downloadTask
                                    .getDownloadStrategy());

                    String postFix = FileInfoUtils.getPostFix(this.getUrl());
                    if (downloadTask != null) {
                        if (downloadTask.getStatus() != DownloadTaskStatus.PAUSEING) {
                            if (downloadStrategy != null) {
                                if (downloadStrategy.getVisibility() == DownloadStrategy.VISIBILITY) {
                                    mNotificationHelper.addNotification(this
                                            .getTaskId() + mDbHashCode, -1, StringUtils
                                            .getOriginalFileNameFromUrl(this
                                                    .getUrl()), downloadTask
                                            .getCnname(), this.getUrl());
                                }
                            } else {
                                mNotificationHelper.addNotification(this
                                        .getTaskId() + mDbHashCode, -1, StringUtils
                                        .getOriginalFileNameFromUrl(this
                                                .getUrl()), downloadTask
                                        .getCnname(), this.getUrl());
                            }

                            syncDownloadStatusWithDB(this.getTaskId(),
                                    DownloadTaskStatus.DOWNLOADING, null, null,
                                    null);
                            testSavepath(downloadTask.getId(), "onStart");
                        } else {
                            continueHandler(this.getUrl(),
                                    downloadTask.getVisibility());
                        }

                    }

                }

                // by robin
                // DownLoadConfigUtil.storeURL(mDownloadinghandlers.indexOf(this),getTaskId(),getUrl());
            }

            @Override
            public void onFailure(Throwable error) {
                if (error != null) {
                    Message message = new Message();
                    message.arg1 = (int) this.getTaskId();
                    message.what = -1;
                    myHandler.sendMessage(message);
                }
                if (error != null) {
                    Logger.e(TAG, "Throwable:" + error.getMessage());
                    Logger.d(TAG, "[hot track]===onFailed==point 9==");
                    error.printStackTrace();
                    String erroMessage = error.getMessage();
                    if (TextUtils.isEmpty(erroMessage)) {
                        if (mDownLoadCallback != null) {
                            mDownLoadCallback.sendFailureMessage(
                                    this.getTaskId(), this.getUrl(),
                                    Erros.TIMEOUT);

                        }
                        return;
                    }
                    if (erroMessage.contains("ETIMEDOUT")) {
                        if (mDownLoadCallback != null) {
                            if (NetWorkUtil.isNetworkAvailable(mContext)) {
                                mDownLoadCallback.sendFailureMessage(
                                        this.getTaskId(), this.getUrl(),
                                        Erros.TIMEOUT);
                            }

                        }

                    } else if (erroMessage.contains("host")) {
                        if (mDownLoadCallback != null) {
                            mDownLoadCallback.sendFailureMessage(
                                    this.getTaskId(), this.getUrl(),
                                    Erros.URL_EXECEPTION);
                        }
                    } else if (erroMessage.contains("I/O")) {
                        if (!Environment.MEDIA_MOUNTED.equals(Environment
                                .getExternalStorageState())) {
                            // if (mDownLoadCallback != null) {
                            // mDownLoadCallback.onFailure(this.getTaskId(),
                            // this.getUrl(), Erros.NO_SD);
                            // }
                        }
                    }
                }
                mNotificationHelper.updateNotificationTicker(this.getTaskId() + mDbHashCode,
                        "下载失败");
                mNotificationHelper.cancelNotification(this.getTaskId() + mDbHashCode);
                pauseTask(this.getTaskId());
            }
        };

        return handler;
    }

    @SuppressWarnings("unused")
    private boolean isWaitingTask(String url) {

        for (int i = 0; i < mhandlerQueue.size(); i++) {

            if (((FileHttpResponseHandler) mhandlerQueue.get(i)).getUrl()
                    .equals(url)) {
                return true;
            }

        }

        return false;
    }

    @SuppressWarnings("unused")
    private boolean isPausingTask(String url) {
        for (int i = 0; i < mPausinghandlers.size(); i++) {
            if (((FileHttpResponseHandler) mPausinghandlers.get(i)).getUrl()
                    .equals(url))
                return true;
        }
        return false;
    }

    @SuppressWarnings("unused")
    private boolean isDownloadingTask(String url) {
        for (int i = 0; i < mDownloadinghandlers.size(); i++) {
            if (((FileHttpResponseHandler) mDownloadinghandlers.get(i))
                    .getUrl().equals(url))
                return true;
        }
        return false;
    }

    private class HandlerQueue {
        private Queue<AsyncHttpResponseHandler> handlerQueue;

        public HandlerQueue() {
            handlerQueue = new LinkedList<AsyncHttpResponseHandler>();
        }

        public void offer(AsyncHttpResponseHandler handler) {

            handlerQueue.offer(handler);
        }

        public AsyncHttpResponseHandler poll() {

            AsyncHttpResponseHandler handler = null;
            while (mDownloadinghandlers.size() >= DownLoadConfig.MAX_DOWNLOAD_THREAD_COUNT
                    || (handler = handlerQueue.poll()) == null) {
                try {
                    Thread.sleep(1000); // sleep
                } catch (InterruptedException e) {
                    Logger.e(TAG, e.toString());
                }
            }
            return handler;
        }

        public AsyncHttpResponseHandler get(int position) {

            if (position >= size()) {
                return null;
            }
            return ((LinkedList<AsyncHttpResponseHandler>) handlerQueue)
                    .get(position);
        }

        public int size() {

            return handlerQueue.size();
        }

        @SuppressWarnings("unused")
        public boolean remove(int position) {

            return handlerQueue.remove(get(position));
        }

        public boolean remove(AsyncHttpResponseHandler handler) {

            return handlerQueue.remove(handler);
        }
    }

    private void removeRealtimeStatus(long taskId, String url) {
        for (int i = 0; i < mDownloadTaskStatusData.size(); i++) {
            DownloadTaskStatus s = mDownloadTaskStatusData.get(i);
            if (s.getTaskId() == taskId || s.getUrl().equals(url)) {
                mDownloadTaskStatusData.remove(i);
                break;
            }
        }
    }

    private DownloadTaskStatus getTaskRealtimeStatus(long taskId, String url) {
        if (mDownloadTaskStatusData != null) {
            for (int i = 0; i < mDownloadTaskStatusData.size(); i++) {
                DownloadTaskStatus s = mDownloadTaskStatusData.get(i);
                if (s != null) {
                    if (s.getTaskId() == taskId || s.getUrl().equals(url))
                        return s;
                }

            }
        }

        return null;
    }

    private void syncDownloadStatusWithDB(long taskId, int status,
                                          String savePath, String packageName, String appName) {
        boolean savedbResult = mDbutil.updateDownload(taskId, null, appName,
                null, status, -1, savePath, packageName);
    }

    /*****
     * blow method for client to invoke
     *
     * @throws Exception
     *****/

    /*
     * post one download task with url and chinese name
     * @param url
     * @param cnname app name, mostly in chinese
     * @param packageName
     * @downloadStrategy download Strategy
     * @return DownloadTask
     */
    public synchronized DownloadTask postTask(String url, String cnname,
                                              String packageName, JSONObject downloadStrategyJsonObj)
            throws Exception {
        Logger.d(TAG, "postTask::" + url + "|" + cnname + "|" + packageName
                + "|" + downloadStrategyJsonObj);
        if (!url.startsWith("http") && !url.startsWith("https")) {
            throw new Exception();
        }
        url = url.trim();
        url = encodeUrl(url);
        Logger.d(TAG, "encodeurl--->" + url);
        int visibility = 0;
        String postFix = FileInfoUtils.getPostFix(url);
        DownloadTask downloadTask = new DownloadTask(url, cnname);
        DownloadTaskStatus istatus = getTaskRealtimeStatus(0, url);
        DownloadStrategy downloadStrategy = null;
        if (downloadStrategyJsonObj != null) {
            downloadStrategy = DownloadStrategy
                    .parseFromJsonObject(downloadStrategyJsonObj);
        }
        if (downloadStrategy != null) {
            visibility = downloadStrategy.getVisibility();
            downloadTask.setVisibility(visibility);
        } else {
            downloadTask.setVisibility(visibility);
        }
        if (istatus != null) {
            // 内存中有这个状态
            Logger.d(TAG,
                    "内存中有----》taskId:" + downloadTask.getId() + ";url---->"
                            + url + ";+statues" + istatus.getCurrentStatus());
            downloadTask.setStatus(istatus.getCurrentStatus());
            // 继续任务并且修改内存和文件状态为Dowloading

            if (NetWorkUtil.isNetworkConnected(mContext)) {
                Logger.d(TAG, "有网络连接");
                if (downloadTask.getStatus() == DownloadTaskStatus.WAITING) {
                    DownloadTask downloadTasktemp = mDbutil
                            .findDownloadByUrl(url);

                    Logger.d(TAG, "正在添加进度条---》url" + url + ";taskId"
                            + downloadTasktemp.getId() + "visibility-->"
                            + downloadTasktemp.getDownloadStrategy());
                    downloadTasktemp.setVisibility(visibility);

                    if (visibility == DownloadStrategy.VISIBILITY) {
                        addNotifactions(url, downloadTasktemp);
                        // 修改数据库

                        mDbutil.updateDownloadStrategyById(
                                downloadTasktemp.getId(),
                                downloadStrategyJsonObj != null ? downloadStrategyJsonObj
                                        .toString() : null);

                    } else {
                        mNotificationHelper.cancelNotification(downloadTasktemp
                                .getId() + mDbHashCode);
                        mDbutil.updateDownloadStrategyById(
                                downloadTasktemp.getId(),
                                downloadStrategyJsonObj != null ? downloadStrategyJsonObj
                                        .toString() : null);
                    }
                    if (downloadTasktemp != null) {
                        Logger.d(TAG, "数据库里面存在---》url" + url + ";taskId"
                                + downloadTasktemp.getId());
                        mDownloadManager
                                .addHandler(
                                        downloadTasktemp.getId(),
                                        url,
                                        downloadStrategy != null ? DownloadStrategy
                                                .parseFromJsonObject(downloadStrategyJsonObj)
                                                : null, downloadTask
                                                .getCnname(), false);
                        Logger.d(TAG, "addHandler()---》url" + url + ";taskId"
                                + downloadTasktemp.getId());
                    } else {
                        Logger.d(TAG, "数据库里不存在---》url" + url + ";taskId"
                                + downloadTasktemp.getId());
                    }
                } else {
                    continueHandler(url, visibility);
                }
            }
        } else {
            Logger.d(TAG, "内存无----》taskId:" + downloadTask.getId()
                    + ";url---->" + url);
            // 从数据库里面查看文件状态,数据库有记录
            DownloadTask downloadTasktemp = mDbutil.findDownloadByUrl(url);
            if (downloadTasktemp != null) {
                downloadTask = downloadTasktemp;
                downloadTask.setPostFix(postFix);
                downloadTask.setVisibility(visibility);
                if (downloadTask != null) {
                    if (downloadTask.getStatus() == DownloadTaskStatus.COMPLETED) {
                        if ("apk".equalsIgnoreCase(postFix)) {
                            boolean mApkIsAvaliable = checkApk(downloadTask);
                            String savePath = downloadTask.getSavepath();
                            if (!TextUtils.isEmpty(savePath) && new File(savePath).exists()
                                    && mApkIsAvaliable) {
                                downloadTask.setSavepath(downloadTask
                                        .getSavepath());
                            } else {// 数据库里有完成记录,但是临时文件不存在(或则已经损坏),重新下载
                                deleteTempFile(downloadTask);
                                // 删除数据库的记录
                                mDbutil.deleteDownload(downloadTask.getId());
                                mNotificationHelper
                                        .cancelNotification(downloadTask
                                                .getId() + mDbHashCode);
                                postTaskFirst(url, cnname, packageName,
                                        downloadStrategyJsonObj, downloadTask);

                            }
                        } else {
                            if (!new File(DownLoadConfig.FILE_ROOT
                                    + downloadTask.getName()).exists()) {
                                deleteTempFile(downloadTask);
                                if (downloadTask.getVisibility() == DownloadStrategy.VISIBILITY) {
                                    addNotifactions(url, downloadTask);
                                }
                                putnewTask(url, downloadStrategyJsonObj,
                                        downloadTask);

                            }
                        }

                    } else {// 数据库里面有记录,文件状态没有完成,临时文件存在,断点续传
                        downloadTask.setStatus(DownloadTaskStatus.UNCOMPLETED)
                                .setSavepath(
                                        DownLoadConfig.FILE_ROOT
                                                + downloadTask.getName());
                        if (downloadTask.getVisibility() == DownloadStrategy.VISIBILITY) {
                            addNotifactions(url, downloadTask);
                        }
                        putnewTask(url, downloadStrategyJsonObj, downloadTask);

                    }
                }
            } else {
                postTaskFirst(url, cnname, packageName,
                        downloadStrategyJsonObj, downloadTask);
            }

        }

        return downloadTask;
    }

    public synchronized boolean saveTempTask(String url, String cnname,
                                             String packageName, JSONObject downloadStrategyJsonObj) {
        boolean result = true;
        Logger.d(TAG, "saveTempTask::" + url + "|" + cnname + "|" + packageName
                + "|" + downloadStrategyJsonObj);
        try {
            url = url.trim();
            url = encodeUrl(url);
            Logger.d(TAG, "encodeurl--->" + url);
            if (mDbutil != null) {
                DownloadTask downloadTask = mDbutil.findDownloadByUrl(url);
                if (downloadTask == null) {
                    mDbutil.insertDownload(
                            StringUtils.getOriginalFileNameFromUrl(url),
                            cnname,
                            url,
                            packageName,
                            downloadStrategyJsonObj != null ? downloadStrategyJsonObj
                                    .toString() : null,
                            DownloadTaskStatus.TEMP_NODOWNLOAD);

                }
            } else {
                result = false;
            }

        } catch (Exception e) {
            result = true;
            Logger.e(TAG, e.toString());
        }
        return result;

    }

    public void startTempTask() {
        if (mDbutil != null) {
            List<DownloadTask> downloadTaskList = mDbutil
                    .findAllTempTaskByStatus();
            if (downloadTaskList != null) {
                int listSize = downloadTaskList.size();
                if (listSize > 0) {
                    for (DownloadTask task : downloadTaskList) {
                        Logger.d(
                                TAG,
                                "startTempTask().getVisibility-->"
                                        + task.getVisibility());
                        if (task.getVisibility() == DownloadStrategy.VISIBILITY) {
                            mNotificationHelper.addNotification(task.getId() + mDbHashCode,
                                    -1, StringUtils
                                            .getOriginalFileNameFromUrl(task
                                                    .getUrl()), task
                                            .getCnname(), task.getUrl());
                        }
                        DownloadStrategy downloadStrategy = DownloadStrategy
                                .parseFromJsonString(task.getDownloadStrategy());

                        addHandler(task.getId(), task.getUrl(),
                                downloadStrategy != null ? downloadStrategy
                                        : null, task.getCnname(), false);
                    }
                }
            }
        }

    }

    private void addNotifactions(String url, DownloadTask downloadTask) {
        try {
            mNotificationHelper.addNotification(downloadTask.getId() + mDbHashCode, -1,
                    StringUtils.getOriginalFileNameFromUrl(url),
                    downloadTask.getCnname(), url);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String encodeUrl(String url) {
        url = Uri.decode(url);
        String encodeUrl = Uri.encode(url, "UTF-8").replace("%3A", ":")
                .replace("%2F", "/");
        return encodeUrl;
    }

    /**
     * ycw 删除临时文件
     *
     * @param downloadTask
     */
    private void deleteTempFile(DownloadTask downloadTask) {
        File mTempFile = new File(DownLoadConfig.FILE_ROOT
                + downloadTask.getName());
        if (mTempFile.exists()) {
            mTempFile.delete();
        }
    }

    /**
     * ycw
     *
     * @param downloadTask
     * @return
     */
    private boolean checkApk(DownloadTask downloadTask) {
        boolean isAvaliable = true;
        String savePath = downloadTask.getSavepath();
        if (downloadTask != null) {
            try {
                if (new File(savePath).exists()) {
                    ApkUtil.fetchApkFileInfo(mContext,
                            downloadTask.getSavepath());
                } else {
                    isAvaliable = false;
                }

            } catch (Exception e) {
                isAvaliable = false;
                Logger.e(TAG, e.toString());
            }
        }
        return isAvaliable;
    }

    /**
     * ycw
     *
     * @param url
     * @param cnname
     * @param packageName
     * @param downloadStrategy
     * @param downloadTask
     */
    private void postTaskFirst(String url, String cnname, String packageName,
                               JSONObject downloadStrategy, DownloadTask downloadTask) {
        long taskId = mDbutil.insertDownload(
                StringUtils.getOriginalFileNameFromUrl(url), cnname, url,
                packageName,
                downloadStrategy != null ? downloadStrategy.toString() : null);
        Logger.d(TAG, "new taskid=" + taskId);
        if (downloadStrategy != null) {
            DownloadStrategy downloadStrategy2 = DownloadStrategy
                    .parseFromJsonObject(downloadStrategy);
            if (downloadStrategy2 != null) {
                if (downloadStrategy2.getVisibility() == DownloadStrategy.VISIBILITY) {
                    mNotificationHelper.addNotification(taskId + mDbHashCode, -1,
                            StringUtils.getOriginalFileNameFromUrl(url),
                            downloadTask.getCnname(), url);

                }
            }
        } else {
            mNotificationHelper.addNotification(taskId + mDbHashCode, -1,
                    StringUtils.getOriginalFileNameFromUrl(url),
                    downloadTask.getCnname(), url);

        }

        mDownloadManager.addHandler(
                taskId,
                url,
                downloadStrategy != null ? DownloadStrategy
                        .parseFromJsonObject(downloadStrategy) : null,
                downloadTask.getCnname(), true);
        downloadTask.setId(taskId).setStatus(DownloadTaskStatus.WAITING);
    }

    private void putnewTask(String url, JSONObject downloadStrategy,
                            DownloadTask downloadTask) {
        if (downloadTask != null) {
            long taskId = downloadTask.getId();
            syncDownloadStatusWithDB(taskId, DownloadTaskStatus.WAITING, null,
                    null, null);

            mDownloadManager.addHandler(
                    taskId,
                    url,
                    downloadStrategy != null ? DownloadStrategy
                            .parseFromJsonObject(downloadStrategy) : null,
                    downloadTask.getCnname(), false);
            downloadTask.setId(taskId).setStatus(DownloadTaskStatus.WAITING);
        }

    }

    public int getDownloadTaskStatus(long taskId) {
        DownloadTaskStatus istatus = getTaskRealtimeStatus(taskId, null);

        if (istatus != null)
            return istatus.getCurrentStatus();
        // if can't find in cache
        DownloadTask entity = mDbutil.fetchOneDownload(taskId);
        return entity != null ? entity.getStatus() : DownloadTaskStatus.UNKNOW;
    }

    /**
     * get one downloaded task info including base-infomation save path etc.
     *
     * @param taskId
     * @return DownloadTask
     */
    public DownloadTask getDownloadedTaskInfo(long taskId) {
        DownloadTask downloadTask = mDbutil.fetchOneDownload(taskId);
        // return (entity!=null &&
        // entity.getStatus()==DownloadTaskStatus.COMPLETED)?entity:null;
        if (downloadTask == null) {
            return null;
        }
        if (downloadTask.getStatus() == DownloadTaskStatus.COMPLETED) {
            String filePath = downloadTask.getSavepath();
            File file = new File(filePath);
            if (TextUtils.isEmpty(filePath) || !file.exists()) {
                downloadTask.setStatus(DownloadTaskStatus.UNCOMPLETED);
            }
        }

        return (downloadTask != null) ? downloadTask : null;
    }

    public DownloadTask getDownloadedTaskInfo(String url) {
        DownloadTask entity = mDbutil.findDownloadByUrl(url);
        if (entity != null) {
            for (int i = 0; i < mDownloadinghandlers.size(); i++) {
                FileHttpResponseHandler fh = (FileHttpResponseHandler) mDownloadinghandlers
                        .get(i);
                if (fh.getUrl().equals(url)) {
                    long totalSize = fh.getTotalSize();
                    if (totalSize != 0) {
                        int downloadPercent = Long.valueOf(
                                fh.getDownloadSize() * 100 / totalSize)
                                .intValue();
                        entity.setProgress(downloadPercent);

                    } else {
                        entity.setProgress(100);
                    }
                    break;
                }
            }
        }
        return entity;
    }

    public synchronized void pauseTask(long taskId) {
        FileHttpResponseHandler handler;
        for (int i = 0; i < mDownloadinghandlers.size(); i++) {
            handler = (FileHttpResponseHandler) mDownloadinghandlers.get(i);
            if (handler != null && handler.getTaskId() == taskId) {
                pausehandler(handler);
            }
        }
    }

    // remove notification specified by packageName
    public void removeNotification(String packageName) {
        ArrayList<DownloadTask> mDownloadtaskList = mDbutil
                .findDownloadByPackageName(packageName);
        if (mDownloadtaskList.size() > 0) {
            for (DownloadTask mTask : mDownloadtaskList) {
                mNotificationHelper.cancelNotification(mTask.getId() + mDbHashCode);
            }

        }
    }

    public void removeNotification(long taskId) {
        mNotificationHelper.cancelNotification(taskId + mDbHashCode);
    }

    public Context getContext() {
        return mContext;
    }

    public void setContext(Context context) {
        this.mContext = context;
    }

    public void setClickAble(boolean clickAble) {
        if (clickAble) {
            DownLoadConfig.isClickable = true;
        }

    }

    private void showToast(String text) {
        if (DownLoadConfig.isShow) {
            Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
        }
    }

    public void setShowToast(boolean isShow) {
        if (isShow) {
            DownLoadConfig.isShow = true;
        }
    }

    public void setNotifacationCancleAble(boolean isCancelAble) {
        if (isCancelAble) {
            DownLoadConfig.notifactionCancleAble = true;
        }

    }

    public void unRegisterAllBroadCastReceiver() {
        try {
            NetworkStateReceiver.unRegisterNetworkStateReceiver(mContext);
            if (mNotifactionClickReceiver != null && mContext != null) {
                mContext.unregisterReceiver(mNotifactionClickReceiver);
            }
            unRegisterSdReceiver();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            Logger.e(TAG, e.toString());
        }
    }

    /**
     * 要在getInstance 之后调用
     *
     * @param mContext type=0 恢复 有通知 条的任务 ,type =1 恢复 静默 任务 .type=2 恢复所有 未完成的任务
     */
    public void restartUnCompleteTask(Context mContext, int type) {
        if (mDownloadManager != null) {
            restartUnCompletedTask(type);
        }
    }

    public static String getmDataBaseName() {
        return mDataBaseName;
    }

    public static void setmDataBaseName(String mDataBaseName) {
        DownloadManager.mDataBaseName = mDataBaseName;
    }

    /**
     * 根据包名查找完成记录
     *
     * @param packageName
     * @return
     */
    public List<DownloadTask> getCompletedTaskByPackage(String packageName) {
        ArrayList<DownloadTask> tempDownloadtaskList = null;
        ArrayList<DownloadTask> downloadcompletetaskList = new ArrayList<DownloadTask>();
        if (mDbutil != null) {
            tempDownloadtaskList = mDbutil
                    .findDownloadByPackageName(packageName);
        }
        for (int i = 0; i < tempDownloadtaskList.size(); i++) {
            DownloadTask downloadTask = tempDownloadtaskList.get(i);
            String filePath = downloadTask.getSavepath();
            File file = new File(filePath);
            if (!TextUtils.isEmpty(filePath) && file.exists()) {
                downloadcompletetaskList.add(downloadTask);
            }
        }

        return downloadcompletetaskList;
    }

}

    这里需要说明的是 获取的单例 的方法有多个重载,如没有特殊业务需求直接调用getInstance(Context context) 即可

    postTask 方法返回的是DownloadTask 对象,可在调用处判断下载状态,如果是DownloadTaskStatus.COMPLETED 并且

   下载文件存在,可以直接走安装逻辑。

   FileType 类

    

package com.downloader.sdk.dlplugin.util.common;

public enum FileType {
    PNG, OGG, GIF, JPG, JS, MP3, WAV, APK, HTML, PHP, JAR, SO, EXE, AVI, MP4, GP3, JSP, TEXT, JSON, DOC, EXL, PPT, RAR, ZIP, UNKOWN
}

   本下载器支持的文件类型

  Errors 类:

   (错误类型,在DownloadCallBack 的onFailure()回调参数中会使用,用于下载失败原因统计。

 

package com.downloader.sdk.dlplugin;

public class Erros {
    /**
     * 资源不可用,有可能是url 不被识别
     */
    public static final int URL_EXECEPTION = 1;
    /**
     * apk损坏
     */
    public static final int APK_UNINSTALLABLE = 2;
    /**
     * 网络连接超时
     */
    public static final int TIMEOUT = 3;
    /**
     * 无网络连接
     */
    public static final int NO_NETWORK = 4;

    /**
     * sd卡容量不足
     */
    public static final int SD_NOSPACE = 5;

    /**
     * 没有sd卡,或者sd未挂载
     */
    public static final int NO_SD = 6;

}

DlNotifaction 类

Notifaction 的封装类,下载器通知的相关方法封装。

package com.downloader.sdk.dlplugin.util.notification;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.RemoteViews;

import com.downloader.sdk.dlplugin.DownLoadConfig;
import com.downloader.sdk.dlplugin.DownloadManager;
import com.downloader.sdk.dlplugin.util.common.StringUtils;

import java.lang.reflect.Field;
import java.util.UUID;

public class DLNotification {

    private Notification notification;

    private Context mContext;

    private static final int MAX_NAME_LENGTH = 30;
    private int[] remoteViewInnerids;
    private boolean existProgressBar;
    private long taskId;
    private String url;

    public DLNotification(Context context, long taskId, int icon, String name,
            String cnname, String url) {
        this.mContext = context.getApplicationContext();
        this.notification = new Notification();
        this.taskId = taskId;
        this.url = url;

        Intent intent = new Intent(mContext, this.getClass());
        Bundle bundle = new Bundle();
        intent.putExtra("ExtraData", bundle);

        PendingIntent pendingIntent = PendingIntent.getService(mContext, UUID
                .randomUUID().hashCode(), intent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        this.notification.icon = android.R.drawable.stat_sys_download;

        this.notification.defaults=Notification.DEFAULT_SOUND;

        String displayName = StringUtils.isEmpty(cnname) ? StringUtils
                .toLength(name, MAX_NAME_LENGTH) : cnname;

        this.notification.when = System.currentTimeMillis();
//        this.notification.setLatestEventInfo(mContext, displayName, null,
//                pendingIntent);


        Notification.Builder builder = new Notification.Builder(context);//新建Notification.Builder对象
        builder.setContentTitle(displayName);//设置标题
        builder.setContentText("正在下载");//设置内容
        builder.setSmallIcon(notification.icon);//设置图片
        builder.setContentIntent(pendingIntent);//执行intent
        builder.build();

        notification = builder.getNotification();//将builder对象转换为普通的notification

        if (this.notification.tickerText == null) {
            this.notification.tickerText = "【" + displayName + "】开始下载";
        }
        RemoteViews remoteViews = this.notification.contentView;

        remoteViewInnerids = fetchNecessaryIds();
        if (remoteViewInnerids[0] > 0) {
            remoteViews.setViewVisibility(remoteViewInnerids[0], View.VISIBLE);
            remoteViews.setImageViewResource(remoteViewInnerids[0],
                    android.R.drawable.stat_sys_download_done);
        }
        if (remoteViewInnerids[1] > 0)
            remoteViews.setTextViewText(remoteViewInnerids[1], displayName);
        if (remoteViewInnerids[2] > 0)
            remoteViews.setTextViewText(remoteViewInnerids[2], "0%");

        View v = null;
        try {
            v = LayoutInflater.from(mContext).inflate(
                    remoteViews.getLayoutId(), null);
        } catch (Exception e) {

        }

        if (v != null)
            findProgressBarInRemoteViewLayout(v);

        if (remoteViewInnerids[7] > 0 && existProgressBar) {
            remoteViews.setProgressBar(remoteViewInnerids[7], 100, 0, false);
            remoteViews.setViewVisibility(remoteViewInnerids[7], View.VISIBLE);
        }

    }

    public void setProcess(int downloadedPercent, int progress) {

        if (remoteViewInnerids[2] > 0)
            this.notification.contentView.setTextViewText(
                    remoteViewInnerids[2], progress + "%");
        if (existProgressBar)
            this.notification.contentView.setProgressBar(remoteViewInnerids[7],
                    100, downloadedPercent, false);
        if (progress == 100) {
            this.notification.icon = android.R.drawable.stat_sys_download_done;
            Bundle bundle = new Bundle();
            bundle.putLong("taskid", this.taskId);
            bundle.putString("taskurl", this.url);
            Intent mIntent = new Intent(
                    DownloadManager.NOTIFICATION_CLICK_ACTION);
            mIntent.putExtras(bundle);

            PendingIntent pintent = PendingIntent.getBroadcast(mContext, Long
                    .valueOf(this.taskId).intValue(), mIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
            this.notification.contentView.setOnClickPendingIntent(
                    this.notification.contentView.getLayoutId(), pintent);
            this.notification.contentIntent = pintent;
            if (DownLoadConfig.notifactionCancleAble) {
                this.notification.flags = Notification.FLAG_AUTO_CANCEL;
            }
        } else {
            this.notification.icon = android.R.drawable.stat_sys_download_done;
            Bundle bundle = new Bundle();
            bundle.putLong("taskid", this.taskId);
            bundle.putString("taskurl", this.url);
            Intent mIntent = new Intent(
                    DownloadManager.NOFINISH_NOTIFICATION_CLICK_ACTION);
            mIntent.putExtras(bundle);
            PendingIntent pintent = PendingIntent.getBroadcast(mContext, Long
                    .valueOf(this.taskId).intValue(), mIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
            this.notification.contentView.setOnClickPendingIntent(
                    this.notification.contentView.getLayoutId(), pintent);
            this.notification.contentIntent = pintent;
        }

    }

    public void setIcon(Drawable icon) {
        if (remoteViewInnerids[0] > 0) {
            BitmapDrawable bd = (BitmapDrawable) icon;
            this.notification.contentView.setImageViewBitmap(
                    remoteViewInnerids[0], bd.getBitmap());
        }
    }

    public static int getNotificationIdByTaskId(long taskId) {
        return Long.valueOf(taskId).intValue();
    }

    public Notification getNotification() {
        return notification;
    }

    public void setNotification(Notification notification) {
        this.notification = notification;
    }

    private int[] fetchNecessaryIds() {
        int[] rtn = {
                0, 0, 0, 0, 0, 0, 0, 0
        };// order:icon,title,text,text1,text2,info,time,progress
        Field[] fields = null;
        try {
            Class cls = Class.forName("com.android.internal.R$id");
            fields = cls.getFields();
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        for (int i = 0; i < fields.length; i++) {
            Field fd = fields[i];
            String fname = fd.getName();
            int fvalue = 0;
            try {
                fvalue = fd.getInt(fname);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            if (fname.equals("icon")) {
                rtn[0] = fvalue;
            }
            if (fname.equals("title")) {
                rtn[1] = fvalue;
            }
            if (fname.equals("text")) {
                rtn[2] = fvalue;
            }
            if (fname.equals("text1")) {
                rtn[3] = fvalue;
            }
            if (fname.equals("text2")) {
                rtn[4] = fvalue;
            }
            if (fname.equals("info")) {
                rtn[5] = fvalue;
            }
            if (fname.equals("time")) {
                rtn[6] = fvalue;
            }
            if (fname.equals("progress")) {
                rtn[7] = fvalue;
            }
        }
        return rtn;
    }

    private void findProgressBarInRemoteViewLayout(View paramView) {
        if (paramView == null)
            return;
        out: if (paramView instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) paramView).getChildCount(); ++i) {
                View localView = ((ViewGroup) paramView).getChildAt(i);
                if (localView instanceof ProgressBar) {
                    existProgressBar = true;
                    break out;
                }

                if (localView instanceof ViewGroup)
                    findProgressBarInRemoteViewLayout(localView);
            }
        }
    }

}

6.0 手机上正常使用,7.0 小米上remoteView 为null ,导致功能有点问题,随后修复。

DBUtil 类

对下载数据进行入库,查询,删除 操作

 

package com.downloader.sdk.dlplugin.util.db;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import android.util.Log;

import com.downloader.sdk.dlplugin.DownloadTask;
import com.downloader.sdk.dlplugin.DownloadTaskStatus;
import com.downloader.sdk.dlplugin.util.log.Logger;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 *
 */
/**
 * @author ycw
 */
public class DBUtil extends SQLiteOpenHelper {
    private static DBUtil mInstance = null;
    private SQLiteDatabase mDb;
    private Context mContext;
    private boolean mIsSaveOldData;
    private static String dataBaseName = "dlplugin_database";
    private static final String TAG = "DBUtil";
    private static final int DATABASE_VERSION = 59;
    private static final String DATABASE_TABLE_DOWNLOAD = "tb_download";
    private static final String DATABASE_TABLE_CONFIG = "tb_config";
    /**
     * Database creation sql statement
     */
    private static final String CREATE_DOWNLOAD_TABLE = "create table "
            + DATABASE_TABLE_DOWNLOAD + " (" + DownloadTask.KEY_ROWID
            + " integer primary key autoincrement, " + DownloadTask.KEY_NAME
            + " text not null, " + DownloadTask.KEY_CNNAME + " text ,"
            + DownloadTask.KEY_FILESIZE + " INTEGER NOT NULL DEFAULT 0,"
            + DownloadTask.KEY_CREATETIME + " INTEGER NOT NULL DEFAULT 0,"
            + DownloadTask.KEY_URL + " text not null, "
            + DownloadTask.KEY_PACKAGE_NAME + " text, "
            + DownloadTask.KEY_DOWNLOAD_STRATEGY + " text, "
            + DownloadTask.KEY_STATUS + " INTEGER NOT NULL DEFAULT 0,"
            + DownloadTask.KEY_INSTALLED + " INTEGER NOT NULL DEFAULT 0,"
            + DownloadTask.KEY_SAVEPATH + " text );";

    private static final String CREATE_CONFIG_TABLE = "create table "
            + DATABASE_TABLE_CONFIG
            + " (_id  integer primary key autoincrement, latestCleanTime INTEGER NOT NULL DEFAULT 0);";

    private static final String DROP_DOWNLOAD_TABLE = "DROP TABLE IF EXISTS "
            + DATABASE_TABLE_DOWNLOAD;
    private static final String DROP_CONFIG_TABLE = "DROP TABLE IF EXISTS "
            + DATABASE_TABLE_CONFIG;

    private DBUtil(Context context, String dataBaseName, boolean isSaveOldDataBase) {
        super(context, dataBaseName, null, DATABASE_VERSION);
        handleDb(context, dataBaseName, isSaveOldDataBase);
        this.dataBaseName = dataBaseName;
        this.mIsSaveOldData = isSaveOldDataBase;
        this.mContext = context;
        try {
            mDb = getWritableDatabase();
        } catch (Exception e) {
            mDb = getReadableDatabase();
        }

    }

    public static void handleDb(Context context, String dataBaseName, boolean isSaveOldData) {
        if (isSaveOldData) {
            // 老数据库存在,数据库存在 ,重命名老数据库,删除 新数据库
            if (DBUtil.dataBaseExits(context, "dlplugin_database")
                    && DBUtil.dataBaseExits(context, dataBaseName)) {
                DBUtil.delDataBase(context, dataBaseName);
                DBUtil.reNameDataBase(context, "dlplugin_database", dataBaseName);
                Logger.d(TAG, "老数据库存在,新数据库存在 ,删除新数据库,重命名老数据库");
                // 老数据库不存在,新数据库存在 ,打开新数据库 对象
            }
        } else {
            if (DBUtil.dataBaseExits(context, "dlplugin_database")
                    && DBUtil.dataBaseExits(context, dataBaseName)) {
                DBUtil.delDataBase(context, dataBaseName);
                DBUtil.delDataBase(context, "dlplugin_database");
            }
        }
    }

    /**
     * 单例
     */
    public static synchronized DBUtil getInstance(Context context, String dataBaseName,
            boolean isSaveOldData) {
        if (mInstance == null) {
            mInstance = new DBUtil(context, dataBaseName, isSaveOldData);
        }

        return mInstance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.i(TAG, "Creating DataBase: " + CREATE_DOWNLOAD_TABLE);
        if (mIsSaveOldData) {
            if (oldDataBaseExits(mContext) && !"dlplugin_database".equals(dataBaseName)) {
                Logger.e(TAG, "old db extist!!");
                File oldDataBaseFile = mContext.getApplicationContext().getDatabasePath(
                        "dlplugin_database");
                File newDataBaseFile = new File(oldDataBaseFile.getParentFile().getAbsolutePath()
                        + File.separator + dataBaseName);

                if (newDataBaseFile.exists()) {
                    newDataBaseFile.delete();
                    Logger.e(TAG, "delete init null db ");
                }
                copyDataBase(mContext);
                // 重新指定 数据库连接
                // 得到数据库对象
                Logger.e(TAG, "open not null db ");

                if (mDb != null) {
                    mDb.close();
                }
                try {
                    mDb = getWritableDatabase();
                    Logger.e(TAG, "get getWritableDatabase");
                } catch (Exception e) {
                    mDb = getReadableDatabase();
                    Logger.e(TAG, "get getReadableDatabase");
                }

            } else {
                createTable(db);
            }
        } else {
            try {
                if (oldDataBaseExits(mContext)) {
                    File oldDataBaseFile = mContext.getApplicationContext().getDatabasePath(
                            "dlplugin_database");
                    if (oldDataBaseFile.exists()) {
                        oldDataBaseFile.delete();
                    }
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                Logger.e(TAG, e.toString());
            }
            createTable(db);
        }

    }

    public void createTable(SQLiteDatabase db) {
        db.execSQL(CREATE_DOWNLOAD_TABLE);
        db.execSQL(CREATE_CONFIG_TABLE);
        db.execSQL("insert into " + DATABASE_TABLE_CONFIG
                + "(latestCleanTime) values(" + System.currentTimeMillis()
                + ")");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(DROP_DOWNLOAD_TABLE);
        db.execSQL(CREATE_DOWNLOAD_TABLE);
        db.execSQL(DROP_CONFIG_TABLE);
        db.execSQL(CREATE_CONFIG_TABLE);
        db.execSQL("insert into " + DATABASE_TABLE_CONFIG
                + "(latestCleanTime) values(" + System.currentTimeMillis()
                + ")");
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion);
    }

    public void close() {
        this.close();
    }

    public void truncateDownloadTable() {
        mDb.execSQL("delete from " + DATABASE_TABLE_DOWNLOAD, new Object[] {});
        mDb.execSQL("update sqlite_sequence set seq=0 where name= '"
                + DATABASE_TABLE_DOWNLOAD + "'", new Object[] {});
    }

    public long insertDownload(String name, String cnname, String url,
            String packageName, String downloadStrategy) {
        ContentValues initialValues = new ContentValues();
        initialValues.put(DownloadTask.KEY_NAME, name);
        initialValues.put(DownloadTask.KEY_CNNAME, cnname);
        // initialValues.put(DownloadEntity.KEY_FILESIZE, name);
        initialValues.put(DownloadTask.KEY_CREATETIME,
                System.currentTimeMillis());
        initialValues.put(DownloadTask.KEY_URL, url);
        if (packageName != null)
            initialValues.put(DownloadTask.KEY_PACKAGE_NAME, packageName);
        if (downloadStrategy != null)
            initialValues.put(DownloadTask.KEY_DOWNLOAD_STRATEGY,
                    downloadStrategy);

        initialValues.put(DownloadTask.KEY_STATUS, 0);
        initialValues.put(DownloadTask.KEY_INSTALLED, 0);

        return mDb.insert(DATABASE_TABLE_DOWNLOAD, null, initialValues);
    }

    public long insertDownload(String name, String cnname, String url,
            String packageName, String downloadStrategy, int stauts) {
        ContentValues initialValues = new ContentValues();
        initialValues.put(DownloadTask.KEY_NAME, name);
        initialValues.put(DownloadTask.KEY_CNNAME, cnname);
        // initialValues.put(DownloadEntity.KEY_FILESIZE, name);
        initialValues.put(DownloadTask.KEY_CREATETIME,
                System.currentTimeMillis());
        initialValues.put(DownloadTask.KEY_URL, url);
        if (packageName != null)
            initialValues.put(DownloadTask.KEY_PACKAGE_NAME, packageName);
        if (downloadStrategy != null)
            initialValues.put(DownloadTask.KEY_DOWNLOAD_STRATEGY,
                    downloadStrategy);

        initialValues.put(DownloadTask.KEY_STATUS, stauts);
        initialValues.put(DownloadTask.KEY_INSTALLED, 0);

        return mDb.insert(DATABASE_TABLE_DOWNLOAD, null, initialValues);
    }

    public boolean deleteDownload(long rowId) {
        return mDb.delete(DATABASE_TABLE_DOWNLOAD, DownloadTask.KEY_ROWID + "="
                + rowId, null) > 0;
    }

    public Cursor fetchAllDownload() {
        return mDb.query(DATABASE_TABLE_DOWNLOAD, new String[] {
                DownloadTask.KEY_ROWID, DownloadTask.KEY_NAME,
                DownloadTask.KEY_CNNAME, DownloadTask.KEY_URL,
                DownloadTask.KEY_STATUS, DownloadTask.KEY_INSTALLED
        }, null,
                null, null, null, null);
    }

    public List<DownloadTask> findUnCompletedTask() {
        List<DownloadTask> result = new ArrayList<DownloadTask>();
        Cursor mCursor = null;
        try {
            mCursor = mDb
                    .query(true, DATABASE_TABLE_DOWNLOAD, new String[] {
                            DownloadTask.KEY_ROWID, DownloadTask.KEY_NAME,
                            DownloadTask.KEY_CNNAME, DownloadTask.KEY_FILESIZE,
                            DownloadTask.KEY_CREATETIME, DownloadTask.KEY_URL,
                            DownloadTask.KEY_PACKAGE_NAME,
                            DownloadTask.KEY_DOWNLOAD_STRATEGY,
                            DownloadTask.KEY_STATUS,
                            DownloadTask.KEY_INSTALLED,
                            DownloadTask.KEY_SAVEPATH
                    },
                            DownloadTask.KEY_STATUS + "<"
                                    + DownloadTaskStatus.COMPLETED + " and "
                                    + DownloadTask.KEY_STATUS + ">="
                                    + DownloadTaskStatus.WAITING, null, null,
                            null, "_id", null);

            if (mCursor.getCount() > 0) {
                while (mCursor.moveToNext()) {
                    DownloadTask entity = new DownloadTask()
                            .setId(mCursor.getLong(0))
                            .setName(mCursor.getString(1))
                            .setCnname(mCursor.getString(2))
                            .setFilesize(mCursor.getLong(3))
                            .setCreatetime(mCursor.getLong(4))
                            .setUrl(mCursor.getString(5))
                            .setPackageName(mCursor.getString(6))
                            .setDownloadStrategy(mCursor.getString(7))
                            .setStatus(mCursor.getInt(8))
                            .setInstalled(mCursor.getInt(9))
                            .setSavepath(mCursor.getString(10))
                            .setFileTypeByUrl(
                                    mCursor.getString(10) == null ? mCursor
                                            .getString(5) : mCursor
                                            .getString(10));
                    result.add(entity);
                }
            }
        } catch (Exception e) {
            return result;
        } finally {
            if (mCursor != null) {
                mCursor.close();
            }
        }

        return result;
    }

    public List<DownloadTask> findDownLoadingTask() {
        List<DownloadTask> result = new ArrayList<DownloadTask>();
        Cursor mCursor = null;
        try {
            mCursor = mDb.query(true, DATABASE_TABLE_DOWNLOAD, new String[] {
                    DownloadTask.KEY_ROWID, DownloadTask.KEY_NAME,
                    DownloadTask.KEY_CNNAME, DownloadTask.KEY_FILESIZE,
                    DownloadTask.KEY_CREATETIME, DownloadTask.KEY_URL,
                    DownloadTask.KEY_PACKAGE_NAME,
                    DownloadTask.KEY_DOWNLOAD_STRATEGY,
                    DownloadTask.KEY_STATUS, DownloadTask.KEY_INSTALLED,
                    DownloadTask.KEY_SAVEPATH
            }, DownloadTask.KEY_STATUS + "=="
                    + DownloadTaskStatus.DOWNLOADING, null, null, null, "_id",
                    null);

            if (mCursor.getCount() > 0) {
                while (mCursor.moveToNext()) {
                    DownloadTask entity = new DownloadTask()
                            .setId(mCursor.getLong(0))
                            .setName(mCursor.getString(1))
                            .setCnname(mCursor.getString(2))
                            .setFilesize(mCursor.getLong(3))
                            .setCreatetime(mCursor.getLong(4))
                            .setUrl(mCursor.getString(5))
                            .setPackageName(mCursor.getString(6))
                            .setDownloadStrategy(mCursor.getString(7))
                            .setStatus(mCursor.getInt(8))
                            .setInstalled(mCursor.getInt(9))
                            .setSavepath(mCursor.getString(10))
                            .setFileTypeByUrl(
                                    mCursor.getString(10) == null ? mCursor
                                            .getString(5) : mCursor
                                            .getString(10));
                    result.add(entity);
                }
            }
        } catch (Exception e) {
            return result;
        } finally {
            if (mCursor != null) {
                mCursor.close();
            }
        }

        return result;
    }

    public DownloadTask fetchOneDownload(long id) {
        DownloadTask entity = null;
        Cursor mCursor = null;

        try {
            mCursor = mDb.query(true, DATABASE_TABLE_DOWNLOAD, new String[] {
                    DownloadTask.KEY_ROWID, DownloadTask.KEY_NAME,
                    DownloadTask.KEY_CNNAME, DownloadTask.KEY_FILESIZE,
                    DownloadTask.KEY_CREATETIME, DownloadTask.KEY_URL,
                    DownloadTask.KEY_PACKAGE_NAME,
                    DownloadTask.KEY_DOWNLOAD_STRATEGY,
                    DownloadTask.KEY_STATUS, DownloadTask.KEY_INSTALLED,
                    DownloadTask.KEY_SAVEPATH
            }, DownloadTask.KEY_ROWID + "="
                    + id, null, null, null, null, null);

            if (mCursor.getCount() > 0) {
                mCursor.moveToFirst();
                entity = new DownloadTask()
                        .setId(mCursor.getLong(0))
                        .setName(mCursor.getString(1))
                        .setCnname(mCursor.getString(2))
                        .setFilesize(mCursor.getLong(3))
                        .setCreatetime(mCursor.getLong(4))
                        .setUrl(mCursor.getString(5))
                        .setPackageName(mCursor.getString(6))
                        .setDownloadStrategy(mCursor.getString(7))
                        .setStatus(mCursor.getInt(8))
                        .setInstalled(mCursor.getInt(9))
                        .setSavepath(mCursor.getString(10))
                        .setFileTypeByUrl(
                                mCursor.getString(10) == null ? mCursor
                                        .getString(5) : mCursor.getString(10));
            }
        } catch (Exception e) {
            return null;
        } finally {
            if (mCursor != null) {
                mCursor.close();
            }
        }

        return entity;
    }

    public DownloadTask findDownloadByUrl(String url) {
        DownloadTask entity = null;
        Cursor mCursor = null;
        try {
            mCursor = mDb.query(true, DATABASE_TABLE_DOWNLOAD, new String[] {
                    DownloadTask.KEY_ROWID, DownloadTask.KEY_NAME,
                    DownloadTask.KEY_CNNAME, DownloadTask.KEY_FILESIZE,
                    DownloadTask.KEY_CREATETIME, DownloadTask.KEY_URL,
                    DownloadTask.KEY_PACKAGE_NAME,
                    DownloadTask.KEY_DOWNLOAD_STRATEGY,
                    DownloadTask.KEY_STATUS, DownloadTask.KEY_INSTALLED,
                    DownloadTask.KEY_SAVEPATH
            }, DownloadTask.KEY_URL + "='"
                    + url + "'", null, null, null, null, null);

            if (mCursor.getCount() > 0) {
                mCursor.moveToFirst();
                entity = new DownloadTask();
                entity = entity
                        .setId(mCursor.getLong(0))
                        .setName(mCursor.getString(1))
                        .setCnname(mCursor.getString(2))
                        .setFilesize(mCursor.getLong(3))
                        .setCreatetime(mCursor.getLong(4))
                        .setUrl(mCursor.getString(5))
                        .setPackageName(mCursor.getString(6))
                        .setDownloadStrategy(mCursor.getString(7))
                        .setStatus(mCursor.getInt(8))
                        .setInstalled(mCursor.getInt(9))
                        .setSavepath(mCursor.getString(10))
                        .setFileTypeByUrl(
                                mCursor.getString(10) == null ? mCursor
                                        .getString(5) : mCursor.getString(10));
            }
        } catch (Exception e) {
            return null;
        } finally {
            if (mCursor != null) {
                mCursor.close();
            }
        }

        return entity;
    }

    public ArrayList<DownloadTask> findDownloadByPackageName(String packageName) {
        ArrayList<DownloadTask> mDownloadTasksList = new ArrayList<DownloadTask>();
        Cursor mCursor = null;
        try {
            mCursor = mDb.query(true, DATABASE_TABLE_DOWNLOAD, new String[] {
                    DownloadTask.KEY_ROWID, DownloadTask.KEY_NAME,
                    DownloadTask.KEY_CNNAME, DownloadTask.KEY_FILESIZE,
                    DownloadTask.KEY_CREATETIME, DownloadTask.KEY_URL,
                    DownloadTask.KEY_PACKAGE_NAME,
                    DownloadTask.KEY_DOWNLOAD_STRATEGY,
                    DownloadTask.KEY_STATUS, DownloadTask.KEY_INSTALLED,
                    DownloadTask.KEY_SAVEPATH
            }, DownloadTask.KEY_PACKAGE_NAME
                    + "='" + packageName + "' and " + DownloadTask.KEY_STATUS
                    + "=" + DownloadTaskStatus.COMPLETED, null, null, null,
                    null, null);

            if (mCursor.getCount() > 0) {
                while (mCursor.moveToNext()) {
                    DownloadTask entity = new DownloadTask();
                    entity = entity
                            .setId(mCursor.getLong(0))
                            .setName(mCursor.getString(1))
                            .setCnname(mCursor.getString(2))
                            .setFilesize(mCursor.getLong(3))
                            .setCreatetime(mCursor.getLong(4))
                            .setUrl(mCursor.getString(5))
                            .setPackageName(mCursor.getString(6))
                            .setDownloadStrategy(mCursor.getString(7))
                            .setStatus(mCursor.getInt(8))
                            .setInstalled(mCursor.getInt(9))
                            .setSavepath(mCursor.getString(10))
                            .setFileTypeByUrl(
                                    mCursor.getString(10) == null ? mCursor
                                            .getString(5) : mCursor
                                            .getString(10));

                    mDownloadTasksList.add(entity);
                }

            }
        } catch (Exception e) {
            return null;
        } finally {
            if (mCursor != null) {
                mCursor.close();
            }
        }
        return mDownloadTasksList;

    }

    public boolean updateDownload(long id, String name, String cnname,
            String url, int status, int installed, String savepath,
            String packageName) {
        ContentValues args = new ContentValues();
        if (name != null && !name.equals(""))
            args.put(DownloadTask.KEY_NAME, name);
        if (cnname != null && !cnname.equals(""))
            args.put(DownloadTask.KEY_CNNAME, cnname);
        if (url != null && !url.equals(""))
            args.put(DownloadTask.KEY_URL, url);
        if (status >= 0)
            args.put(DownloadTask.KEY_STATUS, status);
        if (installed == 0 || installed == 1)
            args.put(DownloadTask.KEY_INSTALLED, installed);
        if (savepath != null && !savepath.equals(""))
            args.put(DownloadTask.KEY_SAVEPATH, savepath);
        if (packageName != null && !packageName.equals(""))
            args.put(DownloadTask.KEY_PACKAGE_NAME, packageName);
        return mDb.update(DATABASE_TABLE_DOWNLOAD, args, DownloadTask.KEY_ROWID
                + "=" + id, null) > 0;
    }

    public boolean updateDownloadStrategyById(long id,
            String downloadStrategyStr) {
        ContentValues args = new ContentValues();
        if (!TextUtils.isEmpty(downloadStrategyStr)) {
            args.put(DownloadTask.KEY_DOWNLOAD_STRATEGY, downloadStrategyStr);
        }
        return mDb.update(DATABASE_TABLE_DOWNLOAD, args, DownloadTask.KEY_ROWID
                + "=" + id, null) > 0;
    }

    // 清除过期的下载记录
    public void removeCompletedDownloadTask() {
        if (mDb.delete(DATABASE_TABLE_DOWNLOAD, DownloadTask.KEY_STATUS + "="
                + DownloadTaskStatus.COMPLETED, null) > 0) {
            udpateLatestCleanTime(System.currentTimeMillis());
        }
    }

    public long getLatestCleanTime() {
        long returnVal = -1;
        Cursor mCursor = null;
        try {
            mCursor = mDb.query(true, DATABASE_TABLE_CONFIG, new String[] {
                    "_id", "latestCleanTime"
            }, "_id=1", null, null, null,
                    null, null);
            if (mCursor.getCount() > 0) {
                mCursor.moveToFirst();
                returnVal = mCursor.getLong(1);
                if (returnVal == 0)
                    returnVal = -1;
            }
        } catch (Exception e) {
            Log.i(TAG, "getLatestCleanTime: error!");
        } finally {
            if (mCursor != null) {
                mCursor.close();
            }
        }
        return returnVal;
    }

    public boolean udpateLatestCleanTime(long updateTime) {
        ContentValues args = new ContentValues();
        if (updateTime > 0)
            args.put("latestCleanTime", updateTime);
        return mDb.update(DATABASE_TABLE_CONFIG, args, "_id=1", null) > 0;
    }

    public ArrayList<DownloadTask> findAllTask() {
        ArrayList<DownloadTask> result = new ArrayList<DownloadTask>();
        Cursor mCursor = null;
        try {
            mCursor = mDb.query(true, DATABASE_TABLE_DOWNLOAD, new String[] {
                    DownloadTask.KEY_ROWID, DownloadTask.KEY_NAME,
                    DownloadTask.KEY_CNNAME, DownloadTask.KEY_FILESIZE,
                    DownloadTask.KEY_CREATETIME, DownloadTask.KEY_URL,
                    DownloadTask.KEY_PACKAGE_NAME,
                    DownloadTask.KEY_DOWNLOAD_STRATEGY,
                    DownloadTask.KEY_STATUS, DownloadTask.KEY_INSTALLED,
                    DownloadTask.KEY_SAVEPATH
            }, null, null, null, null, "_id",
                    null);

            if (mCursor.getCount() > 0) {
                while (mCursor.moveToNext()) {
                    DownloadTask entity = new DownloadTask()
                            .setId(mCursor.getLong(0))
                            .setName(mCursor.getString(1))
                            .setCnname(mCursor.getString(2))
                            .setFilesize(mCursor.getLong(3))
                            .setCreatetime(mCursor.getLong(4))
                            .setUrl(mCursor.getString(5))
                            .setPackageName(mCursor.getString(6))
                            .setDownloadStrategy(mCursor.getString(7))
                            .setStatus(mCursor.getInt(8))
                            .setInstalled(mCursor.getInt(9))
                            .setSavepath(mCursor.getString(10))
                            .setFileTypeByUrl(
                                    mCursor.getString(10) == null ? mCursor
                                            .getString(5) : mCursor
                                            .getString(10));
                    result.add(entity);
                }
            }
        } catch (Exception e) {
            return result;
        } finally {
            if (mCursor != null) {
                mCursor.close();
            }
        }

        return result;
    }

    public ArrayList<DownloadTask> findAllTempTaskByStatus() {
        ArrayList<DownloadTask> downLoadTaskList = new ArrayList<DownloadTask>();
        Cursor mCursor = null;
        try {
            mCursor = mDb.query(true, DATABASE_TABLE_DOWNLOAD, new String[] {
                    DownloadTask.KEY_ROWID, DownloadTask.KEY_NAME,
                    DownloadTask.KEY_CNNAME, DownloadTask.KEY_FILESIZE,
                    DownloadTask.KEY_CREATETIME, DownloadTask.KEY_URL,
                    DownloadTask.KEY_PACKAGE_NAME,
                    DownloadTask.KEY_DOWNLOAD_STRATEGY,
                    DownloadTask.KEY_STATUS, DownloadTask.KEY_INSTALLED,
                    DownloadTask.KEY_SAVEPATH
            }, DownloadTask.KEY_STATUS + "="
                    + DownloadTaskStatus.TEMP_NODOWNLOAD, null, null, null,
                    "_id", null);

            if (mCursor.getCount() > 0) {
                while (mCursor.moveToNext()) {
                    DownloadTask entity = new DownloadTask()
                            .setId(mCursor.getLong(0))
                            .setName(mCursor.getString(1))
                            .setCnname(mCursor.getString(2))
                            .setFilesize(mCursor.getLong(3))
                            .setCreatetime(mCursor.getLong(4))
                            .setUrl(mCursor.getString(5))
                            .setPackageName(mCursor.getString(6))
                            .setDownloadStrategy(mCursor.getString(7))
                            .setStatus(mCursor.getInt(8))
                            .setInstalled(mCursor.getInt(9))
                            .setSavepath(mCursor.getString(10))
                            .setFileTypeByUrl(
                                    mCursor.getString(10) == null ? mCursor
                                            .getString(5) : mCursor
                                            .getString(10));
                    downLoadTaskList.add(entity);
                }
            }
        } catch (Exception e) {
        } finally {
            if (mCursor != null) {
                mCursor.close();
            }
        }
        return downLoadTaskList;

    }

    public static String getDATABASE_NAME() {
        return dataBaseName;
    }

    public void setDATABASE_NAME(String dATABASE_NAME) {
        dataBaseName = dATABASE_NAME;
    }

    /**
     * 重命名数据库达到 复制老数据库 的效果 `
     * 
     * @param context
     */
    public void copyDataBase(Context context) {
        Logger.e(TAG, "prepare to copy olddb!");
        if (context != null) {
            File oldDataBaseFile = context.getApplicationContext().getDatabasePath(
                    "dlplugin_database");
            if (oldDataBaseFile.exists() && !"dlplugin_database".equals(dataBaseName)) {
                File newDataBaseFile = new File(oldDataBaseFile.getParentFile().getAbsolutePath()
                        + File.separator + dataBaseName);
                if (newDataBaseFile.exists()) {
                    Logger.e(TAG, "newDataBaseFile ---exists!");
                }
                FileInputStream inputStream = null;
                FileOutputStream outputStream = null;
                try {
                    inputStream = new FileInputStream(oldDataBaseFile);
                    outputStream = new FileOutputStream(newDataBaseFile);
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    try {
                        while ((len = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, len);
                        }
                        outputStream.flush();
                        oldDataBaseFile.delete();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        Logger.e(TAG, e.toString());
                    }
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    Logger.e(TAG, e.toString());
                } finally {
                    if (outputStream != null) {
                        try {
                            outputStream.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            Logger.e(TAG, e.toString());
                        }
                    }
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            Logger.e(TAG, e.toString());
                        }

                    }
                }

            }
        }
        Logger.e(TAG, " db copy already!");
    }

    /**
     * 判断老数据库是否 存在
     * 
     * @param context
     * @return
     */
    public boolean oldDataBaseExits(Context context) {
        boolean result = false;
        if (context != null) {
            File oldDataBaseFile = context.getApplicationContext().getDatabasePath(
                    "dlplugin_database");
            if (oldDataBaseFile.exists()) {
                result = true;
            }
        }
        return result;

    }

    /**
     * 判断老数据库是否 存在
     * 
     * @param context
     * @return
     */
    public static boolean dataBaseExits(Context context, String dbName) {
        boolean result = false;
        if (context != null) {
            File oldDataBaseFile = context.getApplicationContext().getDatabasePath(
                    dbName);
            if (oldDataBaseFile.exists()) {
                result = true;
            }
        }
        return result;

    }

    /**
     * 判断老数据库是否 存在
     * 
     * @param context
     * @return
     */
    public static boolean delDataBase(Context context, String dbName) {
        boolean result = false;
        if (context != null) {
            File dataBaseFile = context.getApplicationContext().getDatabasePath(
                    dbName);
            if (dataBaseFile.exists()) {
                result = dataBaseFile.delete();
            }
        }
        return result;
    }

    /**
     * 重命名数据库达到 复制老数据库 的效果 `
     * 
     * @param context
     */
    public static void reNameDataBase(Context context, String oldDataBaseName,
            String newDataBaseName) {
        Logger.e(TAG, "prepare to copy olddb!");
        if (context != null) {
            File oldDataBaseFile = context.getApplicationContext().getDatabasePath(
                    oldDataBaseName);
            if (oldDataBaseFile.exists() && !"dlplugin_database".equals(dataBaseName)) {
                File newDataBaseFile = new File(oldDataBaseFile.getParentFile().getAbsolutePath()
                        + File.separator + dataBaseName);
                if (!newDataBaseFile.exists()) {
                    Logger.e(TAG, "newDataBaseFile ---exists!");
                    oldDataBaseFile.renameTo(newDataBaseFile);
                }
            }
        }
        Logger.e(TAG, " db copy already!");
    }
}

此外附上github 项目地址:https://github.com/15811472463/downloader.git

   

 

 

 

 

 

         

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值