標籤:伺服器 private android public upgrade
應用升級大致步驟:
檢測是否有更新(讀取伺服器config檔案,比對版本號碼)
若發現高版本則讀取更新檔案updateinfo.xml擷取下載更新相關資訊
校正資訊確認升級後,下載apk
下載完apk後,進行MD5檢驗apk的完整性
安裝apk
升級入口
private void upgrade() {//需要訪問網路,避免主線程堵塞new Thread(){public void run() {if(checkUpdate()){//檢查更新handler.sendEmptyMessage(20);//通知介面提示有版本更新}};}.start();}private boolean checkUpdate(){String url = PATH_SERVER + "upgrade/config";//從config檔案讀取Version資訊,和UpdateInfo.xml檔案地址try {updateInfoMap = ParseUpdateFile.getConfigInfo(url);} catch (Exception e) {e.printStackTrace();}//擷取當前apk的版本號碼PackageInfo packageInfo = null;try {packageInfo = MainActivity.this.getPackageManager().getPackageInfo(MainActivity.this.getPackageName(), 0);} catch (Exception e) {e.printStackTrace();}int updateVCode = Integer.valueOf(updateInfoMap.get("Version"));//伺服器端apk版本高於現在的版本,則讀取updateinfo.xml檔案if(updateVCode > packageInfo.versionCode){url = PATH_SERVER+"upgrade/updateinfo.xml";try {updateInfoMap.putAll(ParseXmlUtil.parseXml(url));} catch (Exception e) {e.printStackTrace();}//輸出讀取結果Set<String> set = updateInfoMap.keySet();System.out.println("map.size():"+updateInfoMap.size());for (Iterator<String> iterator = set.iterator(); iterator.hasNext();) {String string = (String) iterator.next();System.out.println(string + "——>" + updateInfoMap.get(string));}//檢查資訊合法性,通過則發送可更新訊息return checkUpdateInfo(updateInfoMap);}return false;}
解析config檔案
public static Map<String,String> getConfigInfo(String strURL) throws Exception {Map<String,String> configMap = new HashMap<String, String>();URL url = new URL(strURL);URLConnection conn = url.openConnection();if (conn == null) {return configMap;}InputStream inputStream = conn.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream);BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String str = null;while (null != (str=bufferedReader.readLine())) {if (str != null) {if (str.contains("Version=")) {configMap.put("Version", str.substring(str.indexOf("=")+1));}if (str.contains("VersionServer")) {configMap.put("VersionServer", str.substring(str.indexOf("::")+2));}}}bufferedReader.close();return configMap;}
checkUpdateInfo()主要校正資訊的合法性
private boolean checkUpdateInfo(Map<String, String> updateInfoMap){String downloadPath = updateInfoMap.get("DownloadPath");String packageName = updateInfoMap.get("packageName");String versionCode = updateInfoMap.get("versionCode");String updateVCode = updateInfoMap.get("Version");if (checkUrl(downloadPath)//檢測是否可訪問&& versionCode.equals(updateVCode)//config和updateinfoxml檔案中版本號碼是否一致&& packageName.equals(getPackageName())) {//包名return true;}return false;}
下載檔案到裝置需要許可權
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
private void downLoadAPK(){new Thread() {public void run() {String downLoadPath = updateInfoMap.get("DownloadPath");String downLoadDir = "/acfg/";File fileDir = new File(downLoadDir);if (!fileDir.exists()) {fileDir.mkdir();}String fileName = downLoadDir + downLoadPath.substring(downLoadPath.lastIndexOf("/")+1);File file = new File(fileName);if (file.exists()) {file.delete();}try {file.createNewFile();// 構造URLURL url = new URL(downLoadPath);// 開啟串連URLConnection con = url.openConnection();// 獲得檔案的長度int contentLength = con.getContentLength();System.out.println("長度 :" + contentLength);// 輸入資料流InputStream is = con.getInputStream();// 1K的資料緩衝byte[] bs = new byte[1024];// 讀取到的資料長度int len;// 輸出的檔案流OutputStream os = new FileOutputStream(fileName);// 開始讀取while ((len = is.read(bs)) != -1) {os.write(bs, 0, len);}// 完畢,關閉所有連結os.close();is.close();updateInfoMap.put("fileName", fileName);} catch (Exception e) {e.printStackTrace();handler.sendEmptyMessage(22);}handler.sendEmptyMessage(21);//通知介面下載完成};}.start();}
下載完成後核對apk的MD5值
File file = new File(fileName);String fileMD5 = MD5Util.getMD5OfFile(file);if (fileMD5.equals(activity.updateInfoMap.get("md5sum"))) { Toast.makeText(activity, "Download Finished. It‘s ready to update!", Toast.LENGTH_LONG).show(); activity.update(fileName);}
擷取檔案的MD5值
public static String getMD5OfFile(File file) {String value = null;FileInputStream in = null;try {in = new FileInputStream(file);MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());MessageDigest md5 = MessageDigest.getInstance("MD5");md5.update(byteBuffer);BigInteger bi = new BigInteger(1, md5.digest());value = bi.toString(16).toUpperCase(Locale.ENGLISH);} catch (Exception e) {e.printStackTrace();} finally {if (null != in) {try {in.close();} catch (IOException e) {e.printStackTrace();}}}return value;}
安裝下載好的apk
private void update(String filePath) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(filePath)), "application/vnd.android.package-archive"); startActivity(intent);}
安裝完成後進入應用
Android應用升級,檢測更新,下載,檢驗,安裝