步骤:
1.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName。
2.从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面。
3.当提示用户进行版本升级时,如果用户点击了确定,系统将自动从服务器上下载并进行自动升级,如果点击取消将进入程序主界面。




01 | 获取当前程序的版本号: |
02 |
03 | 1./*
|
04 | 2. * 获取当前程序的版本号 |
05 | 3. */ |
06 | 4.private
String getVersionName() throws
Exception{ |
07 | 5. //获取packagemanager的实例
|
08 | 6. PackageManager packageManager = getPackageManager();
|
09 | 7. //getPackageName()是你当前类的包名,0代表是获取版本信息
|
10 | 8. PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(),
0); |
11 | 9. return
packInfo.versionName; |
12 | 10.} |
01 | 获取服务器端的版本号: |
02 | 1./*
|
03 | 2. * 用pull解析器解析服务器返回的xml文件 (xml封装了版本号)
|
04 | 3. */ |
05 | 4.public
static UpdataInfo getUpdataInfo(InputStream is)
throws Exception{
|
06 | 5. XmlPullParser parser = Xml.newPullParser();
|
07 | 6. parser.setInput(is,
"utf-8");//设置解析的数据源
|
08 | 7. int
type = parser.getEventType(); |
09 | 8. UpdataInfo info =
new UpdataInfo();//实体
|
10 | 9. while(type != XmlPullParser.END_DOCUMENT ){
|
11 | 10.
switch (type) { |
12 | 11.
case XmlPullParser.START_TAG:
|
13 | 12.
if("version".equals(parser.getName())){
|
14 | 13. info.setVersion(parser.nextText());
//获取版本号 |
15 | 14. }else
if ("url".equals(parser.getName())){
|
16 | 15. info.setUrl(parser.nextText());
//获取要升级的APK文件 |
17 | 16. }else
if ("description".equals(parser.getName())){
|
18 | 17. info.setDescription(parser.nextText());
//获取该文件的信息 |
19 | 18. }
|
20 | 19.
break; |
21 | 20. }
|
22 | 21. type = parser.next();
|
23 | 22. }
|
24 | 23.
return info; |
25 | 24.} |
01 | 从服务器下载apk: |
02 | 1.public
static File getFileFromServer(String path, ProgressDialog pd)
throws Exception{
|
03 | 2. //如果相等的话表示当前的sdcard挂载在手机上并且是可用的
|
04 | 3. if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
|
05 | 4. URL url =
new URL(path); |
06 | 5. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
07 | 6. conn.setConnectTimeout(5000);
|
08 | 7.
//获取到文件的大小 |
09 | 8. pd.setMax(conn.getContentLength());
|
10 | 9. InputStream is = conn.getInputStream();
|
11 | 10. File file =
new File(Environment.getExternalStorageDirectory(),
"updata.apk"); |
12 | 11. FileOutputStream fos =
new FileOutputStream(file);
|
13 | 12. BufferedInputStream bis =
new BufferedInputStream(is);
|
14 | 13.
byte[] buffer = new
byte[1024];
|
15 | 14.
int len ; |
16 | 15.
int total=0;
|
17 | 16.
while((len =bis.read(buffer))!=-1){
|
18 | 17. fos.write(buffer,
0, len); |
19 | 18. total+= len;
|
20 | 19.
//获取当前下载量 |
21 | 20. pd.setProgress(total);
|
22 | 21. }
|
23 | 22. fos.close();
|
24 | 23. bis.close();
|
25 | 24. is.close();
|
26 | 25.
return file; |
27 | 26. }
|
28 | 27.
else{ |
29 | 28.
return null;
|
30 | 29. }
|
31 | 30.} |
匹配、下载、自动安装:
01 | /* |
02 | * 从服务器获取xml解析并进行比对版本号
|
03 | */ |
04 | public class
CheckVersionTask implements
Runnable{ |
05 | |
06 | public
void run() { |
07 | try
{ |
08 | //从资源文件获取服务器 地址
|
09 | String path = getResources().getString(R.string.serverurl);
|
10 | //包装成url的对象
|
11 | URL url =
new URL(path); |
12 | HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
13 | conn.setConnectTimeout(5000);
|
14 | InputStream is =conn.getInputStream();
|
15 | info = UpdataInfoParser.getUpdataInfo(is);
|
16 | |
17 | if(info.getVersion().equals(versionname)){
|
18 | Log.i(TAG,"版本号相同无需升级");
|
19 | LoginMain();
|
20 | }else{
|
21 | Log.i(TAG,"版本号不同 ,提示用户升级 ");
|
22 | Message msg =
new Message(); |
23 | msg.what = UPDATA_CLIENT;
|
24 | handler.sendMessage(msg);
|
25 | }
|
26 | }
catch (Exception e) { |
27 | // 待处理
|
28 | Message msg =
new Message(); |
29 | msg.what = GET_UNDATAINFO_ERROR;
|
30 | handler.sendMessage(msg);
|
31 | e.printStackTrace();
|
32 | }
|
33 | }
|
34 | } |
01 | Handler handler = new
Handler(){ |
02 | @Override |
03 | public
void handleMessage(Message msg) {
|
04 | // TODO Auto-generated method stub
|
05 | super.handleMessage(msg);
|
06 | switch
(msg.what) { |
07 | case
UPDATA_CLIENT: |
08 | //对话框通知用户升级程序
|
09 | showUpdataDialog();
|
10 | break;
|
11 | case
GET_UNDATAINFO_ERROR: |
12 | //服务器超时
|
13 | Toast.makeText(getApplicationContext(),
"获取服务器更新信息失败", 1).show();
|
14 | LoginMain();
|
15 | break;
|
16 | case
DOWN_ERROR: |
17 | //下载apk失败
|
18 | Toast.makeText(getApplicationContext(),
"下载新版本失败", 1).show();
|
19 | LoginMain();
|
20 | break;
|
21 | }
|
22 | }
|
23 | }; |
01 | /* |
02 | *
|
03 | * 弹出对话框通知用户更新程序
|
04 | *
|
05 | * 弹出对话框的步骤:
|
06 | * 1.创建alertDialog的builder.
|
07 | * 2.要给builder设置属性, 对话框的内容,样式,按钮
|
08 | * 3.通过builder 创建一个对话框
|
09 | * 4.对话框show()出来
|
10 | */ |
11 | protected
void showUpdataDialog() { |
12 | AlertDialog.Builder builer =
new Builder(this) ;
|
13 | builer.setTitle("版本升级");
|
14 | builer.setMessage(info.getDescription());
|
15 | //当点确定按钮时从服务器上下载 新的apk 然后安装
|
16 | builer.setPositiveButton("确定",
new OnClickListener() {
|
17 | public
void onClick(DialogInterface dialog,
int which) { |
18 | Log.i(TAG,"下载apk,更新");
|
19 | downLoadApk();
|
20 | }
|
21 | });
|
22 | //当点取消按钮时进行登录
|
23 | builer.setNegativeButton("取消",
new OnClickListener() {
|
24 | public
void onClick(DialogInterface dialog,
int which) { |
25 | // TODO Auto-generated method stub
|
26 | LoginMain();
|
27 | }
|
28 | });
|
29 | AlertDialog dialog = builer.create();
|
30 | dialog.show();
|
31 | } |
01 | /* |
02 | * 从服务器中下载APK
|
03 | */ |
04 | protected
void downLoadApk() { |
05 | final
ProgressDialog pd; //进度条对话框
|
06 | pd =
new ProgressDialog(this);
|
07 | pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
08 | pd.setMessage("正在下载更新");
|
09 | pd.show();
|
10 | new
Thread(){ |
11 | @Override |
12 | public
void run() { |
13 | try
{ |
14 | File file = DownLoadManager.getFileFromServer(info.getUrl(), pd);
|
15 | sleep(3000);
|
16 | installApk(file);
|
17 | pd.dismiss();
//结束掉进度条对话框 |
18 | }
catch (Exception e) {
|
19 | Message msg =
new Message(); |
20 | msg.what = DOWN_ERROR;
|
21 | handler.sendMessage(msg);
|
22 | e.printStackTrace();
|
23 | }
|
24 | }}.start();
|
25 | } |
1 | //安装apk |
2 | protected
void installApk(File file) { |
3 | Intent intent =
new Intent(); |
4 | //执行动作
|
5 | intent.setAction(Intent.ACTION_VIEW);
|
6 | //执行的数据类型
|
7 | intent.setDataAndType(Uri.fromFile(file),
"application/vnd.Android.package-archive");//编者按:此处Android应为android,否则造成安装不了
|
8 | startActivity(intent);
|
9 | } |
1 | /* |
2 | * 进入程序的主界面
|
3 | */ |
4 | private void
LoginMain(){ |
5 | Intent intent =
new Intent(this,MainActivity.class);
|
6 | startActivity(intent);
|
7 | //结束掉当前的activity
|
8 | this.finish();
|
9 | } |
二、参考后使用情况:
1.可以下载apk,但安装失败:
1)以为配置文件中需定义了android.permission.INSTALL_PACKAGES,其实不需;
2)以为是要在执行安装的activity中配置
1 | <intent-filter> |
2 | <action
android:name="android.intent.action.VIEW"
/> |
3 | <category
android:name="android.intent.category.DEFAULT"
/> |
4 | </intent-filter> |
,其实不是;
3)代码中application/vnd.Android.package-archive有一个字母A大写了,改小写后解决;
本文介绍了如何通过检测当前版本信息、从服务器获取版本号、比较版本并进行自动升级的过程,包括获取当前程序版本号、从服务器下载APK、自动安装升级等功能。
4096

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



