概述
以前一直没有时间整理自己封装的类库。本篇博文跟大家介绍下之前自己写的一款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
最后
以上就是自然发卡为你收集整理的android 多线程下载器 源码解析的全部内容,希望文章能够帮你解决android 多线程下载器 源码解析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复