android apk自动升级实现

来源:互联网 发布:oracle数据库多少钱 编辑:程序博客网 时间:2024/06/09 03:08
由于Android项目开源所致,市面上出现了N多安卓软件市场。为了让我们开发的软件有更多的用户使用,我们需要向N多市场发布,软件升级后,我们也必须到安卓市场上进行更新,给我们增加了工作量。因此我们有必要给我们的Android应用增加自动更新的功能。而用户一键就可以完成软件的升级更新。得益于Android系统的软件包管理和安装机制。
实现思路:
从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面。

update.JPEG 
一.服务器xml自定义信息
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <update>
  3. <version>1.0.2</version>
  4. <versionCode>2</versionCode>
  5. <updateTime>20120515</updateTime>
  6. <apkName>sems_02_20120425.apk</apkName>
  7. <downloadURL>http://192.168.2.57:95/updater/sems.apk</downloadURL>
  8. <displayMessage>新版本发布,赶紧下载吧 ## 1.地图模式 ## 2.列表模式## 3.自动更新</displayMessage>
  9. </update>
复制代码
version标签为当前版本号
versionCode用来对比是否需要升级
updateTime用来显示更新的时间
displayMessage 版本更新的信息

二.客户端定时检查(或自定义触发检查)是否需要更新
  1.         /**
  2.          * 方法描述  检查是否有更新的版本发布
  3.          * @author hechuan
  4.          * @createTime  2012-5-3
  5.          */
  6.         public void checkUpdateInfo(int type) {
  7.                 // TODO check是否需要更新
  8.                  PreferenceManager.getDefaultSharedPreferences(mContext);
  9.                 connect();//与服务端交互获取版本信息
  10.                 try {
  11.                  pi = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), PackageManager.GET_CONFIGURATIONS);//获取当前包信息
  12.                 } catch (NameNotFoundException e) {
  13.                         e.printStackTrace();
  14.                 }
  15.                 versionCode = pi.versionCode;//获取当前的版本号
  16.                 if(versionCode>=info.getVersionCode()){
  17.                         if(type == ConstanseUtils.UPDATE_TYPE_SELF){
  18.                         DialogUtil.showNoNeedUpdate(mContext);
  19.                         }
  20.                         return;
  21.                 }else{
  22.                 showNoticeDialog();//弹出提示更新框
  23.                 }
  24.         }
复制代码
  1.         /**
  2.          * 方法描述  与服务端交互,获取更新版本的信息
  3.          * @author hechuan
  4.          * @createTime  2012-5-3
  5.          */
  6.         private void connect() {
  7.                 URL url = null;
  8.                 try {
  9.                         // 构造一个URL对象
  10.                         url = new URL(ConstanseUtils.COMMON_URL_START + PreferencesUtils.getServer()
  11.                                         + ConstanseUtils.UPDATE_URL_END);
  12.                 } catch (MalformedURLException e) {
  13.                         Log.e("debug", "MalformedURLException");
  14.                 }
  15.                 if (url != null) {
  16.                         try {
  17.                                 // 使用HttpURLConnection打开连接
  18.                                 HttpURLConnection urlConn = (HttpURLConnection) url
  19.                                                 .openConnection();
  20.                                 // 得到读取的内容(流)
  21.                                 info = XMLParserUtils.getUpdateInfo(urlConn.getInputStream());
  22.                                 urlConn.disconnect();
  23.                                 // 设置显示取得的内容
  24.                         } catch (IOException e) {
  25.                                 Log.e("debug", "IOException");
  26.                         } catch (Exception e) {
  27.                                 e.printStackTrace();
  28.                         }
  29.                 } else {
  30.                         Log.e("DEBUG_TAG", "Url NULL");
  31.                 }
  32.         }
复制代码
xml解析代码片段
  1.    case XmlPullParser.START_TAG:
  2.                             if ("version".equals(parser.getName())) {
  3.                                 info.setVersion(parser.nextText());
  4.                             } else if ("updateTime".equals(parser.getName())) {
  5.                                     info.setUpdateTime(parser.nextText());
  6.                             } else if ("downloadURL".equals(parser.getName())) {
  7.                                 info.setDownloadURL(parser.nextText());
  8.                             } else if ("displayMessage".equals(parser.getName())) {
  9.                                     info.setDisplayMessage(parseTxtFormat(parser.nextText()));
  10.                             } else if ("apkName".equals(parser.getName())) {
  11.                                     info.setApkName(parser.nextText());
  12.                             } else if ("versionCode".equals(parser.getName())) {
  13.                                     info.setVersionCode(Integer.parseInt(parser.nextText()));
  14.                             }
