Android联网更新应用


UpdateInfo
public class UpdateInfo {
public String version;//服务器的最新版本值
public String apkUrl;//最新版本的路径
public String desc;//版本更新细节
}
WelcomeActivity:
public class WelcomeActivity extends Activity {
private static final int TO_MAIN = ;
private static final int DOWNLOAD_VERSION_SUCCESS = ;
private static final int DOWNLOAD_APK_FAIL = ;
private static final int DOWNLOAD_APK_SUCCESS = ;
@Bind(R.id.iv_welcome_icon)
ImageView ivWelcomeIcon;
@Bind(R.id.rl_welcome)
RelativeLayout rlWelcome;
@Bind(R.id.tv_welcome_version)
TextView tvWelcomeVersion;
private boolean connect;
private long startTime;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case TO_MAIN:
finish();
startActivity(new Intent(WelcomeActivity.this, MainActivity.class));
break;
case DOWNLOAD_VERSION_SUCCESS:
//获取当前应用的版本信息
String version = getVersion();
//更新页面显示的版本信息
tvWelcomeVersion.setText(version);
//比较服务器获取的最新的版本跟本应用的版本是否一致
if(version.equals(updateInfo.version)){
UIUtils.toast("当前应用已经是最新版本",false);
toMain();
}else{
new AlertDialog.Builder(WelcomeActivity.this)
.setTitle("下载最新版本")
.setMessage(updateInfo.desc)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//下载服务器保存的应用数据
downloadApk();
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
toMain();
}
})
.show();
}
break;
case DOWNLOAD_APK_FAIL:
UIUtils.toast("联网下载数据失败",false);
toMain();
break;
case DOWNLOAD_APK_SUCCESS:
UIUtils.toast("下载应用数据成功",false);
dialog.dismiss();
installApk();//安装下载好的应用
finish();//结束当前的welcomeActivity的显示
break;
}
}
};
private void installApk() {
Intent intent = new Intent("android.intent.action.INSTALL_PACKAGE");
intent.setData(Uri.parse("file:" + apkFile.getAbsolutePath()));
startActivity(intent);
}
private ProgressDialog dialog;
private File apkFile;
private void downloadApk() {
//初始化水平进度条的dialog
dialog = new ProgressDialog(this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCancelable(false);
dialog.show();
//初始化数据要保持的位置
File filesDir;
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
filesDir = this.getExternalFilesDir("");
}else{
filesDir = this.getFilesDir();
}
apkFile = new File(filesDir,"update.apk");
//启动一个分线程联网下载数据:
new Thread(){
public void run(){
String path = updateInfo.apkUrl;
InputStream is = null;
FileOutputStream fos = null;
HttpURLConnection conn = null;
try {
URL url = new URL(path);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout();
conn.setReadTimeout();
conn.connect();
if(conn.getResponseCode() == ){
dialog.setMax(conn.getContentLength());//设置dialog的最大值
is = conn.getInputStream();
fos = new FileOutputStream(apkFile);
byte[] buffer = new byte[];
int len;
while((len = is.read(buffer)) != -){
//更新dialog的进度
dialog.incrementProgressBy(len);
fos.write(buffer,,len);
SystemClock.sleep();
}
handler.sendEmptyMessage(DOWNLOAD_APK_SUCCESS);
}else{
handler.sendEmptyMessage(DOWNLOAD_APK_FAIL);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(conn != null){
conn.disconnect();
}
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}.start();
}
private UpdateInfo updateInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 去掉窗口标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 隐藏顶部的状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_welcome);
ButterKnife.bind(this);
//将当前的activity添加到ActivityManager中
ActivityManager.getInstance().add(this);
//提供启动动画
setAnimation();
//联网更新应用
updateApkFile();
}
/**
* 当前版本号
*
* @return
*/
private String getVersion() {
String version = "未知版本";
PackageManager manager = getPackageManager();
try {
PackageInfo packageInfo = manager.getPackageInfo(getPackageName(), );
version = packageInfo.versionName;
} catch (PackageManager.NameNotFoundException e) {
//e.printStackTrace(); //如果找不到对应的应用包信息, 就返回"未知版本"
}
return version;
}
private void updateApkFile() {
//获取系统当前时间
startTime = System.currentTimeMillis();
//1.判断手机是否可以联网
boolean connect = isConnect();
if (!connect) {//没有移动网络
UIUtils.toast("当前没有移动数据网络", false);
toMain();
} else {//有移动网络
//联网获取服务器的最新版本数据
AsyncHttpClient client = new AsyncHttpClient();
String url = AppNetConfig.UPDATE;
client.post(url, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(String content) {
//解析json数据
updateInfo = JSON.parseObject(content, UpdateInfo.class);
handler.sendEmptyMessage(DOWNLOAD_VERSION_SUCCESS);
}
@Override
public void onFailure(Throwable error, String content) {
UIUtils.toast("联网请求数据失败", false);
toMain();
}
});
}
}
private void toMain() {
long currentTime = System.currentTimeMillis();
long delayTime = - (currentTime - startTime);
if (delayTime < ) {
delayTime = ;
}
handler.sendEmptyMessageDelayed(TO_MAIN, delayTime);
}
private void setAnimation() {
AlphaAnimation alphaAnimation = new AlphaAnimation(, );//0:完全透明 1:完全不透明
alphaAnimation.setDuration();
alphaAnimation.setInterpolator(new AccelerateInterpolator());//设置动画的变化率
//方式一:
// alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
// @Override
// public void onAnimationStart(Animation animation) {
//
// }
// //当动画结束时:调用如下方法
// @Override
// public void onAnimationEnd(Animation animation) {
// Intent intent = new Intent(WelcomeActivity.this,MainActivity.class);
// startActivity(intent);
// finish();//销毁当前页面
// }
//
// @Override
// public void onAnimationRepeat(Animation animation) {
//
// }
// });
//方式二:使用handler
// handler.postDelayed(new Runnable() {
// @Override
// public void run() {
// Intent intent = new Intent(WelcomeActivity.this, MainActivity.class);
// startActivity(intent);
//// finish();//销毁当前页面
// //结束activity的显示,并从栈空间中移除
// ActivityManager.getInstance().remove(WelcomeActivity.this);
// }
// }, 3000);
//启动动画
rlWelcome.startAnimation(alphaAnimation);
}
public boolean isConnect() {
boolean connected = false;
ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
if (networkInfo != null) {
connected = networkInfo.isConnected();
}
return connected;
}
}
Android联网更新应用的更多相关文章
- android studio 更新 Gradle错误解决方法(Gradle sync failed)
android studio 更新 Gradle错误解决方法 Android Studio每次更新版本都会更新Gradle这个插件,但由于长城的问题每次更新都是失败,又是停止在Refreshing ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- fir.im Weekly - iOS / Android 动态化更新方案盘点
动态化更新是 App 开发必然面对的问题.在 iOS 环境下,Apple 开发者们像是" 带着手铐脚镣跳舞" ,相比之下 Android 开发者会轻松一点,有很多相关的开源框架帮助 ...
- [转]Android SDK更新 Connection to http://dl-ssl.google.com refused 解决方法
问题描述 使用SDK Manager更新时出现问题Failed to fetch URL https://dl-ssl.google.com/android/repository/repository ...
- Android 数据库管理— — —更新数据
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=" ...
- Android 增量更新(BSDiff / bspatch)
Android 增量更新 BSDiff / bspatchhttp://www.daemonology.net/bsdiff/android的代码目录下 \external\bsdiff bsdiff ...
- Android异步更新UI的四种方式
Android异步更新UI的四种方式 2015-09-06 09:23 segmentfault 字号:T | T 大家都知道由于性能要求,android要求只能在UI线程中更新UI,要想在其他线程中 ...
随机推荐
- RSA实现JS前端加密,PHP后端解密
web前端,用户注册与登录,不能直接以明文形式提交用户密码,容易被截获,这时就引入RSA. 前端加密 需引入4个JS扩展文件,jsbn.js.prng4.js.rng.js和rsa.js. <h ...
- Liferay7 BPM门户开发之24: Liferay7应用程序安全
整理中...... Resources, Roles, and PermissionsPortal Access Control List (PACL) Custom SSO Providers Au ...
- (转)websphere线程池 连接池设置
原文:http://www.talkwithtrend.com/Article/207511 池(Pool)是WebSphere中最常涉及的概念之一.从网络.Web 服务器.Web 容器.EJB 容器 ...
- 国外程序员整理的 C++ 资源大全 (zt)
关于 C++ 框架.库和资源的一些汇总列表,由 fffaraz 发起和维护. 内容包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C++标准库,包括了S ...
- WinForm版图像编辑小程序(实现图像拖动、缩放、旋转、抠图)
闲暇之余,开发一个图片编辑小程序.程序主要特点就是可方便的对多个图像编辑,实现了一些基本的操作.本文主要介绍一下程序的功能.设计思路. 执行程序 下载地址: 百度网盘.https://pan.baid ...
- Spring Boot 解决方案 - 配置
习惯优于配置 Spring Boot 项目的重要思想就是"习惯优于配置",这也是为什么该项目诞生的原因,让开发者免于 Spring 生态中各种项目的配置.尽管如此,但项目中完全零配 ...
- EOS1.1版本新特性介绍
EOSIO/eos 目前在github的项目活跃度方面排名第一,release版本更新的速度让人应接不暇.今天EOS的大版本1.1发布,我也有幸参与了贡献,本篇文章重点介绍1.1版本的重大功能升级. ...
- JQ的offset().top与js的offsetTop区别详解
一.前言 最近在做一个图片懒加载的插件,就纵轴(Y轴)而言,我需要时时获取图片的上偏移量,好判断是否已进入视图区域,而我所理解的是offsetTop应该是跟offset().top一样的,然后陷入了因 ...
- python redis模块详解
前言 现在越来越觉得知识的沉淀尤为重要,最近打算慢慢的把一些知识点做个记录,如果长期不用生疏了也可以快速回顾.下面我会依次介绍在python中常用组件redis,rabbitmq,mongodb,E ...
- 技术人员在小公司成长 vs 大公司成长路径和建议
我们经常听到这样的对话: 大公司猿A:真不想干了,每天都做类似的工作,学不到什么东西,会议也多,浪费不少时间,想去小公司多做些事情,多学些东西. 小公司猿B:累死了,什么都做,太乱太杂,没系统不规范, ...