Android实现版本更新
Android 实现从后台下载apk文件,保存到本地sd卡,使用系统安装apk,完成版本更新功能
LoadAppUtil.java
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List; /**
* Depiction:
* Author: kuzan
* Date: 2017/01/14 9:42
*/
public class LoadAppUtil { private static List<String> list = new ArrayList<>();
private static final int TIMEOUT = 10 * 60 * 1000; // 超时 public static final int LOAD_PROCESS = 1;
public static final int LOAD_SUCCEED = 2;
public static final int LOAD_ERROR = 3; /**
* 下载apk
* @param context
* @param packageName 保存apk的名称
* @param url apk后台下载的地址
*/
public static void loadApp(Context context, final String packageName, final String url) { final String path = getLoadAppPath(context, packageName); if (StringUtils.isEmptyString(path) || StringUtils.isEmptyString(url)) {
loadError(packageName);
return;
} // 判断是否在下载
if (list.contains(packageName)) {
return;
} list.add(packageName); new Thread(new Runnable() {
@Override
public void run() {
downloadUpdateFile(packageName, url, path);
}
}).start();
} /**
* 文件下载
* @param packageName 保存apk的名称
* @param down_url apk后台下载的地址
* @param file 保存apk的文件路径
* */
public static void downloadUpdateFile(String packageName, String down_url, String file) { int totalSize = 0; // 文件总大小
InputStream in = null;
FileOutputStream fos = null; FileUtils.deleteFile(file);
FileUtils.createFile(file); URL url;
try {
url = new URL(down_url); HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection(); httpURLConnection.setConnectTimeout(TIMEOUT); httpURLConnection.setReadTimeout(TIMEOUT); // 获取下载文件的size
totalSize = httpURLConnection.getContentLength();
Log.e("LoadAppUtil", "totalSize = " + totalSize); if (httpURLConnection.getResponseCode() == 404) {
loadError(packageName);
return;
} in = httpURLConnection.getInputStream();
fos = new FileOutputStream(file, false);
} catch (IOException e) {
e.printStackTrace();
loadError(packageName);
return;
} int downloadCount = 0; // 已下载大小
int updateProgress = 0; // 更新进度 byte buffer[] = new byte[64];
int readsize = 0; try {
LoadBean bean = new LoadBean(packageName,file,0);
post(LOAD_PROCESS,bean);
while ((readsize = in.read(buffer)) != -1) { fos.write(buffer, 0, readsize); // 计算已下载到的大小
downloadCount += readsize; // 先计算已下载的百分比,然后跟上次比较是否有增加,有则更新通知进度
int now = downloadCount * 100 / totalSize;
// Log.e(TAG, "now = " + now) ;
if (updateProgress < now) {
updateProgress = now;
// 发送下载进度
bean.setProcess(now);
post(LOAD_PROCESS,bean);
}
}
} catch (Exception e) {
e.printStackTrace();
loadError(packageName);
return;
} finally {
try {
fos.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
} // 发送下载完成消息
if(list.contains(packageName)){
list.remove(packageName);
LoadBean bean = new LoadBean(packageName,file,100);
post(LOAD_SUCCEED,bean);
} } private static void loadError(String packageName) {
if (list.contains(packageName)) {
list.remove(packageName);
}
// 发送下载错误消息
LoadBean bean = new LoadBean(packageName,"",0);
post(LOAD_ERROR,bean);
} /**
* 获取保存apk的文件路径
*
* @param context
* @return
*/
public static String getLoadAppPath(Context context, String packageName) {
if (FileUtils.isSdCardExist()) {
return context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + packageName + ".apk";
}
return "";
} /**
* 判断文件是否存在
* @param path 文件路径
* @return
*/
public static boolean isFileExists(String path) {
if (TextUtils.isEmpty(path)) {
return false;
}
try {
File f=new File(path);
if(!f.exists()) {
return false;
}
}
catch (Exception e) {
return false;
} return true;
} /**
* 通知UI
* */
public static void post(int clickId,LoadBean bean){
RxBus.getDefault().post(RxBusEvent.newBuilder(R.id.load_apk).clickId(clickId).setObj(bean).build());
}
}
调用方法:
LoadAppUtil.loadApp(UpdateActivity.this, newVersionName, UrlConstants.UPLOAD_URL);
信息读取:(使用的消息通知是android RxBus)
mySubscriptions.add(RxBus.getDefault().toObserverable(RxBusEvent.class).subscribe(new Action1<RxBusEvent>() {
@Override
public void call(final RxBusEvent rxBusEvent) {
if (rxBusEvent.getType() == R.id.load_apk) {
switch (rxBusEvent.getClickId()) {
case LoadAppUtil.LOAD_SUCCEED:
runOnUiThread(new Runnable() {
@Override
public void run() {
// 下载完成
Log.e("LOAD", "LOAD_SUCCEED");
AppUtils.installApp(UpdateActivity.this, (LoadBean) rxBusEvent.getObj().getPath());
isLoadFinish = true;
}
});
break;
case LoadAppUtil.LOAD_PROCESS:
runOnUiThread(new Runnable() {
@Override
public void run() {
// 下载进度
isLoadFinish = false;
updateProgress((LoadBean) rxBusEvent.getObj());
}
});
break;
case LoadAppUtil.LOAD_ERROR:
runOnUiThread(new Runnable() {
@Override
public void run() {
// 下载出错
Log.e("upload", "err");
isLoadFinish = false;
ToastUtils.ToastMessage(UpdateActivity.this, "下载失败");
}
});
break;
}
}
}
}));
LoadBean.java
public class LoadBean {
private String packageName;
private String path;
private int process;
public LoadBean(String packageName, String path, int process) {
this.packageName = packageName;
this.path = path;
this.process = process;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getProcess() {
return process;
}
public void setProcess(int process) {
this.process = process;
}
}
Android实现版本更新的更多相关文章
- android应用版本更新功能---完整版
源码下载地址:csdn下载地址:http://download.csdn.net/download/csdn576038874/9526085 博客园下载地址:http://files.cnblogs ...
- Android程序版本更新--通知栏更新下载安装(转)
Android应用检查版本更新后,在通知栏下载,更新下载进度,下载完成自动安装,效果图如下: 检查当前版本号 AndroidManifest文件中的versionCode用来标识版本,在服务器放一个新 ...
- Android软件版本更新
转的:适合新手学习,但在实际项目中不可这么做. 以下是我转的内容: ================================================================= ...
- android检测版本更新
原理就是从服务器获取版本号和本得apk的版本号对比更新: //检查更新 Activity activity = this; while(activity.getParent ...
- Android提示版本更新的实现
一.首先,参考了以下文章<Android自动检测版本及自动升级> http://www.linuxidc.com/Linux/2011-10/45718p2.htm: 步骤: .检测当前版 ...
- Android关于版本更新下载安装之踩坑记录(针对7.0以上)
最近刚刚把古老的项目targetSdk版本升级到26,升级之前是19(非常非常古老了).那么升级后一些问题开始出现. Android 8.0 (Android O)为了针对一些流氓软件引导用户安装其他 ...
- Android 全局弹出版本更新 Dialog 思考和解决办法
Android 针对版本更新,需要做全局的弹出(需求:版本更新只需要在 App 内全局弹出就可以),思路是使用 AlertDialog ,然后设置 setType 为 TYPE_ALERT_WINDO ...
- Android其它新控件 (转)
原文出处:http://blog.csdn.net/lavor_zl/article/details/51312715 Android其它新控件是指非Android大版本更新时提出的新控件,也非谷歌I ...
- 从 Eclipse 迁移至 Android Studio
从 Eclipse 迁移至 Android Studio 本文内容 Android Studio 基础知识 迁移先决条件 将项目导入 Android Studio 后续步骤 将项目迁移至 Androi ...
随机推荐
- qemu -hda /dev/sdc -m 1024 -vga std
同事拿了个烂u盘让我给他做个启动盘,用cp *.iso /dev/sdc怎么也启动不了. 改用dd if=copied/20140923/debian-7.6.0-amd64-DVD-1.iso of ...
- public private proteccted区别
public公共,加上这个修饰的类或属性,可以在同一个包或者别的包里面访问 private私有的,加上这个修饰的类或属性,只能在同类里访问,同包和别的包不能访问 protected保护,加上这个修饰的 ...
- Exponential notation
Exponential notation You are given a positive decimal number x. Your task is to convert it to the &q ...
- DW常用
Dreamweaver代码 基本结构标签: <HTML>,表示该文件为HTML文件 <HEAD>,包含文件的标题,使用的脚本,样式定义等 <TITLE>---< ...
- Eclipse中常用的操作单词
Existing Project into Workspace 现有的工程引入工作空间(加载工程)File 文件New 新建Project 工程Folder 文件夹Import 引入(加载&导 ...
- urllib2修改header
python网络访问的标准模块 urllib与urllib2并不是升级版的关系,具体可见谷歌文章:difference between urllib and urllib2urllib2的官方文档:h ...
- cron expr
api docs说的很清楚,不需要去搜索, org.quartz 类 CronExpression java.lang.Object org.quartz.CronExpression 所有已实现的接 ...
- higncharts 去掉Highcharts.com链接
将credits属性设为false credits: { enabled: false },
- openstack创建实例测试步骤
source admin-openrc.shkeystone user-create --name=demo --pass=123456keystone tenant-create --name=de ...
- Keepalived详细介绍简介
1.1.Keepalived简介 Keepalived是Linux下一个轻量级别的高可用解决方案.高可用(High Avalilability,HA),其实两种不同的含义:广义来讲,是指整个系统的高可 ...