package com.coderdream.mobilesafe.activity; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import org.xmlpull.v1.XmlPullParserException; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.Window; import android.view.WindowManager; import android.view.animation.AlphaAnimation; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import com.coderdream.mobilesafe.R; import com.coderdream.mobilesafe.domain.UpdateInfo; import com.coderdream.mobilesafe.engine.UpdateInfoParser; public class SplashActivity extends Activity { private TextView tv_splash_version; private UpdateInfo info; private static final int GET_INFO_SUCCESS = 10; private static final int SERVER_ERROR = 11; private static final int SERVER_URL_ERROR = 12; private static final int PROTOCOL_ERROR = 13; private static final int IO_ERROR = 14; private static final int XML_PARSE_ERROR = 15; private static final int DOWNLOAD_SUCCESS = 16; private static final int DOWNLOAD_ERROR = 17; protected static final String TAG = "SplashActivity"; private long startTime; private RelativeLayout rl_splash; private long endTime; private ProgressDialog pd; private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case XML_PARSE_ERROR: Toast.makeText(getApplicationContext(), "xml解析錯誤", Toast.LENGTH_LONG).show(); // loadMainUI(); break; case IO_ERROR: Toast.makeText(getApplicationContext(), "I/O錯誤", Toast.LENGTH_LONG).show(); // loadMainUI(); break; case PROTOCOL_ERROR: Toast.makeText(getApplicationContext(), "協議不支持", Toast.LENGTH_LONG).show(); // loadMainUI(); break; case SERVER_URL_ERROR: Toast.makeText(getApplicationContext(), "服務器路徑不正確", Toast.LENGTH_LONG).show(); // loadMainUI(); break; case SERVER_ERROR: Toast.makeText(getApplicationContext(), "服務器內部異常", Toast.LENGTH_LONG).show(); // loadMainUI(); break; case GET_INFO_SUCCESS: String serverversion = info.getVersion(); String currentversion = getVersion(); if (currentversion.equals(serverversion)) { Log.i(TAG, "版本號相同進入主界面"); // loadMainUI(); } else { Log.i(TAG, "版本號不相同,升級對話框"); showUpdateDialog(); } break; case DOWNLOAD_SUCCESS: Log.i(TAG, "文件下載成功"); // File file = (File) msg.obj; // installApk(file); break; case DOWNLOAD_ERROR: Toast.makeText(getApplicationContext(), "下載數據異常", Toast.LENGTH_LONG).show(); // loadMainUI(); break; } }; }; /** * 顯示升級提示的對話框 */ protected void showUpdateDialog() { // 建立了對話框的構造器 AlertDialog.Builder builder = new Builder(this); // 設置對話框的提示內容 builder.setIcon(getResources().getDrawable(R.drawable.notification)); // 設置升級標題 builder.setTitle("升級提示"); // 設置升級提示內容 builder.setMessage(info.getDescription()); // 建立下載進度條 pd = new ProgressDialog(SplashActivity.this); // 設置進度條在顯示時的提示消息 pd.setMessage("正在下載"); // 指定顯示下載進度條爲水平形狀 pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); // 設置升級按鈕 builder.setPositiveButton("升級", new OnClickListener() { public void onClick(DialogInterface dialog, int which) { // loadMainUI(); } }); builder.setNegativeButton("取消", new OnClickListener() { public void onClick(DialogInterface dialog, int which) { // loadMainUI(); } }); builder.create().show(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 設置爲無標題欄 requestWindowFeature(Window.FEATURE_NO_TITLE); // 設置爲全屏模式 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_splash); rl_splash = (RelativeLayout) findViewById(R.id.rl_splash); tv_splash_version = (TextView) findViewById(R.id.tv_splash_version); tv_splash_version.setText("版本號:" + getVersion()); AlphaAnimation aa = new AlphaAnimation(0.3f, 1.0f); aa.setDuration(2000); rl_splash.startAnimation(aa); // 1.鏈接服務器獲取服務器上的配置信息. new Thread(new CheckVersionTask()) { }.start(); } /** * 連網檢查應用的版本號與服務端上的版本號是否相同 * * @author Administrator * */ private class CheckVersionTask implements Runnable { public void run() { // 獲取Sdcard下的config.xml文件,若是該文件不存在,那麼將會自動建立該文件 SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE); // 由sp對象來獲取autoupdate所對應的boolean值,若是該鍵不存在,默認返回true boolean autoupdate = sp.getBoolean("autoupdate", true); // 自動更新沒有開啓 if (!autoupdate) { try { // 睡眠2秒鐘的是爲了播放動畫 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } // 睡眠2秒鐘播放動畫完畢後進入程序主界面 // loadMainUI(); } startTime = System.currentTimeMillis(); Message msg = Message.obtain(); try { // 獲取服務端的配置信息的鏈接地址 String serverurl = getResources().getString(R.string.serverurl); URL url = new URL(serverurl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET");// 設置請求方式 conn.setConnectTimeout(5000); int code = conn.getResponseCode();// 獲取響應碼 if (code == 200) {// 響應碼爲200時,表示與服務端鏈接成功 InputStream is = conn.getInputStream(); info = UpdateInfoParser.getUpdateInfo(is); endTime = System.currentTimeMillis(); long resulttime = endTime - startTime; if (resulttime < 2000) { try { Thread.sleep(2000 - resulttime); } catch (InterruptedException e) { e.printStackTrace(); } } msg.what = GET_INFO_SUCCESS; handler.sendMessage(msg); } else { // 服務器狀態錯誤. msg.what = SERVER_ERROR; handler.sendMessage(msg); endTime = System.currentTimeMillis(); long resulttime = endTime - startTime; if (resulttime < 2000) { try { Thread.sleep(2000 - resulttime); } catch (InterruptedException e) { e.printStackTrace(); } } } } catch (MalformedURLException e) { e.printStackTrace(); msg.what = SERVER_URL_ERROR; handler.sendMessage(msg); } catch (ProtocolException e) { msg.what = PROTOCOL_ERROR; handler.sendMessage(msg); e.printStackTrace(); } catch (IOException e) { msg.what = IO_ERROR; handler.sendMessage(msg); e.printStackTrace(); } catch (XmlPullParserException e) { msg.what = XML_PARSE_ERROR; handler.sendMessage(msg); e.printStackTrace(); } } } /** * <pre> * 獲取當前應用程序的版本號。 * 版本號存在於咱們的APK中對應的清單文件中(直接解壓APK後,便可看到對應的清單文件), * 版本號是manifest節點中的android:versionName="1.0" * 當一個應用程序被裝到手機後 ,該apk拷貝到手機的data/app目錄下(也就是系統中), * 如圖6。因此想獲得版本號,咱們須要拿到與系統相關的服務,就能夠獲得apk中的信息了 * * </pre> * * @return */ private String getVersion() { // 獲得系統的包管理器。已經獲得了apk的面向對象的包裝 PackageManager pm = this.getPackageManager(); try { // 參數一:當前應用程序的包名 參數二:可選的附加消息,這裏咱們用不到 ,能夠定義爲0 PackageInfo info = pm.getPackageInfo(getPackageName(), 0); // 返回當前應用程序的版本號 return info.versionName; } catch (Exception e) {// 包名未找到的異常,理論上, 該異常不可能會發生 e.printStackTrace(); return ""; } } }
package com.coderdream.mobilesafe.domain; public class UpdateInfo { private String version; private String description; private String apkurl; public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getApkurl() { return apkurl; } public void setApkurl(String apkurl) { this.apkurl = apkurl; } }
清單 03. UpdateInfoParser.javahtml
package com.coderdream.mobilesafe.engine; import java.io.IOException; import java.io.InputStream; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.util.Xml; import com.coderdream.mobilesafe.domain.UpdateInfo; /** * * 解析XML數據 * */ public class UpdateInfoParser { /** * @param is * xml文件的輸入流 * @return updateinfo的對象 * @throws XmlPullParserException * @throws IOException */ public static UpdateInfo getUpdateInfo(InputStream is) throws XmlPullParserException, IOException { // 得到一個Pull解析的實例 XmlPullParser parser = Xml.newPullParser(); // 將要解析的文件流傳入 parser.setInput(is, "UTF-8"); // 建立UpdateInfo實例,用於存放解析獲得的xml中的數據,最終將該對象返回 UpdateInfo info = new UpdateInfo(); // 獲取當前觸發的事件類型 int type = parser.getEventType(); // 使用while循環,若是得到的事件碼是文檔結束的話,那麼就結束解析 while (type != XmlPullParser.END_DOCUMENT) { if (type == XmlPullParser.START_TAG) {// 開始元素 if ("version".equals(parser.getName())) {// 判斷當前元素是不是讀者須要檢索的元素,下同 // 由於內容也至關於一個節點,因此獲取內容時須要調用parser對象的nextText()方法才能夠獲得內容 String version = parser.nextText(); info.setVersion(version); } else if ("description".equals(parser.getName())) { String description = parser.nextText(); info.setDescription(description); } else if ("apkurl".equals(parser.getName())) { String apkurl = parser.nextText(); info.setApkurl(apkurl); } } type = parser.next(); } return info; } }
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="serverurl">http://192.168.0.101:8080/info.xml</string> </resources>