App更新(Android)

前言:现在一般的Android软件都是需要不断更新的,当你打开某个app的时候,如果有新的版本,它会提示你有新版本需要更新。该项目实现的就是这个功能。并且有强制更新和更新提示两种方式,当有更新时,会弹出一个提示框,点击下载,则在通知来创建一个进度条进行下载,点击取消,则取消更新。

效果:

开发环境:AndroidStudio2.1.2+gradle-2.10

部分代码:

public class UpdateVersionController {

    private Context context;

    //更新文件的实例
private AppUpdateInfo info;
//当前版本号
private int versionCode;
//提示用户更新的dialog
private Dialog dialog;
//下载进度条
private ProgressDialog pd; public static UpdateVersionController getInstance(Context context) {
return new UpdateVersionController(context);
} public UpdateVersionController(Context context) {
this.context = context;
} public void normalCheckUpdateInfo() {
//获取版本号:这里的版本号在项目的build.gradle中是可以看到的,看复制过来的参数
/**
defaultConfig {
applicationId "com.zhh.test"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
*/
versionCode = getVerCode(context);//等于19
checkVersionTask(); } public void forceCheckUpdateInfo() {//强制更新一般不用
versionCode = getVerCode(context);//等于19
info = new AppUpdateInfo();
info.setUrl("http://60.210.21.89/appdl.hicloud.com/dl/appdl/application/apk/dd/ddeabc7e64d64e4287340ffb89c592a8/com.hellotext.1309171635.apk?sign=baidu@baidu&wshc_tag=0&wsts_tag=58c7bde2&wsid_tag=7c5a47c8&wsiphost=ipdbm");
info.setVercode(2);//每次更新都靠它
info.setVername("2.0");//版本名字
info.setApkname("com.hellotext.1309171635.apk");
info.setAppname("Hello");
info.setForceUpp("yes");
info.setUppcontent("1. Hello啊哟更新了\n2. 英文的,界面很好看.\n3. 界面效果优化");//更新内容
updateApp();
} /**
* 步骤一:获取版本信息
*/
private void checkVersionTask() {
//网络加载获取app新版版本信息
//这里不做请求直接赋值
info = new AppUpdateInfo();
info.setUrl("http://60.210.21.89/appdl.hicloud.com/dl/appdl/application/apk/dd/ddeabc7e64d64e4287340ffb89c592a8/"+
            "com.hellotext.1309171635.apk?sign=baidu@baidu&wshc_tag=0&wsts_tag=58c7bde2&wsid_tag=7c5a47c8&wsiphost=ipdbm");
info.setVercode(2);//每次更新都靠它
info.setVername("2.0");//版本名字
info.setApkname("com.hellotext.1309171635.apk");
info.setAppname("Hello");
info.setForceUpp("no");
info.setUppcontent("1. Hello啊哟更新了\n2. 英文的,界面很好看.\n3. 界面效果优化");//更新内容
updateApp();
} private void updateApp() {
if (null != info && info.getVercode() > versionCode) {//20>19可更新
showUpdataDialog();
} else {
Toast.makeText(context, "已经是最新版本啦~", Toast.LENGTH_SHORT).show();
}
} private Button cancelBtn; /**
* 步骤二:弹出对话框提示用户更新
*/
protected void showUpdataDialog() { dialog = new Dialog(context, android.R.style.Theme_Dialog);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
dialog.setContentView(R.layout.activity_updater);
dialog.setCanceledOnTouchOutside(false);
dialog.setCancelable(false);
((TextView) dialog.findViewById(R.id.content)).setText(info.getUppcontent());
cancelBtn = (Button) dialog.findViewById(R.id.cancel);
cancelBtn.setVisibility("yes".equals(info.getForceUpp()) ? View.GONE : View.VISIBLE);
// 取消更新
cancelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
// 确认更新
dialog.findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
downLoadApk();
}
});
dialog.findViewById(R.id.market).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=Hello"));
context.startActivity(intent);
}
});
dialog.show();
} /**
* 步骤三:下载文件
*/
private void downLoadApk() {
// 进度条对话框
pd = new ProgressDialog(context);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("下载中...");
pd.setCanceledOnTouchOutside(false);
pd.setCancelable(false);
// 监听返回键--防止下载的时候点击返回
pd.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
Toast.makeText(context, "正在下载请稍后", Toast.LENGTH_SHORT).show();
return true;
} else {
return false;
}
}
});
// Sdcard不可用
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Toast.makeText(context, "SD卡不可用~", Toast.LENGTH_SHORT).show(); } else {
pd.show();
//下载的子线程
new Thread() {
@Override
public void run() {
try {
// 在子线程中下载APK文件
File file = getFileFromServer(info.getUrl(), pd);
sleep(1000);
// 安装APK文件
installApk(file);
pd.dismiss(); // 结束掉进度条对话框
} catch (Exception e) {
Toast.makeText(context, "文件下载失败了~", Toast.LENGTH_SHORT).show();
pd.dismiss();
e.printStackTrace();
}
} }.start();
}
} /**
* 从服务器下载apk
*/
public File getFileFromServer(String path, ProgressDialog pd) throws Exception {
// 如果相等的话表示当前的sdcard挂载在手机上并且是可用的
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
// 获取到文件的大小
pd.setMax(conn.getContentLength() / 1024);
InputStream is = conn.getInputStream(); File file = new File(Environment.getExternalStorageDirectory().getPath()
+ "/blibao/merchant", "i_blibao_shop.apk");
//判断文件夹是否被创建
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
} FileOutputStream fos = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
int total = 0;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
total += len;
// 获取当前下载量
pd.setProgress(total / 1024);
}
fos.close();
bis.close();
is.close();
return file;
} else {
return null;
}
} /**
* 安装apk
*/
protected void installApk(File file) {
Intent intent = new Intent();
// 执行动作
intent.setAction(Intent.ACTION_VIEW);
// 执行的数据类型
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} /**
* 获取版本名
*/
public static String getVerName(Context context) { String verName = "";
try {
// 获取packagemanager的实例
PackageManager packageManager = context.getPackageManager();
// getPackageName()是你当前类的包名,0代表是获取版本信息
PackageInfo packInfo = packageManager.getPackageInfo(
context.getPackageName(), 0); verName = packInfo.versionName;
} catch (Exception e) {
e.printStackTrace();
}
return verName;
} /**
* 获取版本号
*/
public static int getVerCode(Context context) {
int verCode = -1;
try {
// 获取packagemanager的实例
PackageManager packageManager = context.getPackageManager();
// getPackageName()是你当前类的包名,0代表是获取版本信息
PackageInfo packInfo = packageManager.getPackageInfo(
context.getPackageName(), 0); verCode = packInfo.versionCode;
} catch (Exception e) {
e.printStackTrace();
}
return verCode;
} }

