没深入学习app更新这块的时候,觉得app更新有点神秘!
正是这种神秘感,迫使我去探究下:究竟app更新是怎么实现的呢!!
废话不多说,先上效果图!
如果有新版本,自动提示:
点击更新,通知栏显示下载进度:
下载安装好后,再去 设置 那点击 检查更新,将会有相应提示:
任何开发都离不开思路:
1.获取当前APK的版本
2.去服务器上获取最
新的版本
3.对比后,决定是否更新。
4.更新,去服务器上下载apk.
5.下载后,保存到sd卡,然后安装apk
分析:获取的apk版本是versionCode还是versionName呢?
获取的apk版本是versionCode还是versionName呢?
对比下AndroidManifest.xml 和 build.gradle 文件里面的
versionCode 和 versionName
其中可以查阅资料如下:
versionCode——整数值,代表应用程序代码的相对版本,也就是版本更新过多少次。整数值有利于其它程序比较,检查是升级还是降级。你可以把这个值设定为任何想设的值,但是,你必须保证后续更新版的值要比这个大。系统不会强制要求这一行为,但是随着版本更新值也增加是正常的行为。一般来说,你发布的第一版程序的versionCode设定为1,然后每次发布都会相应增加,不管发布的内容是较大还是较小的。这意味着versionCode不像应用程序的发布版本(看下面的versionName)那样显示给用户。应用程序和发布的服务不应该显示这个版本值给用户。
versionName——字符串值,代表应用程序的版本信息,需要显示给用户。与versionCode一样,系统不会为了任何内部的目的使用这个值,除了显示给用户外。发布的服务也需要提取这个值来显示给用户。
这样想必都很清楚只需要比对versionCode即可了。
(1)获得当前APK版本
/*
* 取得程序的当前 versionCode
*/
public static int getNowVerCode(Context context) {
int verCode = 0;
try {
verCode = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
}
return verCode;
}
/*
* 取得程序的当前 versionName
*/
public static String getNowVerName(Context context){
String VerName = "";
try{
VerName = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0).versionName;
}catch (PackageManager.NameNotFoundException e){
}
return VerName;
}
(2)去服务器获取最新版本
思路:
服务器的一个路径下存放我最新版的apk,供下载。
一个配置文件,说明我最新apk的versionCode以供客户端对比
如下:
(便捷起见)我服务端木有写代码,简单的响应即可。
客户端核心代码如下:
SettingActivity.java
public class SettingActivity extends AppCompatActivity {
version mVersion;
int newVersionCode = 0;
.
.
.
.
.
public void Check(View view){
ToastUtil.show(SettingActivity.this, "检查更新");
goToCheckNewVersion();
Log.e("TAG","Check");
int now_VersionCode = VersionCheck.getNowVerCode(SettingActivity.this);
Log.e("TAG", now_VersionCode + ";"+newVersionCode);
if (VersionCheck.isNewVersion(newVersionCode,now_VersionCode)){
Log.e("TAG", "可以更新");
ToastUtil.show(SettingActivity.this,"正在更新");
VersionCheck.goUpdate(SettingActivity.this);
}else{
ToastUtil.show(SettingActivity.this,"已是最新版本");
}
}
private void goToCheckNewVersion() {
//检查服务器的app版本号,解析这个
// :http://each.ac.cn/atmosphere.json,获得versionCode
new Thread(new Runnable() {
@Override
public void run() {
String url = "http://each.ac.cn/atmosphere.json";
StringRequest request = new StringRequest(Request.Method.GET,
url, new Response.Listener<String>() {
@Override
public void onResponse(String s) {
Log.e("TAG", s);
List<version> versionList = parseJSONWithGson(s);
for (version ver : versionList){
if (ver != null){ //List里面只有一个ver
Log.e("TAG", ver.getVersionCode()+";"+ver.getApkUrl());
versionModel(ver);
}
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG",error.toString());
}
});
request.setTag("testGet");
MyApplication.getHttpQueues().add(request);
}
}).start();
}
private void versionModel(version ver) {
mVersion = ver;
Log.e("TAG", mVersion.getVersionCode()+"");
newVersionCode = mVersion.getVersionCode();
}
private List<version> parseJSONWithGson(String jsonData) {
Gson gson = new Gson();
List<version> versList = gson.fromJson(jsonData,
new TypeToken<List<version>>() {}.getType());
return versList;
}
.
.
.
.
}
工具类VersionCheck.java
public class VersionCheck {
public static Boolean isNewVersion(int newVersionCode,int nowVersionCode){
//判断是否新版本
if (newVersionCode > nowVersionCode){
//可以更新
return true;
}
return false;
}
/*
* 取得程序的当前版本
*/
public static int getNowVerCode(Context context) {
int verCode = 0;
try {
verCode = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
}
return verCode;
}
public static String getNowVerName(Context context){
String VerName = "";
try{
VerName = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0).versionName;
}catch (PackageManager.NameNotFoundException e){
}
return VerName;
}
public static void goUpdate(Context context){
Intent intent = new Intent(context, DownloadService.class);
intent.putExtra("apkUrl", "http://each.ac.cn/new_apk/app-release.apk");
context.startService(intent);
}
}
MainActivity 中核心代码段
public class MainActivity extends AppCompatActivity {
.
.
.
version mVersion; //版本实体类 int versionCode,String apkurl
private MyApplication app; //全局 类对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final ActionBar ab = getSupportActionBar();
assert ab != null;
ab.setHomeAsUpIndicator(R.drawable.ic_menu);
ab.setDisplayHomeAsUpEnabled(true);
init();
//页面启动时检查下是否有新版本可下载
checkIfNewVersion();
}
private void checkIfNewVersion() {
int newVersionCode;
goToCheckNewVersion();
int now_VersionCode = VersionCheck.getNowVerCode(MainActivity.this);
Log.e("TAG","now_VersionCode "+ now_VersionCode );
app = (MyApplication)getApplication();
newVersionCode = app.getValue();//从全局变量中取版本号出来
Log.e("TAG","new_VersionCode "+ newVersionCode);
if (VersionCheck.isNewVersion(newVersionCode,now_VersionCode)){
Log.e("TAG", "可以更新");
//弹出对话框
Dialog dialog = new AlertDialog.Builder(MainActivity.this)
.setTitle("软件更新")
.setMessage("有新版本")
// 设置内容
.setPositiveButton("更新",// 设置确定按钮
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
VersionCheck.goUpdate(MainActivity.this);
ToastUtil.show(MainActivity.this, "正在更新");
}
})
.setNegativeButton("暂不更新",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
// 点击"取消"按钮之后退出程序
//finish();
}
}).create();// 创建
// 显示对话框
dialog.show();
}
}
private void goToCheckNewVersion() {
//检查服务器的app版本号,解析这个:http://each.ac.cn/atmosphere.json,获得versionCode
new Thread(new Runnable() {
@Override
public void run() {
String url = "http://each.ac.cn/atmosphere.json";
StringRequest request = new StringRequest(Request.Method.GET,
url, new Response.Listener<String>() {
@Override
public void onResponse(String s) {
Log.e("TAG", s);
List<version> versionList = parseJSONWithGsonForVersion(s);
for (version ver : versionList){
if (ver != null){
Log.e("TAG", ver.getVersionCode()+";"+ver.getApkUrl());
versionModel(ver);//有新版本的实体对象传出来
}
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("TAG",error.toString());
}
});
request.setTag("testGet");
MyApplication.getHttpQueues().add(request);
}
}).start();
}
private void versionModel(version ver) {
mVersion = ver;
Log.e("TAG", mVersion.getVersionCode()+" versionModel");
int newVersionCode = mVersion.getVersionCode();
Log.e("TAG", "newVersionCode " + newVersionCode);
app = (MyApplication)getApplication();
app.setValue(newVersionCode);//把拿到的版本实体的版本号设置到全局变量中
}
private List<version> parseJSONWithGsonForVersion(String jsonData) {
Gson gson = new Gson();
List<version> versList = gson.fromJson(jsonData,
new TypeToken<List<version>>() {}.getType());
return versList;
}
.
.
.
}
本文探讨了Android应用的更新流程,从获取当前APK版本、对比服务器最新版本、决定是否更新到下载安装的过程。关键在于比对versionCode,通过设置活动和工具类实现自动检查更新功能。
2578

被折叠的 条评论
为什么被折叠?



