Android項目實戰手機安全衛士(02)

目錄

  • 項目結構圖
  • 源代碼
  • 運行結果
  • 項目源代碼

項目結構圖

V0101_01

源代碼

清單 01.  SplashActivity.java

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 "";
		}
	}
}

清單 02. UpdateInfo.java

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;
	}
}

清單 03. config.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="serverurl">http://192.168.0.101:8080/info.xml</string>

</resources>

運行結果

V0101_02

工程源代碼

地址:http://download.csdn.net/detail/xuxiheng/8147099java

相關文章
相關標籤/搜索