Android应用App更新实例详解
发布时间 - 2026-01-11 00:27:09 点击率:次前言:现在一般的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;
}
}
源码下载
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
# android
# app更新
# android程序更新
# app更新源码
# Android编程实现自动检测版本及自动升级的方法
# android实现程序自动升级到安装示例分享(下载android程序安装包)
# Android编程实现应用自动更新、下载、安装的方法
# Android App实现应用内部自动更新的最基本方法示例
# 安卓(Android)应用版本更新方法
# Android应用自动更新功能实现的方法
# Android应用APP自动更新功能的代码实现
# Android应用强制更新APP的示例代码
# 非常实用的小功能 Android应用版本的更新实例
# Android应用更新之自动检测版本及自动升级
# 对话框
# 英文
# 进度条
# 弹出
# 新和
# 很好看
# 不可用
# 下载量
# 都是
# 两种
# 当你
# 你有
# 可以看到
# 不做
# 点击下载
# 它会
# 最新版本
# 则在
# 该项目
# 机上
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
VIVO手机上del键无效OnKeyListener不响应的原因及解决方法
JavaScript如何操作视频_媒体API怎么控制播放
微信小程序 wx.uploadFile无法上传解决办法
如何快速搭建高效简练网站?
Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】
网站建设保证美观性,需要考虑的几点问题!
昵图网官方站入口 昵图网素材图库官网入口
重庆市网站制作公司,重庆招聘网站哪个好?
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】
谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程
详解Oracle修改字段类型方法总结
JavaScript中的标签模板是什么_它如何扩展字符串功能
Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】
为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】
大连 网站制作,大连天途有线官网?
Bootstrap CSS布局之列表
Laravel如何使用Blade组件和插槽?(Component代码示例)
HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】
Laravel如何使用.env文件管理环境变量?(最佳实践)
如何快速搭建安全的FTP站点?
php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】
如何快速辨别茅台真假?关键步骤解析
canvas 画布在主流浏览器中的尺寸限制详细介绍
Laravel如何使用Gate和Policy进行授权?(权限控制)
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理
Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
香港服务器建站指南:外贸独立站搭建与跨境电商配置流程
简单实现jsp分页
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
黑客如何利用漏洞与弱口令入侵网站服务器?
如何在香港服务器上快速搭建免备案网站?
音乐网站服务器如何优化API响应速度?
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
青岛网站建设如何选择本地服务器?
使用spring连接及操作mongodb3.0实例
如何快速打造个性化非模板自助建站?
如何在沈阳梯子盘古建站优化SEO排名与功能模块?
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?
,网页ppt怎么弄成自己的ppt?
Laravel如何处理CORS跨域请求?(配置示例)
Bootstrap整体框架之JavaScript插件架构
百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭
HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】
深圳防火门网站制作公司,深圳中天明防火门怎么编码?

