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,要想在其他线程中 ...
随机推荐
- MySQL 字符集utf8和utf-8的关系
目录 什么是字符集(character set) 校对规则(collation) ASCII码 Unicode国际化支持 UTF-8 utf8 utf8与utf8mb4的关系 超集 字符集设置 什么是 ...
- Tools - 源代码阅读分析工具Source Insight
简介 https://www.sourceinsight.com/ Source Insight是一个面向项目开发的程序编辑器和代码浏览器,可以分析C/C++.C#.Java.Python等语言源代码 ...
- [P4921] 情侣?给我烧了!
回顾一下错排公式 错排问题: 设n位错排数为D[n].考虑元素1的位置,设置为k(有n-1中 ):在考虑元素k的位置, 若为1,则转换为n-2位的错排:否则,视元素k为元素1(不能放在位置1),转换为 ...
- ES6学习总结
const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了 const foo = {}; // 为 foo 添加一个属性,可以成功 foo.prop = 123; foo ...
- Sql语句出错:Unknown column 'CLAMP' in 'where clause'
严重: Servlet.service() for servlet [jsp] in context with path [/management] threw exception [javax.se ...
- Myeclipse--jBPM4.3插件
http://www.baidupcs.com/file/c7f3b8fc57b056567b37d081b1bcd21e?xcode=3966699596a0e8ec88581bd8407457f9 ...
- Hadoop项目实战-用户行为分析之应用概述(三)
1.概述 本课程的视频教程地址:<项目工程准备> 本节给大家分享的主题如下图所示: 下面我开始为大家分享今天的第三节的内容——<项目工程准备>,接下来开始分享今天的内容. 2. ...
- Linux下lz4解压缩命令小结
lz4是一个让"人见人爱.花见花开"的压缩算法,能够在多核上很好的扩展.lz4在压缩率上略微逊色, 但是在解压速度上有着惊人的优势 (大概是gzip的3倍(多次测试对比)).因为压 ...
- window7环境下ZooKeeper的安装运行及监控查看
原文:http://www.cnblogs.com/RainAndWind/p/4668427.html ZooKeeper是一个分布式开源框架,供了协调分布式应用的基本服务.这些天在使用DUBBO, ...
- mybatis mapper xml文件的导入方式和查询方式
mybatis mapper xml文件的导入方式和查询方式 ssm框架 Mybatis mapper与SQLSession的关系 每个基于MyBatis的应用都是以一个SqlSessionFact ...