我们看到很多Android应用都具有自动更新功能,用户一键就可以完成软件的升级更新。得益于Android系统的软件包管理和安装机制,这一功能实现起来相当简单,下面我们就来实践一下。首先给出界面效果:








1. 准备知识
在AndroidManifest.xml里定义了每个Android apk的版本标识:


1
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
package="com.myapp"
3
android:versionCode="1"
4
android:versionName="1.0.0">
5
<application></application>
6
</manifest>
其中,android:versionCode和android:versionName两个字段分别表示版本代码,版本名称。versionCode是 整型数字,versionName是字符串。由于version是给用户看的,不太容易比较大小,升级检查时,可以以检查versionCode为主,方 便比较出版本的前后大小。
那么,在应用中如何读取AndroidManifest.xml中的versionCode和versionName呢?可以使用PackageManager的API,参考以下代码:


01
public static int getVerCode(Context context) {
02
int verCode = -1;
03
try {
04
verCode = context.getPackageManager().getPackageInfo(
05
"com.myapp", 0).versionCode;
06
} catch (NameNotFoundException e) {
07
Log.e(TAG, e.getMessage());
08
}
09
return verCode;
10
}
11

12
public static String getVerName(Context context) {
13
String verName = "";
14
try {
15
verName = context.getPackageManager().getPackageInfo(
16
"com.myapp", 0).versionName;
17
} catch (NameNotFoundException e) {
18
Log.e(TAG, e.getMessage());
19
}
20
return verName;
21
}
或者在AndroidManifest中将android:versionName="1.2.0"写成 android:versionName="@string/app_versionName",然后在values/strings.xml中添加对应 字符串,这样实现之后,就可以使用如下代码获得版本名称:


1
public static String getVerName(Context context) {
2
String verName = context.getResources()
3
.getText(R.string.app_versionName).toString();
4
return verName;
5
}
同理,apk的应用名称可以这样获得:


1
public static String getAppName(Context context) {
2
String verName = context.getResources()
3
.getText(R.string.app_name).toString();
4
return verName;
5
}
2. 流程框架






3. 版本检查
在服务端放置最新版本的apk文件,如:http://localhost/myapp/myapp.apk
同时,在服务端放置对应此apk的版本信息调用接口或者文件,如:http://localhost/myapp/ver.json
ver.json中的内容为:


[{"appname":"jtapp12","apkname":"jtapp-12-updateapksamples.apk","verName":1.0.1,"verCode":2}]


然后,在手机客户端上进行版本读取和检查:


01
private boolean getServerVer () {
02
try {
03
String verjson = NetworkTool.getContent(Config.UPDATE_SERVER
04
+ Config.UPDATE_VERJSON);
05
JSONArray array = new JSONArray(verjson);
06
if (array.length() > 0) {
07
JSONObject obj = array.getJSONObject(0);
08
try {
09
newVerCode = Integer.parseInt(obj.getString("verCode"));
10
newVerName = obj.getString("verName");
11
} catch (Exception e) {
12
newVerCode = -1;
13
newVerName = "";
14
return false;
15
}
16
}
17
} catch (Exception e) {
18
Log.e(TAG, e.getMessage());
19
return false;
20
}
21
return true;
22
}
比较服务器和客户端的版本,并进行更新操作。


1
if (getServerVerCode()) {
2
int vercode = Config.getVerCode(this); // 用到前面第一节写的方法
3
if (newVerCode > vercode) {
4
doNewVersionUpdate(); // 更新新版本
5
} else {
6
notNewVersionShow(); // 提示当前为最新版本
7
}
8
}
详细方法:


