全志代码首次提交
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.download;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Global executor pools for the whole application.
|
||||
* <p>
|
||||
* Grouping tasks like this avoids the effects of task starvation (e.g. disk reads don't wait behind
|
||||
* webservice requests).
|
||||
*/
|
||||
public class AppExecutors {
|
||||
private static AppExecutors appExecutors;
|
||||
private final Executor diskIO;
|
||||
|
||||
private final Executor networkIO;
|
||||
|
||||
private final Executor mainThread;
|
||||
|
||||
private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
|
||||
this.diskIO = diskIO;
|
||||
this.networkIO = networkIO;
|
||||
this.mainThread = mainThread;
|
||||
}
|
||||
|
||||
private AppExecutors() {
|
||||
this(Executors.newSingleThreadExecutor(), Executors.newFixedThreadPool(3),
|
||||
new MainThreadExecutor());
|
||||
}
|
||||
|
||||
public static AppExecutors getAppExecutors() {
|
||||
if (appExecutors == null)
|
||||
return new AppExecutors();
|
||||
else
|
||||
return appExecutors;
|
||||
}
|
||||
|
||||
public Executor diskIO() {
|
||||
return diskIO;
|
||||
}
|
||||
|
||||
public Executor networkIO() {
|
||||
return networkIO;
|
||||
}
|
||||
|
||||
public Executor mainThread() {
|
||||
return mainThread;
|
||||
}
|
||||
|
||||
private static class MainThreadExecutor implements Executor {
|
||||
private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
mainThreadHandler.post(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
package com.android.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.database.DaoManager;
|
||||
import com.android.database.lib.DownLoadTaskBean;
|
||||
import com.android.util.GsonUtil;
|
||||
import com.android.util.LogUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class DownLoadManeger {
|
||||
|
||||
private static DownLoadManeger instance;
|
||||
private boolean isAuto = false;
|
||||
|
||||
private DownloadListener mDownloadListener;
|
||||
|
||||
public void registerDownloadListener(DownloadListener downloadListener){
|
||||
this.mDownloadListener = downloadListener;
|
||||
}
|
||||
public void unRegisterDownloadListener(DownloadListener downloadListener){
|
||||
this.mDownloadListener = null;
|
||||
}
|
||||
|
||||
private DownLoadManeger(Context context) {
|
||||
DaoManager.initeDao(context);
|
||||
}
|
||||
|
||||
public static DownLoadManeger init(Context context){
|
||||
if (instance == null)
|
||||
instance = new DownLoadManeger(context);
|
||||
return instance;
|
||||
}
|
||||
public static DownLoadManeger getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**添加新的下载任务*/
|
||||
public void addDownloadTask(DownloadBuilder builder){
|
||||
if (TextUtils.isEmpty(builder.url)){
|
||||
return;
|
||||
}
|
||||
DownLoadTaskBean downLoadTaskBean = null;
|
||||
if(!isExistTask(builder.url)){
|
||||
downLoadTaskBean = createTaskBean(builder);
|
||||
|
||||
}else {
|
||||
LogUtils.loge("该下载任务已存在无需下载:");
|
||||
return;
|
||||
}
|
||||
//添加下载任务队列
|
||||
if( !TaskQueue.getInstance().isExistTask(downLoadTaskBean)) {
|
||||
TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));//添加到下载队列中
|
||||
}else {
|
||||
LogUtils.loge("该下载任务已存在:"+ GsonUtil.GsonString(downLoadTaskBean));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**下载没有完成的任务管理*/
|
||||
public void restDownloadTask(){
|
||||
List<DownLoadTaskBean> list = DaoManager.getInstance().queryList(DownLoadTaskBean.class); //未完成下载的任务
|
||||
|
||||
if(list.size()>0){
|
||||
LogUtils.loge("start download");
|
||||
for (DownLoadTaskBean downLoadTaskBean:list){
|
||||
//添加下载任务队列
|
||||
if( !TaskQueue.getInstance().isExistTask(downLoadTaskBean)) {
|
||||
TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));//添加到下载队列中
|
||||
}
|
||||
}
|
||||
}else {
|
||||
LogUtils.loge("no download task");
|
||||
}
|
||||
}
|
||||
|
||||
/**清除任务队列*/
|
||||
public void clear(){
|
||||
TaskQueue.getInstance().clear();
|
||||
}
|
||||
|
||||
public boolean isExistTask(String url) {//判断是否存在下载任务
|
||||
List<DownLoadTaskBean> downLoadTaskBeans = DaoManager.getInstance().queryByKeyList(DownLoadTaskBean.class,"url",url);
|
||||
if(downLoadTaskBeans!=null&&downLoadTaskBeans.size()==1){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private DownLoadTaskBean createTaskBean(DownloadBuilder builder) {//创建下载任务bean和创建下载任务
|
||||
DownLoadTaskBean bean = new DownLoadTaskBean();
|
||||
bean.setFileName(builder.name);
|
||||
bean.setPath(builder.path);
|
||||
bean.setUrl(builder.url);
|
||||
bean.setTaskId(System.currentTimeMillis());
|
||||
bean.setListener(builder.listener);
|
||||
bean.setTotal(builder.total);
|
||||
bean.setMinType(builder.minType);
|
||||
bean.setTaskType(builder.taskType);
|
||||
DownLoadTaskThread task = new DownLoadTaskThread(bean, observer);
|
||||
DaoManager.getInstance().insert(DownLoadTaskBean.class, bean);//保存到数据库
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//自动下载
|
||||
public void setAutoDownLoad(boolean isAuto) {
|
||||
this.isAuto = isAuto;
|
||||
}
|
||||
|
||||
public void pauseAll() {//全部暂停
|
||||
TaskQueue.getInstance().pause();
|
||||
}
|
||||
|
||||
public void clearTaskInteruptQueueAndRestart() {
|
||||
List<DownLoadTaskBean> list = DaoManager.getInstance().queryList(DownLoadTaskBean.class);
|
||||
for (DownLoadTaskBean downLoadTaskBean:list) {
|
||||
if(!TextUtils.isEmpty(downLoadTaskBean.getUrl())&&!TextUtils.isEmpty(downLoadTaskBean.getFileName())&&!TextUtils.isEmpty(downLoadTaskBean.getPath())){
|
||||
File file = new File(downLoadTaskBean.getPath()+downLoadTaskBean.getFileName()+"-tmp");
|
||||
if(file.exists()&&downLoadTaskBean.getCurrentProgress()==file.length()&&file.length()<=downLoadTaskBean.getTotal()){
|
||||
TaskQueue.getInstance().remove(downLoadTaskBean);
|
||||
TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateDownloadTaskBeanTable() {
|
||||
List<DownLoadTaskBean> list = DaoManager.getInstance().queryList(DownLoadTaskBean.class);
|
||||
for (DownLoadTaskBean downLoadTaskBean:list) {
|
||||
if(downLoadTaskBean.getCurrentProgress()==0&&!TextUtils.isEmpty(downLoadTaskBean.getUrl())&&!TextUtils.isEmpty(downLoadTaskBean.getFileName())&&!TextUtils.isEmpty(downLoadTaskBean.getPath())){
|
||||
File file = new File(downLoadTaskBean.getPath()+downLoadTaskBean.getFileName()+"-tmp");
|
||||
if(file.exists()&&file.length()>0&&file.length()<=downLoadTaskBean.getTotal()){
|
||||
downLoadTaskBean.setCurrentProgress(file.length());
|
||||
DaoManager.getInstance().update(DownLoadTaskBean.class,downLoadTaskBean);
|
||||
}
|
||||
}else if(downLoadTaskBean.getCurrentProgress()!=0&&!TextUtils.isEmpty(downLoadTaskBean.getUrl())&&!TextUtils.isEmpty(downLoadTaskBean.getFileName())&&!TextUtils.isEmpty(downLoadTaskBean.getPath())){
|
||||
File file = new File(downLoadTaskBean.getPath()+downLoadTaskBean.getFileName()+"-tmp");
|
||||
if(file.exists()&&file.length()>downLoadTaskBean.getCurrentProgress()&&file.length()<=downLoadTaskBean.getTotal()){
|
||||
downLoadTaskBean.setCurrentProgress(file.length());
|
||||
DaoManager.getInstance().update(DownLoadTaskBean.class,downLoadTaskBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class DownloadBuilder {//构造器
|
||||
protected String url;//下载地址
|
||||
protected String path;//下载路径
|
||||
protected String name;//文件名字
|
||||
protected long total;//现在总进度
|
||||
/**文件类型*/
|
||||
protected String minType;
|
||||
/**任务类型*/
|
||||
protected int taskType;
|
||||
protected DownLoadTaskBean.DownLoadListener listener;//下载监听
|
||||
|
||||
|
||||
public DownloadBuilder setMinType(String minType) {
|
||||
this.minType = minType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder url(String url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder filePath(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder listener(DownLoadTaskBean.DownLoadListener listener) {
|
||||
this.listener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder fileName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder taskType(int taskType) {
|
||||
this.taskType = taskType;
|
||||
return this;
|
||||
}
|
||||
public DownloadBuilder fileTotal(long fileSize){
|
||||
this.total =fileSize;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface DownloadListener{
|
||||
public void onStart(DownLoadTaskBean bean, long taskId);
|
||||
public void onError(DownLoadTaskBean bean, long taskId, String erroMsg);
|
||||
public void onProgress(DownLoadTaskBean bean, long taskId, long progress);
|
||||
public void onFinish(DownLoadTaskBean bean, long taskId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//下载线程的观察者
|
||||
private DownLoadTaskThread.DownloadTaskObserver observer = new DownLoadTaskThread.DownloadTaskObserver() {
|
||||
@Override
|
||||
protected void onStart(DownLoadTaskBean bean, long taskId) {//下载开始,回调总进度给监听,方便设置进度大小
|
||||
LogUtils.loge("taskId=" + taskId + ">>>>>" + bean.getTotal());
|
||||
bean.setStatus(0);
|
||||
AppExecutors.getAppExecutors().mainThread().execute(() -> {//切换到主线程
|
||||
if (bean.getListener() != null) {
|
||||
bean.getListener().onStart(bean.getTotal());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgress(DownLoadTaskBean bean, long taskId, long progress) {//进度调用
|
||||
synchronized (this) {//这里必须加同步代码块,因为这共用进度等变量
|
||||
|
||||
|
||||
if(mDownloadListener!=null){
|
||||
mDownloadListener.onProgress(bean,taskId,progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinish(DownLoadTaskBean bean, long taskId, long lastProgress) {
|
||||
synchronized (this) {
|
||||
LogUtils.loge("download Exception===>sleeping finish");
|
||||
TaskQueue.getInstance().remove(bean);//单个任务完成删除
|
||||
DaoManager.getInstance().delete(DownLoadTaskBean.class, bean);
|
||||
if(mDownloadListener!=null){
|
||||
mDownloadListener.onFinish(bean,taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause(DownLoadTaskBean bean, long taskId, long currentProgress) {
|
||||
synchronized (this) {//暂停这里必须加上同步,不然会出现实际进度跟显示进度不一致问题,其实也就是缓存没存进去,第二个线程又来了
|
||||
// DaoManager.getInstance().update(DownLoadTaskBean.class, bean);//更新数据库,退出app再进来就不会从头下载
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onError(DownLoadTaskBean bean, long taskId, String erroMsg) {//错误提示
|
||||
|
||||
if(mDownloadListener!=null){
|
||||
mDownloadListener.onError(bean,taskId,erroMsg);
|
||||
TaskQueue.getInstance().remove(bean);
|
||||
// DaoManager.getInstance().delete(DownLoadTaskBean.class, bean);//删除数据库缓存
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package com.android.download;
|
||||
|
||||
|
||||
|
||||
import com.android.database.lib.DownLoadTaskBean;
|
||||
import com.android.util.LogUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
public class DownLoadTaskThread implements Runnable {
|
||||
private boolean pause;
|
||||
private DownLoadTaskBean bean;
|
||||
private long currentTotal = 0;
|
||||
private DownloadTaskObserver observer;
|
||||
|
||||
public DownLoadTaskThread(DownLoadTaskBean bean, DownloadTaskObserver observer) {
|
||||
this.bean = bean;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
HttpURLConnection urlConnection=null;
|
||||
RandomAccessFile randomFile=null;
|
||||
InputStream inputStream =null;
|
||||
try {
|
||||
URL url = new URL(bean.getUrl());
|
||||
urlConnection = (HttpURLConnection) url.openConnection();
|
||||
urlConnection.setConnectTimeout(20000); //设置连接超时事件为20秒
|
||||
urlConnection.setRequestMethod("GET"); //设置请求方式为GET
|
||||
//设置用户端可以接收的媒体类型
|
||||
urlConnection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, " +
|
||||
"image/pjpeg, application/x-shockwave-flash, application/xaml+xml, " +
|
||||
"application/vnd.ms-xpsdocument, application/x-ms-xbap," +
|
||||
" application/x-ms-application, application/vnd.ms-excel," +
|
||||
" application/vnd.ms-powerpoint, application/msword, */*");
|
||||
|
||||
urlConnection.setRequestProperty("Accept-Language", "zh-CN"); //设置用户语言
|
||||
urlConnection.setRequestProperty("Charset", "UTF-8"); //设置客户端编码
|
||||
//设置用户代理
|
||||
urlConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; " +
|
||||
"Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727;" +
|
||||
" .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
|
||||
|
||||
File dataFile = new File(bean.getPath(), bean.getFileName());
|
||||
if(dataFile.exists()&&dataFile.length()==bean.getTotal()){ //判断该文件已下载无需再下载
|
||||
observer.onFinish(bean, bean.getTaskId(), dataFile.length());
|
||||
return;
|
||||
}
|
||||
|
||||
//设置文件写入位置
|
||||
File file = new File(bean.getPath(), bean.getFileName()+"-tmp");
|
||||
if(!file.exists()){
|
||||
file.createNewFile();
|
||||
}
|
||||
currentTotal = file.length();
|
||||
LogUtils.loge(bean.getStart() + "start------" + currentTotal + ">>>>" + bean.getTotal());
|
||||
if(currentTotal==bean.getTotal()){
|
||||
File targFile = new File(bean.getPath(), bean.getFileName());
|
||||
file.renameTo(targFile);//重命名
|
||||
file.delete();//删除临时文件
|
||||
Thread.sleep(5000);
|
||||
observer.onFinish(bean, bean.getTaskId(), currentTotal);
|
||||
return;
|
||||
}
|
||||
//设置下载位置
|
||||
urlConnection.setRequestProperty("Range", "bytes=" + currentTotal + "-");
|
||||
|
||||
randomFile = new RandomAccessFile(file, "rwd");
|
||||
randomFile.seek(currentTotal);
|
||||
urlConnection.connect();
|
||||
if (observer != null) {
|
||||
observer.onStart(bean, bean.getTaskId());
|
||||
}
|
||||
|
||||
//获得文件流
|
||||
inputStream = urlConnection.getInputStream();
|
||||
byte[] buffer = new byte[1024*10];
|
||||
int len;
|
||||
long time = System.currentTimeMillis();
|
||||
while ( (currentTotal!=bean.getTotal())&&(len = inputStream.read(buffer)) != -1) {
|
||||
|
||||
//写入文件
|
||||
randomFile.write(buffer, 0, len);
|
||||
currentTotal += len;
|
||||
//时间间隔大于500ms再发
|
||||
if (System.currentTimeMillis() - time > 500) {
|
||||
time = System.currentTimeMillis();
|
||||
observer.onProgress(bean, bean.getTaskId(), currentTotal);
|
||||
}
|
||||
//判断是否是暂停状态.保存断点
|
||||
if (observer != null && pause) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
urlConnection.disconnect();
|
||||
urlConnection=null;
|
||||
randomFile.close();
|
||||
randomFile=null;
|
||||
inputStream.close();
|
||||
inputStream=null;
|
||||
|
||||
observer.onProgress(bean, bean.getTaskId(), currentTotal);
|
||||
|
||||
if (observer != null && !pause) {
|
||||
if(currentTotal == bean.getTotal()) {
|
||||
LogUtils.loge("下载完成");
|
||||
LogUtils.loge("download Exception===>sleeping before");
|
||||
File targFile = new File(bean.getPath(), bean.getFileName());
|
||||
file.renameTo(targFile);//重命名
|
||||
file.delete();//删除临时文件
|
||||
Thread.sleep(5000);
|
||||
LogUtils.loge("download Exception===>sleeping after");
|
||||
observer.onFinish(bean, bean.getTaskId(), currentTotal);
|
||||
}else {
|
||||
LogUtils.loge("下载失败");
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "下载失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
LogUtils.loge("download Exception===>"+e.getMessage());
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), e.getMessage());
|
||||
}
|
||||
}finally {
|
||||
if(urlConnection!=null) {
|
||||
urlConnection.disconnect();
|
||||
urlConnection=null;
|
||||
}
|
||||
try {
|
||||
if(randomFile!=null) {
|
||||
randomFile.close();
|
||||
randomFile=null;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
if(inputStream!=null) {
|
||||
inputStream.close();
|
||||
inputStream=null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DownLoadTaskBean getBean() {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public void setBean(DownLoadTaskBean bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
public void setPause(boolean pause) {
|
||||
this.pause = pause;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected static abstract class DownloadTaskObserver {
|
||||
|
||||
protected abstract void onStart(DownLoadTaskBean bean, long taskId);
|
||||
|
||||
protected abstract void onProgress(DownLoadTaskBean bean, long taskId, long progress);
|
||||
|
||||
protected abstract void onFinish(DownLoadTaskBean bean, long taskId, long lastProgress);
|
||||
|
||||
protected abstract void onPause(DownLoadTaskBean bean, long taskId, long currentProgress);
|
||||
|
||||
protected abstract void onError(DownLoadTaskBean bean, long taskId, String erroMsg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.android.download;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.util.FileUtil;
|
||||
import com.android.util.LogUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
public class DownloadAppTask extends Thread{
|
||||
public static int threadCount = 3;
|
||||
public static int runningThread = 3;
|
||||
private String downurl;
|
||||
private Context mContext;
|
||||
/**存储路径*/
|
||||
private String FILEPATH_STORAGE;
|
||||
|
||||
/**临时文件名称*/
|
||||
public static String FILENAME_TMP="Nebula-app.bak";
|
||||
/**正是文件名称*/
|
||||
private static String FILENAME_APK="Nebula-app.apk";
|
||||
private DownLoadAppListener mDownLoadAppListener;
|
||||
private long startIndex = 0;
|
||||
private long totalSize = 0;
|
||||
|
||||
public DownloadAppTask(Context context,String versionCode,String url,long fileSize,DownLoadAppListener downLoadAppListener){
|
||||
mContext = context;
|
||||
this.downurl = url;
|
||||
this.totalSize = fileSize;
|
||||
this.mDownLoadAppListener = downLoadAppListener;
|
||||
this.FILEPATH_STORAGE = FileUtil.getBakPath(mContext,1) ;
|
||||
FILENAME_APK=versionCode+"-"+FILENAME_APK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
super.run();
|
||||
|
||||
try {
|
||||
|
||||
|
||||
File tempfile =new File(FILEPATH_STORAGE,FILENAME_TMP);
|
||||
|
||||
if(tempfile.exists()){
|
||||
startIndex = tempfile.length();
|
||||
}else {
|
||||
tempfile.createNewFile();
|
||||
}
|
||||
|
||||
HttpURLConnection urlConnection;
|
||||
URL url = new URL(downurl);
|
||||
// URL url = new URL(" https://ik-cos-1258208609.cos.ap-guangzhou.myqcloud.com/Chrome.apk");
|
||||
|
||||
urlConnection = (HttpURLConnection) url.openConnection();
|
||||
urlConnection.setConnectTimeout(2000*10); //设置连接超时事件为5秒
|
||||
urlConnection.setRequestMethod("GET"); //设置请求方式为GET
|
||||
//设置用户端可以接收的媒体类型
|
||||
urlConnection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, " +
|
||||
"image/pjpeg, application/x-shockwave-flash, application/xaml+xml, " +
|
||||
"application/vnd.ms-xpsdocument, application/x-ms-xbap," +
|
||||
" application/x-ms-application, application/vnd.ms-excel," +
|
||||
" application/vnd.ms-powerpoint, application/msword, */*");
|
||||
|
||||
urlConnection.setRequestProperty("Accept-Language", "zh-CN"); //设置用户语言
|
||||
urlConnection.setRequestProperty("Charset", "UTF-8"); //设置客户端编码
|
||||
//设置用户代理
|
||||
urlConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; " +
|
||||
"Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727;" +
|
||||
" .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
|
||||
//设置下载位置
|
||||
urlConnection.setRequestProperty("Range", "bytes=" + startIndex + "-" + (totalSize-1));
|
||||
LogUtils.loge("totalSize:"+totalSize+"");
|
||||
LogUtils.loge("getResponseCode:"+urlConnection.getResponseCode()+"");
|
||||
InputStream in = urlConnection.getInputStream();
|
||||
RandomAccessFile raf = new RandomAccessFile(tempfile.getPath(), "rwd");
|
||||
raf.seek(startIndex);
|
||||
int len = 0;
|
||||
int progress=0;
|
||||
byte buf[] =new byte[1024];
|
||||
while((len = in.read(buf))!=-1){
|
||||
raf.write(buf, 0, len);
|
||||
progress+=len;
|
||||
LogUtils.loge("downlaod progress:"+progress);
|
||||
}
|
||||
in.close();
|
||||
raf.close();
|
||||
|
||||
|
||||
File apkFile = new File(FILEPATH_STORAGE,FILENAME_APK);
|
||||
LogUtils.loge("downlaod:"+tempfile.length());
|
||||
if(tempfile.length()==totalSize){
|
||||
tempfile.renameTo(apkFile);
|
||||
tempfile.delete();
|
||||
//下载完成
|
||||
if(mDownLoadAppListener!=null){
|
||||
mDownLoadAppListener.onDowanlaodResult(0,apkFile.getPath());
|
||||
}
|
||||
|
||||
|
||||
}else {
|
||||
if(mDownLoadAppListener!=null){
|
||||
mDownLoadAppListener.onDowanlaodResult(-1,null);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if(mDownLoadAppListener!=null){
|
||||
mDownLoadAppListener.onDowanlaodResult(-1,null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// public boolean executeAppInstall(String apkPath){
|
||||
// boolean result = false;
|
||||
// try {
|
||||
// Runtime.getRuntime().exec("su");
|
||||
// String command = "pm install -r " + apkPath + "\n";
|
||||
// Process process = Runtime.getRuntime().exec(command);
|
||||
// BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||
// String msg = "";
|
||||
// String line;
|
||||
// while ((line = errorStream.readLine()) != null) {
|
||||
// msg += line;
|
||||
// }
|
||||
// if (!msg.contains("Failure")) {
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public interface DownLoadAppListener{
|
||||
public void onDowanlaodResult(int status,String filePath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package com.android.download;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
||||
import com.android.api.biz.CoreKeys;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
public class DownloadService {
|
||||
|
||||
/**
|
||||
* 是否正在下载
|
||||
*/
|
||||
private boolean isDownloading=false;
|
||||
public static int progress;
|
||||
private String dowUrl = null;
|
||||
//下载状态
|
||||
private int status = -1;
|
||||
private int fileSize;
|
||||
private int readSize;
|
||||
private int downSize;
|
||||
private File downFile;
|
||||
private static DownloadService mInstance = null;
|
||||
private DownlaodProgressCallBack mDownlaodProgressCallBack;
|
||||
/**下载完成状态*/
|
||||
public static final int DOWNLOAD_COMPLETE=0;
|
||||
/**下载完成状态*/
|
||||
public static final int DOWNLOAD_ERROR=-1;
|
||||
public static final String FEATURE_PATH = CoreKeys.down_file+"atv.apk";
|
||||
private Handler handler = new Handler(){
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
super.handleMessage(msg);
|
||||
switch (msg.what) {
|
||||
case 0:
|
||||
// //更新下载进度
|
||||
if(mDownlaodProgressCallBack!=null){
|
||||
int progress = (int) ((double) downSize / (double) fileSize * 100);
|
||||
mDownlaodProgressCallBack.onDownlaodProgress(progress);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
//下载完成进度
|
||||
mDownlaodProgressCallBack.onDownlaodStatus(DOWNLOAD_COMPLETE);
|
||||
break;
|
||||
case 2:
|
||||
//下载异常
|
||||
mDownlaodProgressCallBack.onDownlaodStatus(DOWNLOAD_ERROR);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private DownloadService(){
|
||||
}
|
||||
|
||||
public static DownloadService initDownloadService(){
|
||||
if(mInstance ==null){
|
||||
mInstance = new DownloadService();
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
public static DownloadService getInstance(){
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
public void initDownLoadUrl(String downloadUrl){
|
||||
dowUrl = downloadUrl;
|
||||
}
|
||||
|
||||
public void setDownlaodProgressCallBack(DownlaodProgressCallBack downlaodProgressCallBack){
|
||||
this.mDownlaodProgressCallBack = downlaodProgressCallBack;
|
||||
}
|
||||
|
||||
|
||||
public void startService(){
|
||||
if(isDownloading){
|
||||
return;
|
||||
}
|
||||
new Thread(startDownload).start();
|
||||
}
|
||||
|
||||
public void stopService(){
|
||||
isDownloading = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载模块
|
||||
*/
|
||||
private Runnable startDownload = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
fileSize = 0;
|
||||
readSize = 0;
|
||||
downSize = 0;
|
||||
progress = 0;
|
||||
|
||||
InputStream is = null;
|
||||
FileOutputStream fos = null;
|
||||
Log.e("downUrl", dowUrl);
|
||||
try {
|
||||
URL myURL = new URL(dowUrl);
|
||||
URLConnection conn = myURL.openConnection();
|
||||
conn.connect();
|
||||
fileSize = conn.getContentLength();
|
||||
is = conn.getInputStream();
|
||||
|
||||
if (is == null) {
|
||||
Log.d("tag", "error");
|
||||
throw new RuntimeException("stream is null");
|
||||
}
|
||||
|
||||
File dir = new File(CoreKeys.down_file);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
downFile = new File(FEATURE_PATH);
|
||||
fos = new FileOutputStream(downFile);
|
||||
byte buf[] = new byte[1024 * 1024];
|
||||
isDownloading = true;
|
||||
while ((readSize = is.read(buf)) > 0) {
|
||||
if(!isDownloading){
|
||||
return;
|
||||
}
|
||||
fos.write(buf, 0, readSize);
|
||||
downSize += readSize;
|
||||
Log.e("downSize", downSize+"");
|
||||
sendMessage(0,downSize);
|
||||
}
|
||||
sendMessage(1);
|
||||
isDownloading = false;
|
||||
|
||||
} catch (Exception e) {
|
||||
sendMessage(2);
|
||||
} finally {
|
||||
try {
|
||||
if (null != fos) fos.close();
|
||||
if (null != is) is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private void sendMessage(int code){
|
||||
handler.sendEmptyMessage(code);
|
||||
}
|
||||
|
||||
private void sendMessage(int code,int progress){
|
||||
Message message = new Message();
|
||||
message.what=code;
|
||||
message.arg1 = progress;
|
||||
handler.sendMessage(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取进度
|
||||
*/
|
||||
public int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public interface DownlaodProgressCallBack{
|
||||
|
||||
public void onDownlaodProgress(int progress);
|
||||
public void onDownlaodStatus(int status);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
88
mylibrary/src/main/java/com/android/download/TaskQueue.java
Normal file
88
mylibrary/src/main/java/com/android/download/TaskQueue.java
Normal file
@@ -0,0 +1,88 @@
|
||||
package com.android.download;
|
||||
|
||||
|
||||
import com.android.database.lib.DownLoadTaskBean;
|
||||
import com.android.util.GsonUtil;
|
||||
import com.android.util.LogUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class TaskQueue {
|
||||
private static TaskQueue instance;
|
||||
private List<DownLoadTaskThread> mTaskQueue;
|
||||
private ExecutorService downloadThreadCache = Executors.newFixedThreadPool(3);//这里是写死最多5个线程
|
||||
|
||||
private TaskQueue() {
|
||||
mTaskQueue = new ArrayList<>();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return mTaskQueue.size();
|
||||
}
|
||||
|
||||
public static TaskQueue getInstance() {
|
||||
if (instance == null)
|
||||
instance = new TaskQueue();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public List<DownLoadTaskThread> getAllTask() {
|
||||
return mTaskQueue;
|
||||
}
|
||||
|
||||
public void add(DownLoadTaskThread task) {
|
||||
mTaskQueue.add(task);
|
||||
downloadThreadCache.execute(task);
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
mTaskQueue.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void remove(DownLoadTaskBean p) {
|
||||
for (int i = 0; i < mTaskQueue.size(); i++) {
|
||||
DownLoadTaskThread task = mTaskQueue.get(i);
|
||||
if (task.getBean().getUrl().equals(p.getUrl())) {
|
||||
mTaskQueue.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isExistTask(DownLoadTaskBean p) {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
if (task.getBean().getUrl().equals(p.getUrl()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void pause(String url) {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
if (task.getBean().getUrl().equals(url)) {
|
||||
task.setPause(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
task.setPause(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void start(String url) {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
if (task.getBean().getUrl().equals(url)) {
|
||||
task.setPause(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user