步骤:
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大写了,改小写后解决;