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
Android项目实战手机安全卫士(02)的更多相关文章
- Android项目实战手机安全卫士(01)
目录 项目结构图 源代码 运行结果 项目结构图 源代码 SplashActivity.java package com.coderdream.mobilesafe.activity; import a ...
- Android项目实战--手机卫士开发系列教程
<ignore_js_op> banner131010.jpg (71.4 KB, 下载次数: 0) 下载附件 保存到相册 2 分钟前 上传 Android项目实战--手机卫士01- ...
- Android 项目实战--手机卫士(实现splash)
从今天开始根据之前学习的android的基础知识,实战一下,实现一个简单功能的android手机卫士 本文地址:http://www.cnblogs.com/wuyudong/p/5899283.ht ...
- Android项目实战--手机卫士24--程序锁的实现以及逻辑
昨天我们已经把程序全部读取出来,显示到界面上了,那今天,我们就来讲一下那个程序锁的实现啦.其实也很简单啦,我们主要就是把用户要锁定的程序放到一个表里面,然后就监听手机里面的任务栈,如果发现任务栈里面出 ...
- Android项目实战--手机卫士20--拿到已经安装了的程序以及程序管理主界面
好了,之前我们就讲了高级工具里面的短信备份与还原,那么我们高级工具里面的功能就基本上完成的啦,还有一个叫程序锁的功能而已,但我们今天先不做它先,我们先把我们的程序管理这个功能完成先. 先让大家看一下我 ...
- Android项目实战--手机卫士18--读取用户的短信内容以及短信备份
我们今天要说的就是我们手机卫士里面的高级工具里面的短信备份功能啦,其实这个软件备份的功能也很简单,就是把用户的短信读出来,然后写到一个xml或者数据库里面, 但我们这里的是读取到xml里面的. 首先我 ...
- Android项目实战(二十九):酒店预定日期选择
先看需求效果图: 几个需求点: 1.显示当月以及下个月的日历 (可自行拓展更多月份) 2.首次点击选择"开始日期",再次点击选择"结束日期" (1).如果&qu ...
- Android项目实战(四十九):Andoird 7.0+相机适配
解决方案类似: Android项目实战(四十):Andoird 7.0+ 安装APK适配 解决方法: 一.在AndroidManifest.xml 文件中添加 四大组件之一的 <provider ...
- Android项目实战(三十二):圆角对话框Dialog
前言: 项目中多处用到对话框,用系统对话框太难看,就自己写一个自定义对话框. 对话框包括:1.圆角 2.app图标 , 提示文本,关闭对话框的"确定"按钮 难点:1.对话框边框圆角 ...
随机推荐
- .net EF中从数据添加表或视图时无法添加的问题
.net 使用EF模式进行开发,添加实体时不能够正常添加 错误描述: .net中在EF文件中添加数据库中已有的表或视图时不能正常添加,在添加时没有任何的错误提示,但是表或视图就一直拉不过来,,保存也没 ...
- java注解入门(含源码下载)
注解(Annotation)是从jdk1.5开始增加的特性.学习注解能够读懂框架的代码:让编程更加简洁,代码更加清晰. 注解概念:java提供了一种原程序中的元素关联任何信息和任何元数据的途径和方法. ...
- C#用正则表达式 获取网页源代码标签的属性或值
1.有url获取到网页源代码: using System.Web; using System.IO; using System.Net; private void GetHtmlinfo(string ...
- 'nmake' 不是内部或外部命令,VCVARS32.BAT路径问题
'nmake' 不是内部或外部命令,VCVARS32.BAT路径问题 2014-5-24 VC运行不正确基本上都是路径的问题,今天在进行Openssl开发的环境搭建时,需要使用nmake进行源码和库的 ...
- C++之类与对象(1)
下个阶段,我将讲解C++中面向对象的部分,也是C++对C语言改进的最重要的部分.以前C++也被叫做是"带类的C".今天主要讲类的构成,成员函数以及对象的定义和使用. 1.其实这一节 ...
- projecteuler之58题Spiral primes
package com.android; public class SpiralPrimes { public static void main(String args[]) { long numPr ...
- Python之路Day13
day13主要内容:JavaScript.DOM.jQuery 武Sir blog:http://www.cnblogs.com/wupeiqi/articles/5369773.html JavaS ...
- python成长之路16
阅读(72) 一:jQuery是一个兼容多浏览器的javascript类库,核心理念是write less,do more(写得更少,做得更多),对javascript进行了封装,是的更加便捷的开发, ...
- 2013 南京邀请赛 A play the dice 求概率
/** 大意:给定一个色子,有n个面,每一个面上有一个数字,在其中的m个面上有特殊的颜色,当掷出的色子出现这m个颜色之一时,可以再掷一次..求其最后的期望 思路:假设 期望为ans 4 ans = 1 ...
- STL string 模拟
下面的代码来自c++ primer plus第5版第12章,书中代码写的非常好: // string1.h -- fixed and augmented string class definition ...