Android项目实战手机安全卫士(02)

目录

  • 项目结构图
  • 源代码
  • 运行结果
  • 项目源代码

项目结构图

源代码

清单 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.java

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>

运行结果

工程源代码

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

时间: 2024-10-13 21:59:59

Android项目实战手机安全卫士(02)的相关文章

Android项目实战手机安全卫士(01)

目录 项目结构图 源代码 运行结果 项目结构图 源代码 SplashActivity.java package com.coderdream.mobilesafe.activity; import android.app.Activity; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Bundle; import android.view.Wi

Android 项目实战--手机卫士(实现splash)

从今天开始根据之前学习的android的基础知识,实战一下,实现一个简单功能的android手机卫士 本文地址:http://www.cnblogs.com/wuyudong/p/5899283.html,转载请注明源地址. 手机卫士的主要功能如下: 手机页面的splash页面初步如下: splash布局 相应的代码在布局文件activity_splash.xml文件中: <RelativeLayout xmlns:android="http://schemas.android.com/a

Android项目实战(十二):解决OOM的一种偷懒又有效的办法

原文:Android项目实战(十二):解决OOM的一种偷懒又有效的办法 在程序的manifest文件的application节点加入android:largeHeap=“true” 即可. 对,只需要一句话! 那么这行代码的意思是什么呢? 简单的说就是使该APP获取最大可分配的内存,以便解决OOM问题. 但是.OOM问题出现的原因总得来说有两点: 1.某个手机的内存真的很少 2.代码问题,比如没有处理好Bitmap图片的大小 可以说,出现OOM的情况基本都是第二种情况,那么就需要修改代码,看看哪

Android项目实战(七):Dialog主题Activity实现自定义对话框效果

原文:Android项目实战(七):Dialog主题Activity实现自定义对话框效果 想必大家都用过Dialog主题的Activity吧,用它来显示自定义对话框效果绝对是一个非常不错的选择. 即把activity交互界面以Dialog的形式展现出来,Dialog主题的Activity大小将以内容的宽高来决定 <activity android:name=”MainActivity” android:theme=”@android:style/Theme.Dialog”> </acti

Android项目实战(三十四):蓝牙4.0 BLE 多设备连接

原文:Android项目实战(三十四):蓝牙4.0 BLE 多设备连接 最近项目有个需求,手机设备连接多个蓝牙4.0 设备 并获取这些设备的数据. 查询了很多资料终于实现,现进行总结. -------------------------------------------------------------------------------------------------------------------------------------------------------------

Android项目实战(四十二):启动页优化,去除短暂白屏或黑屏

原文:Android项目实战(四十二):启动页优化,去除短暂白屏或黑屏 大家会发现一个空项目,从手机桌面打开app是秒启动.但是对于自己开发的项目,有时会发现打开app的时候,会有短暂的1秒--2秒的白屏或者黑屏,然后才进入到程序界面. 个人理解为我们自己实现的Application文件里面做了较多的初始化操作,当这些初始化操作完成后才进入到第一个Activity,这段初始化的时间因为没有界面,应用便会因为主题的类别而显示白屏或者黑屏. 构成白屏/黑屏的原因代码如下: /*** @author

android项目实战-背呗单词00-文章目录

一.准备篇android项目实战-背呗单词00-文章目录android项目实战-背呗单词01-软件说明android项目实战-背呗单词02-项目概述android项目实战-背呗单词03-项目图表android项目实战-背呗单词04-项目数据库说明 二.重要技术实现说明android项目实战-背呗单词DEV00-程序环境构架搭建android项目实战-背呗单词DEV01-拷贝单词书实现android项目实战-背呗单词DEV02-创建计划实现android项目实战-背呗单词DEV03-创建任务实现a

(转载)Android项目实战(三十二):圆角对话框Dialog

Android项目实战(三十二):圆角对话框Dialog 前言: 项目中多处用到对话框,用系统对话框太难看,就自己写一个自定义对话框. 对话框包括:1.圆角 2.app图标 , 提示文本,关闭对话框的"确定"按钮 难点:1.对话框边框圆角显示 2.考虑到提示文本字数不确定,在不影响美观的情况下,需要在一行内显示提示的文字信息   3.设置对话框的宽和高 技术储备: 1.安卓开发_使用AlertDialog实现对话框    知道AlertDialog有setView(view) ,Dia

android项目实战-背呗单词DEV07-单词测试实现

该篇说明 该篇我们进行单词测试实现讲解 也就是单词测试界面WordExamActivity中功能 布局也需要在xml中实现 但是也需要有单词测试视图类来设置一些值具体查看对照源码 在该界面中,测试完后会更新数据 效果如图 流程图 单词测试界面功能流程详解 1> 显示单词测试信息 a> 首先要加载单词测试数据 需要调用单词测试管理模块加载数据功能 private void loadWordExamData() { loadingExamDataProgressBar = (ProgressBar