public class DownloadManager {
//下载目录
public static String DOWNLOAD_DIR = Environment.getExternalStorageDirectory()
+"/"+GooglePlayApplication.getContext().getPackageName()+"/download";
public static final int STATE_NONE = 0;//初始状态
public static final int STATE_WAITTING = 1;//等待状态
public static final int STATE_DOWNLOADING = 2;//下载状态
public static final int STATE_FINISH = 3;//下载完成状态
public static final int STATE_ERROR = 4;//下载出错状态
public static final int STATE_PAUSE = 5;//下载出错状态
private ArrayList<DownloadObserver> observers = new ArrayList<DownloadObserver>();
// SparseArray<DownloadInfo> downloadInfoMap = new SparseArray<DownloadInfo>();
private HashMap<Integer, DownloadInfo> downloadInfoMap = new HashMap<Integer, DownloadInfo>();
private HashMap<Integer, DownloadTask> downloadTaskMap = new HashMap<Integer, DownloadTask>();
private static DownloadManager mInstance = new DownloadManager();
private DownloadManager(){
//初始化下载目录
File file = new File(DOWNLOAD_DIR);
if(!file.exists()){
file.mkdirs();//创建下载目录
}
}
public static DownloadManager getInstance(){
return mInstance;
}
/**
* 下载的方法
* @param appInfo
*/
public void download(AppInfo appInfo){
if(appInfo==null)return;
//1.获取downloadInfo
DownloadInfo downloadInfo = downloadInfoMap.get(appInfo.getId());
if(downloadInfo==null){
//如果没有则创建,然后放入downloadInfoMap
downloadInfo = DownloadInfo.create(appInfo);
downloadInfoMap.put(appInfo.getId(), downloadInfo);
}
//2.判断是否能够开始下载
//只要不是下载中和下载完成都可以下载
if(downloadInfo.getState()==STATE_NONE || downloadInfo.getState()==STATE_PAUSE
|| downloadInfo.getState()==STATE_ERROR){
//3.创建下载任务,并放入downloadTaskMap中维护起来
DownloadTask downloadTask = new DownloadTask(downloadInfo);
downloadTaskMap.put(downloadInfo.getId(), downloadTask);
//此时当前downloadInfo更新为等待状态
downloadInfo.setState(STATE_WAITTING);
//通知状态更新
notifyStateChange(downloadInfo);
//4.将任务交给ThreadPoolManager执行
ThreadPoolManager.getInstance().execute(downloadTask);
}
}
class DownloadTask implements Runnable{
private DownloadInfo downloadInfo;
public DownloadTask(DownloadInfo downloadInfo) {
super();
this.downloadInfo = downloadInfo;
}
@Override
public void run() {
//5.一旦执行run方法,说明任务已经开始执行,需要将状态更新为下载中
downloadInfo.setState(STATE_DOWNLOADING);
notifyStateChange(downloadInfo);
//6.具体的下载,2种情况:从头下载和断点下载
HttpResult httpResult;
File file = new File(downloadInfo.getPath());
if(!file.exists() || file.length()!=downloadInfo.getCurrentLength()){
//文件不存在,或者文件的大小和downloadInfo中保存的不一致,则文件无效
file.delete();//删除无效文件
downloadInfo.setCurrentLength(0);//重置已经下载的长度
//需要从头下载
String url = String.format(Url.APP_DOWNLOAD, downloadInfo.getDownloadUrl());
httpResult = HttpHelper.download(url);
}else {
//需要断点下载
String url = String.format(Url.APP_BREAK_DOWNLOAD, downloadInfo.getDownloadUrl(),downloadInfo.getCurrentLength());
httpResult = HttpHelper.download(url);
}
//7.IO操作
if(httpResult!=null && httpResult.getInputStream()!=null){
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file, true);
InputStream is = httpResult.getInputStream();
byte[] buffer = new byte[1024*8];//定义缓冲区
int len = -1;
while((len=is.read(buffer))!=-1 && downloadInfo.getState()==STATE_DOWNLOADING){
fos.write(buffer, 0, len);
fos.flush();
//更新currentLength
downloadInfo.setCurrentLength(downloadInfo.getCurrentLength()+len);
notifyProgressChange(downloadInfo);
}
} catch (Exception e) {
e.printStackTrace();
//如果出异常,属于下载出错
downloadInfo.setState(STATE_ERROR);
downloadInfo.setCurrentLength(0);
file.delete();//删除无效文件
notifyStateChange(downloadInfo);
}finally{
//关闭流和链接
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
httpResult.close();
}
//走到这里有3种情况:a.下载完成 b.下载出错 c.下载暂停
if(file.length()==downloadInfo.getCurrentLength() && downloadInfo.getState()==STATE_DOWNLOADING){
//说明下载完成
downloadInfo.setState(STATE_FINISH);
notifyStateChange(downloadInfo);
}else if (downloadInfo.getState()==STATE_PAUSE) {
//暂停状态
notifyStateChange(downloadInfo);
}else {
//下载出错
downloadInfo.setState(STATE_ERROR);
downloadInfo.setCurrentLength(0);
file.delete();//删除无效文件
notifyStateChange(downloadInfo);
}
}else {
//服务器返回错误,属于下载出错
downloadInfo.setState(STATE_ERROR);
downloadInfo.setCurrentLength(0);
file.delete();//删除无效文件
notifyStateChange(downloadInfo);
}
//task结束时需要将当前runnable从downloadTaskMap中移除
downloadTaskMap.remove(downloadInfo.getId());
}
}
/**
* 暂停
*/
public void pause(AppInfo appInfo){
DownloadInfo downloadInfo = downloadInfoMap.get(appInfo.getId());
if(downloadInfo!=null){
DownloadTask downloadTask = downloadTaskMap.get(downloadInfo.getId());
ThreadPoolManager.getInstance().cancel(downloadTask);
//更新状态为暂停
downloadInfo.setState(STATE_PAUSE);
notifyStateChange(downloadInfo);
}
}
public DownloadInfo getDownloadInfo(AppInfo appInfo) {
return downloadInfoMap.get(appInfo.getId());
}
/**
* 安装apk
*/
public void installApk(AppInfo appInfo){
DownloadInfo downloadInfo = downloadInfoMap.get(appInfo.getId());
if(downloadInfo!=null){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://"+downloadInfo.getPath()), "application/vnd.android.package-archive");
GooglePlayApplication.getContext().startActivity(intent);
}
}
/**
* 通知所有的监听器状态更新了
* @param downloadInfo
*/
private void notifyStateChange(DownloadInfo downloadInfo){
for (DownloadObserver observer : observers) {
observer.onDownloadStateChange(downloadInfo);
}
}
/**
* 通知所有的监听器下载进度更新了
* @param downloadInfo
*/
private void notifyProgressChange(DownloadInfo downloadInfo){
for (DownloadObserver observer : observers) {
observer.onDownloadProgressChange(downloadInfo);
}
}
/**
* 注册下载监听
*/
public void registerDownloadObserver(DownloadObserver downloadObserver){
if(downloadObserver!=null && !observers.contains(downloadObserver)){
observers.add(downloadObserver);
}
}
/**
* 取消下载监听
*/
public void unregisterDownloadObserver(DownloadObserver downloadObserver){
if(downloadObserver!=null && observers.contains(downloadObserver)){
observers.remove(downloadObserver);
}
}
/**
* 下载监听
* @author Administrator
*
*/
public interface DownloadObserver{
void onDownloadStateChange(DownloadInfo downloadInfo);
void onDownloadProgressChange(DownloadInfo downloadInfo);
}
}