源码下载...

App更新(Android)的更多相关文章

  1. IOS开始对App Store大扫除:你的APP更新了吗?

    成都亿合科技小编从北京商报了解到,对于开发APP应用的要注意啦,IOS要开始对App Store大扫除:你的APP更新了吗? 日前苹果App Store的开发者们发送邮件,表示将实施一个持续评估应用行 ...

  2. App更新之dialog数字进度条

    App更新之dialog数字进度条 前言:现在一般的Android软件都是需要不断更新的,当你打开某个app的时候,如果有新的版本,它会提示你有新版本需要更新.当有更新时,会弹出一个提示框,点击下载, ...

  3. HBuilder发行App(Android和ios)

    怎样将开发好的app测试和上架,此文包括Android和ios打包.测试和上架的大概过程.内容有些简陋,因为此过程踏坑无数,特此留念. 特此声明:内容不全仅供参考. 介绍两个参考网站: 1. http ...

  4. uniapp中IOS安卓热更新和整包更新app更新

    在App.vue中 onLaunch: function() { console.log('App Launch'); // #ifdef APP-PLUS this.getVersion(); // ...

  5. 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native

    [源码下载] 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native 作者:web ...

  6. 摘抄——读《大话移动APP测试 Android与IOS》

    用了两天读完了<大话移动APP测试 Android与IOS>,由于刚开始接触移动测试,技术型的篇章只能先放过了o(╯□╰)o,有以下内容觉得很有必要时不时的看看,来反思自己的工作,自勉!! ...

  7. 更新Android SDK 出错 Failed to rename directory \temp\ToolPackage.old01

    打算更新Android SDK 版本到 Android SDK Tools 20,打开SDK Manager.exe 开始更新,结果安装时弹出错误提示:Failed to rename directo ...

  8. 更新android SDK的问题

        由于我大天朝将google屏蔽的原因,在更新android SDK的时候,可能速度慢还是个小问题,重要的是你更新的时候出各种错误,比如错误  Failed to fetch URL https ...

  9. Attempt to write to field 'android.support.v4.app.FragmentManagerImpl android.support.v4.app.Fragment.mFragmentManager' on a null object reference

    E/AndroidRuntime﹕ FATAL EXCEPTION: mainProcess: org.example.magnusluca.drawertestapp, PID: 3624java. ...

随机推荐

  1. sed的基本用法

    了解sed的基本参数 sed匹配的方法: '//'p, 此符号与grep的引号类似,但sed是一定加此符号的,且还要加上-n的参数,匹配起来相当麻烦.sed匹配的方法: '//'pI 加上I的参数是指 ...

  2. 简单了解树形DP

    今天在B站看了一个树形DP教学视频有所收获,做一个小小的总结 AV号和链接在这:av12194537 那么先介绍一下树形DP 树形DP就是在树这个特殊的数据结构上进行的DP.有两种方向:自顶向下和自底 ...

  3. 【算法笔记】B1046 划拳

    1046 划拳 (15 分) 划拳是古老中国酒文化的一个有趣的组成部分.酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字.如果谁比划出的数字正好等于两人喊出的数字之和,谁就赢了,输 ...

  4. A. Right-Left Cipher Round #528 (Div. 2)【字符串】

    一.题面 题目链接 二.分析 该题就是一个字符串的还原.长度为奇数时从左边开始,长度为偶数时从右边开始. 三.AC代码 #include <bits/stdc++.h> using nam ...

  5. BZOJ - 1026 数位DP

    中文题面,注意st是不可以放到dp里面的,否则每次solve都要清零 注意状态的转移要st&&i==0,因为子结构也可能是st(当高位取0时) 而st是必然合法的 #include&l ...

  6. setlocal enabledelayedexpansion 解释

    看字面的意思是:设置本地为延迟扩展.其实也就是:延迟变量,全称"延迟环境变量扩展", 在cmd执行命令前会对脚本进行预处理,其中有一个过程是变量识别过程,在这个过程中,如果有两个% ...

  7. eclipse+maven远程(自动)部署web项目到tomcat

    [转自] http://blog.csdn.net/dhmpgt/article/details/11197995 eclipse集成maven后可以用maven命令把web项目自动部署到tomcat ...

  8. VUE项目引入微信jssdk

    npm i -S weixin-js-sdkimport wx from 'weixin-js-sdk'

  9. linux-lnmp 搭建报错

    一, 大概就是 没有php-nysql拓展 yum -y install php-mysql 二, 编辑php.ini php.ini中 添加extension=mysql.so PHP.ini 中找 ...

  10. (转)用shell脚本实现杨辉三角的4个实例!

    概述:    中国古代数学家在数学的许多重要领域中处于遥遥领先的地位.中国古代数学史曾经有自己光辉灿烂的篇章,而杨辉三角的发现就是十分精彩的一页.杨辉三角形,是二项式系数在三角形中的一种几何排列.杨辉 ...