复制代码
三.如果检查到有新的版本需要更新,弹出下载框,提示用户下载。点击下载后,界面动态显示下载进度
  1.         /**
  2.          * 方法描述  弹出下载apk框
  3.          * @author hechuan
  4.          * @createTime  2012-5-3
  5.          */
  6.         private void showDownloadDialog() {
  7.                 final Resources r = mContext.getResources();
  8.                 AlertDialog.Builder builder = new Builder(mContext);
  9.                 builder.setTitle(r.getString(R.string.update_downapk_title));

  10.                 final LayoutInflater inflater = LayoutInflater.from(mContext);
  11.                 View v = inflater.inflate(R.layout.update_progress, null);
  12.                 mProgress = (ProgressBar) v.findViewById(R.id.pb_update_progress);

  13.                 builder.setView(v);
  14.                 builder.setNegativeButton(r.getString(R.string.common_cancle), new OnClickListener() {
  15.                         @Override
  16.                         public void onClick(DialogInterface dialog, int which) {
  17.                                 dialog.dismiss();
  18.                                 interceptFlag = true;//点击取消后,停止下载
  19.                         }
  20.                 });
  21.                 downloadDialog = builder.create();
  22.                 downloadDialog.show();

  23.                 downloadApk();//下载apk
  24.         }
复制代码

动态更新进度
  1. private Runnable mdownApkRunnable = new Runnable() {
  2.                 @Override
  3.                 public void run() {
  4.                         try {
  5.                                 if (!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){
  6.                                         DialogUtil.showSDCARDNotSupport(mContext);
  7.                                         return;
  8.                                 }else{
  9.                                 URL url = new URL(ConstanseUtils.COMMON_URL_START + PreferencesUtils.getServer()
  10.                                                 + ConstanseUtils.APK_URL_END);
  11.                                 HttpURLConnection conn = (HttpURLConnection) url
  12.                                                 .openConnection();
  13.                                 conn.connect();
  14.                                 int length = conn.getContentLength();
  15.                                 InputStream is = conn.getInputStream();
  16.                                 File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ ConstanseUtils.UPDATE_SAVE_PATH);
  17.                                 if (!file.exists()) {
  18.                                         file.mkdir();
  19.                                 }
  20.                                 String apkFile = Environment.getExternalStorageDirectory().getAbsolutePath()+ ConstanseUtils.UPDATE_SAVE_PATH+info.getApkName();
  21.                                 File ApkFile = new File(apkFile);
  22.                                 FileOutputStream fos = new FileOutputStream(ApkFile);

  23.                                 int count = 0;
  24.                                 byte buf[] = new byte[1024];

  25.                                 do {
  26.                                         int numread = is.read(buf);
  27.                                         count += numread;
  28.                                         progress = (int) (((float) count / length) * 100);
  29.                                         // 更新进度
  30.                                         mHandler.sendEmptyMessage(DOWN_UPDATE);
  31.                                         if (numread <= 0) {
  32.                                                 // 下载完成通知安装
  33.                                                 mHandler.sendEmptyMessage(DOWN_OVER);
  34.                                                 break;
  35.                                         }
  36.                                         fos.write(buf, 0, numread);
  37.                                 } while (!interceptFlag);// 点击取消就停止下载.

  38.                                 fos.close();
  39.                                 is.close();
  40.                                 }
  41.                         } catch (MalformedURLException e) {
  42.                                 e.printStackTrace();
  43.                         } catch (IOException e) {
  44.                                 e.printStackTrace();
  45.                         }
  46.                 }
  47.         };
复制代码
update.jpg 
四.接收到下载完成的信息后,卸载旧版本,安装新版本
利用android 里面的handle来处理接收消息
  1.         private Handler mHandler = new Handler() {
  2.                 public void handleMessage(Message msg) {
  3.                         switch (msg.what) {
  4.                         case DOWN_UPDATE:
  5.                                 mProgress.setProgress(progress);//更新进度情况
  6.                                 break;
  7.                         case DOWN_OVER:
  8.                                 mProgress.setVisibility(View.INVISIBLE);
  9.                                 installApk();//安装apk文件
  10.                                 break;
  11.                         default:
  12.                                 break;
  13.                         }
  14.                 };
  15.         };
复制代码

安装apk
  1.         
  2.         /**
  3.          * 方法描述  安装下载的apk文件
  4.          * @author hechuan
  5.          * @createTime  2012-5-3
  6.          */
  7.         private void installApk() {
  8.                 File apkfile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ ConstanseUtils.UPDATE_SAVE_PATH+info.getApkName());//获取当前sdcard存储路径
  9.                 if (!apkfile.exists()) {
  10.                         return;
  11.                 }
  12.                 Intent i = new Intent(Intent.ACTION_VIEW);
  13.                 i.setDataAndType(Uri.fromFile(new File(apkfile.getAbsolutePath())),
  14.                                 "application/vnd.android.package-archive"); //安装   如果签名不一致,可能出现程序未安装提示
  15.                 mContext.startActivity(i);
  16.         }
复制代码
附:我们平时在anroid应用商店里面更新升级版本后,很多apk会提示程序未安装,导致升级失败,只是下载下来了最新的apk。
主要原因是apk签名不一致造成的。出现这种情况,直接在sdcard(下载保存地址)安装下载好的apk包即可。

路灯android版本最近即将推出,届时大家可以下载apk安装体验一下版本升级。








alert.jpg (428.74 KB, 下载次数: 0)

alert.jpg

原创粉丝点击