android端 版本升级
由于项目中要求实现版本升级,特写此代码,有因为这段代码基本都是通用,所以记录下来,以便下次直接拷贝...
public class ApkVersionUpdate {
/** apk文件下载状态:正在下载 */
private static final int DOWNLOADING = 1;
/** apk文件下载状态:已完成下载 */
private static final int DOWNLOADED = 2;
/** 客户端保存到sd卡的路径 */
private String savePath;
/** 下载文件对话框 */
private Dialog downloadDialog;
/** 下载进度条 */
private ProgressBar downloadProgressBar;
/** 下载文件时的进度值 */
private int progress;
/** 是否取消更新,默认为否 */
private boolean cancelUpdate = false;
private Context mContext;
private OkHttpHelper httpHelper = OkHttpHelper.getInstance();
private String downloadurl;
private String clientVersionCode;
private String desc;
private String apkName="sanxin";
public ApkVersionUpdate(Context context) {
mContext = context;
getPackageManage();
}
public void checkVersion(final boolean showProgressDialog) {
final Message msg = Message.obtain();
Map<String,Object> params = new HashMap<>();
params.put("ports","children");
httpHelper.post(HttpUrl.version_url_http, params, new SimpleCallback<Version>(mContext) {
@Override
public void onSuccess(Response response, Version item) {
if(item.getResult()==0){
List<Version.VersionItem> list = item.getList();
Version.VersionItem versionItem = list.get(0);
String serverVersionCode = versionItem.getVersion();
downloadurl =versionItem.getDownloadurl();
desc = versionItem.getDesc();
Log.e("版本",clientVersionCode+"--"+serverVersionCode);
// 当最新版本号大于当前版本号时,提示更新
if (!serverVersionCode.equals(clientVersionCode)) {
if(Integer.valueOf(versionItem.getUpdatevs())==0){
showNoticeDialog();
}else {
showNoticeDialog2();//强制更新
}
} else {
if (showProgressDialog) {
Toast.makeText(mContext, "您现在使用的是最新版本哦", Toast.LENGTH_SHORT).show();
}
}
}
}
@Override
public void onError(Response response, int code, Exception e) {
}
});
}
private void showNoticeDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("更新提醒");
builder.setMessage(desc);
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
}
});
builder.setNegativeButton("下次再说", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.setPositiveButton("立刻更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showDownloadDialog();
}
});
builder.show();
}
private void showNoticeDialog2() {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("更新提醒");
builder.setMessage(desc);
// builder.setCancelable(false);
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
}
});
builder.setPositiveButton("立刻更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
showDownloadDialog();
}
});
builder.show();
}
/**
* 展示下载对话框
*/
private void showDownloadDialog() {
// 构造对话框
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("正在下载");
// 给下载对话框增加进度条
LayoutInflater inflater = LayoutInflater.from(mContext);
View v = inflater.inflate(R.layout.version_update_progress, null);
downloadProgressBar = (ProgressBar) v.findViewById(R.id.update_progress);
builder.setView(v);
// 取消更新
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 隐藏对话框
dialog.dismiss();
// 设置取消状态
cancelUpdate = true;
}
});
downloadDialog = builder.create();
downloadDialog.show();
// 下载文件
downloadApk();
}
/**
* 下载apk文件
*/
private void downloadApk() {
new DownloadApkThread().start();
}
// 文件下载线程
private class DownloadApkThread extends Thread {
@Override
public void run() {
try {
// 判断SD卡是否存在,并且是否具有读写权限
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
// 获得存储卡的路径
String sdPath = Environment.getExternalStorageDirectory() + "/";
savePath = sdPath + "download";
URL url = new URL(downloadurl);
// 创建连接
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.connect();
// 获取文件大小
int length = conn.getContentLength();
// 创建输入流
InputStream is = conn.getInputStream();
File file = new File(savePath);
// 判断文件目录是否存在
if (!file.exists()) {
file.mkdir();
}
File apkFile = new File(savePath, apkName);
FileOutputStream fos = new FileOutputStream(apkFile);
// 已下载量
int count = 0;
// 缓存
byte buf[] = new byte[1024];
// 写入到文件中,点击取消时停止下载
while (!cancelUpdate) {
int numread = is.read(buf);
count += numread;
// 计算进度条位置
progress = (int) (((float) count / length) * 100);
// 更新进度
downloadHandler.sendEmptyMessage(DOWNLOADING);
if (numread <= 0) {
// 下载完成
downloadHandler.sendEmptyMessage(DOWNLOADED);
break;
}
// 写入文件
fos.write(buf, 0, numread);
}
fos.close();
is.close();
} else {
Toast.makeText(mContext, "当前的存储卡不可用,无法完成更新", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
// 取消下载对话框显示
downloadDialog.dismiss();
}
};
/**
* 安装apk文件
*/
private void install() {
File apkFile = new File(savePath, apkName);
if (apkFile.exists()) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + apkFile.toString()),
"application/vnd.android.package-archive");
mContext.startActivity(intent);
}
}
// 文件下载控制器
private Handler downloadHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case DOWNLOADING:
// 正在下载,更新进度条
downloadProgressBar.setProgress(progress);
break;
case DOWNLOADED:
// 下载完成,安装文件
install();
break;
default:
break;
}
}
};
private void getPackageManage() {
PackageManager packageManager = mContext.getPackageManager();
PackageInfo packInfo = null;
try {
packInfo = packageManager.getPackageInfo(
mContext.getPackageName(), 0);
String version = packInfo.versionName;
clientVersionCode = String.valueOf(packInfo.versionCode);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
/* *//**
* 多线程的下载器
*
* @param downloadurl
*//*
private void download(String downloadurl) {
// 多线程断点下载。
HttpUtils http = new HttpUtils();
http.download(downloadurl, "/mnt/sdcard/temp.apk",
new RequestCallBack<File>() {
@Override
public void onSuccess(ResponseInfo<File> arg0) {
UIUtils.showToast(activity,"下载完成...");
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.setDataAndType(Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), "temp.apk")),
"application/vnd.android.package-archive");
startActivityForResult(intent, 0);
}
@Override
public void onFailure(HttpException arg0, String arg1) {
ToastUtils.show(activity, "下载失败");
System.out.println(arg1);
arg0.printStackTrace();
//loadMainUI();
}
@Override
public void onLoading(long total, long current,
boolean isUploading) {
//tv_info.setText(current + "/" + total);
super.onLoading(total, current, isUploading);
}
});
}*/
}
以上就是版本检测与下载的 工具类, 直接引入项目即可,可能做法比较简单,勿喷... 里面有一个判断==0,表示不需要强制更新,==1表示需要强制更新,根据客户要求做的,就是这个json字段
Integer.valueOf(versionItem.getUpdatevs())==0
布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"> <ProgressBar
android:id="@+id/update_progress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal" /> </LinearLayout>
上2个图片


android端 版本升级的更多相关文章
- [Android]Android端ORM框架——RapidORM(v2.1)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6020412.html [Android]Android端ORM ...
- [Android]Android端ORM框架——RapidORM(v2.0)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5626716.html [Android]Android端ORM ...
- Java服务器对外提供接口以及Android端向服务器请求数据
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5056780.html 讲解下java服务器是如何对移动终端提供接口的,以什么数据格式提供出去,移动端又是怎么 ...
- 【Android端 APP GPU过度绘制】GPU过度绘制及优化
一.Android端的卡顿 Android端APP在具体使用的过程中容易出现卡顿的情况,比如查看页面时出现一顿一顿的感受,切换tab之后响应很慢,或者具体滑动操作的时候也很慢. 二.卡顿的原因 卡顿的 ...
- 【Android端 APP 内存分析】使用工具进行APP的内存分析
Android端可以通过adb 命令直接获取内存信息,当然Android studio也提供了对内存的监控分析工具,并且后续可以结合MAT做分析 今天介绍的是通过Android studio和MAT工 ...
- 【Android端APP 安装包检查】安装包检查具体内容及实现方法
一.安装包检查的具体包含内容有哪些? 1.安装包检查的一般内容包括: 安装包基本信息检查: 文件大小: xx MB 包名: com.xx 名称: xx 本次安装包证书与外网证书对比一致性:是 版本号 ...
- pc端和android端应用程序测试有什么区别?(ps面试题)
pc端和android端应用程序测试有什么区别?(ps面试题) [VIP7]大连-凭海临风(215687736) 2014/4/10 8:56:171.测试环境不同PC平台一般都是windows an ...
- 【转载】Android端手机测试体系
1.冒烟测试 跟web端 的测试流程一样,你拿到一个你们开发做出来的apk首先得去冒烟,也就是保证他的稳定性,指定时间内不会崩溃.这款原生sdk自带的monkey可以当做 我们的测试工具.就跟我之前博 ...
- windows 代理服务器的搭建,提供Android 端访问公网.
这段时间遇到一个情况,移动的网络收费.但是可以访问学校内部的网络,比如说学校官网图书馆之类了.所以我这里便想到一个方法,用学校内部一个可以访问互联网的主机充当代理服务器(我这里使用自己的电脑,非服务器 ...
随机推荐
- 二.Google黑客语法
搜索也是一门艺术! 说起Google,可谓是无人不知无人不晓,其强大的搜索功能,可以让你在瞬间找到你想要的一切.对于黑客而言,Google可是 一款绝佳的黑客工具.正因Google强大的检索能力,黑客 ...
- (二十二)c#Winform自定义控件-半透明窗体
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- 7.26 面向对象_封装_property_接口
封装 封装 就是隐藏内部实现细节, 将复杂的,丑陋的,隐私的细节隐藏到内部,对外提供简单的访问接口 为什么要封装 1.保证关键数据的安全性 2.对外部隐藏实现细节,隔离复杂度 什么时候应该封装 1.当 ...
- Daily,一个入门级的 React Native 应用
Daily,一个React-Native写的android app. 下拉刷新获取:图片.诗句.言语.音乐.乐评.雨声.知乎日报.历史上的今天. 可以说是一个入门级的React-Native应用. 项 ...
- socket基于TCP(粘包现象和处理)
目录 6socket套接字 7基于TCP协议的socket简单的网络通信 AF_UNIX AF_INET(应用最广泛的一个) 报错类型 单一 链接+循环通信 远程命令 9.tcp 实例:远程执行命令 ...
- nginx配置ssl证书实现https加密请求详解
原文链接:http://www.studyshare.cn/software/details/1175/0 一.加密方式 1.对称加密 所谓对称加密即:客户端使用一串固定的秘钥对传输内容进行加密,服务 ...
- Django+zTree构建组织架构树
树,因其清晰明了的展现形式而被广泛的使用 日常的开发过程中我们需要经常与"树"打交道,例如公司的组织架构树.服务器的项目归属树,管理后台侧边树等等,本篇文章介绍关于树的两个内容 多 ...
- C# Mqtt 断线重连
在通过 MqttClient 客户端连接之后,在服务端服务重启时,客户端如果没有重连机制,则无法再接收到订阅的消息. 使用的 Mqtt 组件为:M2Mqtt.Net.dll 一些特性发现 (1)如果提 ...
- MySQL数据库之表的增删改查
目录 MySQL数据库之表的增删改查 1 引言 2 创建表 3 删除表 4 修改表 5 查看表 6 复制表 MySQL数据库之表的增删改查 1 引言 1.MySQL数据库中,数据库database就是 ...
- MSIL实用指南-方法的调用
方法调用指令主要有Call和Callvirt. 调用static或sealed修饰的方法,用Call指令. 调用virtual或abstract修饰的方法,用Callvirt指令. 代码实例: ilG ...