http://www.open-open.com/lib/view/open1339581191209.html
步骤:
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大写了,改小写后解决;
4077

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



