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 ...
随机推荐
- regress_partition.sql
--ENV --UAT @/test/change/env/env_test_uat.sql set echo on time on timing on set feedback on set pag ...
- 51nod 修改数组
修改数组 给出一个整数数组A,你可以将任何一个数修改为任意一个正整数,最终使得整个数组是严格递增的且均为正整数.问最少需要修改几个数? Input 第1行:一个数N表示序列的长度(1 <= N ...
- PAT (Advanced Level) 1058. A+B in Hogwarts (20)
简单题. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #in ...
- WebDriver(Selenium2) 判断页面是否刷新的方法
http://uniquepig.iteye.com/blog/1568208 public static boolean waitPageRefresh(WebElement trigger) { ...
- base库插件---form
$().extend('serialize', function () { for (var i = 0; i < this.elements.length; i ++) { var form ...
- ZBUS = MQ + RPC
http://git.oschina.net/rushmore/zbus http://my.oschina.net/sbz/blog Readme.md 18.02 KB ZBUS = MQ + ...
- jquery全选框的实现
函数实现的话: head里加入函数实现 <script language="javascript" type="text/javascript"> ...
- Android init.rc文件浅析
Android init.rc文件浅析 分类: Android2012-04-13 18:00 13149人阅读 评论(2) 收藏 举报 androidservicepathactionsocketc ...
- linux shell 之if-------用if做判断
综合网络,略有修改, 一 简介 1 字符串判断 str1 = str2 当两个串有相同内容.长度时为真 str1 != str2 当串str1和str2不等时为真 -n str1 当串的长度大于0 ...
- CORBA技术及实例
CORBA技术及实例 CORBA是一种规范,它定义了分布式对象如何实现互操作.在WorldWideWeb盛行之前,非凡是java编程语言风靡之前,C++开发者基本将CORBA作为其高端分布式对象的解决 ...