目录

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

项目结构图

源代码

清单 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();}@Overridepublic 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值,如果该键不存在,默认返回trueboolean 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 {// 参数一:当前应用程序的包名 参数二:可选的附加消息,这里我们用不到 ,可以定义为0PackageInfo 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

转载于:https://www.cnblogs.com/ctoroad/p/4090758.html

Android项目实战手机安全卫士(02)相关推荐

  1. 学习笔记之《Android项目实战——手机安全卫士》

    [Android项目实战-手机安全卫士] 目标:快速积累开发经验,具备中级Android工程师能力. 如遇到难以理解的逻辑或功能,可以先将程序打断点观察程序的执行逻辑. 第一章项目简介:欢迎界面.主界 ...

  2. android在使用单位方面,《Android项目实战——手机安全卫士》_面试题答案.docx

    <Android项目实战--手机安全卫士>_面试题答案 <Android项目实战--手机安全卫士>面试题答案第1章项目简介请问Android程序的真正入口是什么.Android ...

  3. Android 程序员不得不收藏的 90+ 个人博客(持续更新,android项目实战手机安全卫士

    来自滴滴出行,Android 开发助手 开发者,android-open-project 维护者 ,android-open-project-analysis 维护者. 中二病也要开发 ANDROID ...

  4. Android 简单的视频录制,android项目实战手机安全卫士

    */ public static Camera getDefaultCamera(int <Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义> [docs. ...

  5. Android项目实战--手机卫士

    Android项目实战--手机卫士--结束 很久都没有来更新博客了,之前一直忙着工作的事,接触到了一些以前从来没有接触过的东西,真的挺有挑战性的,但也有很多的无奈,但也学习到了很多东西,我会慢慢的写到 ...

  6. Android项目:手机安全卫士(9)—— 手机号码归属地查询

    Android项目:手机安全卫士(9)-- 电话号码归属地查询 1 综述 手机防盗功能已经开发完了,接下来开发一个高级工具功能,就是手机归属地查询,严格来讲,是查询手机号码的归属地.不过,由于用的号码 ...

  7. Android项目:手机安全卫士(15)—— 获取手机安装应用与存储空间

    Android项目:手机安全卫士(15)-- 获取手机安装应用与存储空间 1 介绍 今天来讲讲手机安全卫士的第三个功能:软件管理,其实也不应该叫管理,称为软件应用信息查看更正确一点,就是显示手机已安装 ...

  8. Android项目:手机安全卫士(3)—— 主界面布局

    Android项目:手机安全卫士(3)-- 主界面布局 1 总纲 前面实现了"手机安全卫士"的闪屏界面与版本检测升级问题,接下来的任务就是实现主界面了,这个相对简单,因为没有涉及到 ...

  9. Android项目:手机安全卫士(6)—— 手机防盗设置向导

    Android项目:手机安全卫士(6)-- 手机防盗设置向导 1 介绍 设置密码成功或输入正确的密码后,就进入了手机防盗功能界面,若是第一次进入手机防盗功能,则会直接进入设置向导.今天涉及到的界面主要 ...

最新文章

  1. 关于node.js的web框架的应用及并发性能测试
  2. 轻松搞定c++语言pdf_当年锤子的大爆炸,如今12个语言版本都可轻松搞定!
  3. Redis 哨兵架构基础
  4. 「架构技术专题」如何构建网站高可用架构(详细分析篇)?(6)
  5. 黄聪:VirtualBox 安装ghost版windows XP
  6. java形状_形状等于()
  7. FullCalendar应用——整合农历节气和节日
  8. 立志做个有激情的coder
  9. Epub360、iH5、Mugeda,三款专业级H5设计工具详评
  10. Virtualbox源码分析6_VMM虚拟化实现源码分析3 HMVMXR0.cpp
  11. 微信小程序--基于colorui构建皮皮虾短视频去水印组件(仅供学习使用)
  12. SAP中Exchange rate type EURX到底干嘛用的
  13. Word查找和替换通配符(完全版)
  14. 算术左移,逻辑左移,算术右移,逻辑右移之间的区别
  15. oracle 创建唯一索引
  16. 易语言之ocr自动识别验证码dll文件
  17. HAL库之SYSTICK时钟频率探究-F407
  18. 读书笔记《进化的力量:刘润年度演讲1》
  19. C语言教程-main函数
  20. java中jQuery自我学习中介

热门文章

  1. HarmonyOS连接新体验,半入耳舒适降噪耳机华为FreeBuds 4E全新亮相
  2. 华为鸿蒙系统开发者大会视频,鸿蒙OS、EMUI 10正式发布!HDC华为开发者大会2019直播(视频)...
  3. 测试开发 | 视频编辑SDK测试
  4. “江一燕体”被群嘲,star(明星)卖人设有多招人烦?
  5. 解决mac电脑打开应用“意外退出”的问题
  6. 苹果正式发布全系列新款iPod
  7. SVM(二):KKT条件最直白的解释
  8. 微众银行qualitis 部署编译教程
  9. php think queue work,think-queue
  10. linux cp命令不提示覆盖,Linux中cp命令不提示直接覆盖的方法