01
private void notNewVersionShow() {
02
int verCode = Config.getVerCode(this);
03
String verName = Config.getVerName(this);
04
StringBuffer sb = new StringBuffer();
05
sb.append("当前版本:");
06
sb.append(verName);
07
sb.append(" Code:");
08
sb.append(verCode);
09
sb.append(",/n已是最新版,无需更新!");
10
Dialog dialog = new AlertDialog.Builder(Update.this).setTitle("软件更新")
11
.setMessage(sb.toString())// 设置内容
12
.setPositiveButton("确定",// 设置确定按钮
13
new DialogInterface.OnClickListener() {
14
@Override
15
public void onClick(DialogInterface dialog,
16
int which) {
17
finish();
18
}
19
}).create();// 创建
20
// 显示对话框
21
dialog.show();
22
}
23
private void doNewVersionUpdate() {
24
int verCode = Config.getVerCode(this);
25
String verName = Config.getVerName(this);
26
StringBuffer sb = new StringBuffer();
27
sb.append("当前版本:");
28
sb.append(verName);
29
sb.append(" Code:");
30
sb.append(verCode);
31
sb.append(", 发现新版本:");
32
sb.append(newVerName);
33
sb.append(" Code:");
34
sb.append(newVerCode);
35
sb.append(", 是否更新?");
36
Dialog dialog = new AlertDialog.Builder(Update.this)
37
.setTitle("软件更新")
38
.setMessage(sb.toString())
39
// 设置内容
40
.setPositiveButton("更新",// 设置确定按钮
41
new DialogInterface.OnClickListener() {
42
@Override
43
public void onClick(DialogInterface dialog,
44
int which) {
45
pBar = new ProgressDialog(Update.this);
46
pBar.setTitle("正在下载");
47
pBar.setMessage("请稍候...");
48
pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
49
downFile(Config.UPDATE_SERVER + Config.UPDATE_APKNAME);
50
}
51
})
52
.setNegativeButton("暂不更新",
53
new DialogInterface.OnClickListener() {
54
public void onClick(DialogInterface dialog,
55
int whichButton) {
56
// 点击"取消"按钮之后退出程序
57
finish();
58
}
59
}).create();// 创建
60
// 显示对话框
61
dialog.show();
62
}
4. 下载模块


注,本部分参考了前人的相关实现,见 http://apps.hi.baidu.com/share/detail/24172508


01
void downFile(final String url) {
02
pBar.show();
03
new Thread() {
04
public void run() {
05
HttpClient client = new DefaultHttpClient();
06
HttpGet get = new HttpGet(url);
07
HttpResponse response;
08
try {
09
response = client.execute(get);
10
HttpEntity entity = response.getEntity();
11
long length = entity.getContentLength();
12
InputStream is = entity.getContent();
13
FileOutputStream fileOutputStream = null;
14
if (is != null) {
15
File file = new File(
16
Environment.getExternalStorageDirectory(),
17
Config.UPDATE_SAVENAME);
18
fileOutputStream = new FileOutputStream(file);
19
byte[] buf = new byte[1024];
20
int ch = -1;
21
int count = 0;
22
while ((ch = is.read(buf)) != -1) {
23
fileOutputStream.write(buf, 0, ch);
24
count += ch;
25
if (length > 0) {
26
}
27
}
28
}
29
fileOutputStream.flush();
30
if (fileOutputStream != null) {
31
fileOutputStream.close();
32
}
33
down();
34
} catch (ClientProtocolException e) {
35
e.printStackTrace();
36
} catch (IOException e) {
37
e.printStackTrace();
38
}
39
}
40
}.start();
41
}
下载完成,通过handler通知主ui线程将下载对话框取消。


1
void down() {
2
handler.post(new Runnable() {
3
public void run() {
4
pBar.cancel();
5
update();
6
}
7
});
8
}
5. 安装应用


1
<strong> void update() {
2
Intent intent = new Intent(Intent.ACTION_VIEW);
3
intent.setDataAndType(Uri.fromFile(new File(Environment
4
.getExternalStorageDirectory(), Config.UPDATE_SAVENAME)),
5
"application/vnd.android.package-archive");
6
startActivity(intent);
7
}</strong>
如果你将apk应用发布到market上,那么,你会发现market内建了类似的模块,可以自动更新或者提醒你是否更新应用。那么,对于你自己的 应用需要自动更新的话,自己内建一个是不是更加方便了呢?本文提到的代码大多是在UpdateActivity.java中实现,为了能够使更新过程更加 友好,可以在最初launcher的Activity中建立一个线程,用来检查服务端是否有更新。有更新的时候就启动UpdateActivity,这样 的使用体验更加平滑。


本文例程源码查看/下载:
http://code.google.com/p/androidex/source/browse/trunk/jtapp-12-updateapksamples


版权归个人所有,转载请注明出处


http://blog.csdn.net/xjanker2/archive/2011/04/06/6303937.aspx

更多相关文章

  1. Flutter 与 Android(安卓)的交互
  2. Qt for Android使用grpc探索
  3. 微信Android模块化架构重构实践
  4. 激进地用着Android(安卓)Studio
  5. Android特色开发之账户管理
  6. android手把手教你开发launcher(五)
  7. Android之组件详解
  8. Android(安卓)输入法遮挡问题
  9. android中selector在java代码中使用无效的解决方案

随机推荐

  1. 创建android Notification
  2. Android(安卓)imageView图片按比例缩放
  3. Android之提高Service优先级总结及androi
  4. Android(安卓)anr介绍
  5. android studio无法更新之解决方案
  6. android布局及常见布局属性 二
  7. 详解 Android(安卓)的 Activity 组件
  8. Android(安卓)集成FaceBook广告
  9. Android(安卓)的设备节点
  10. Android(安卓)监听短信2种方式:Broadcast