目 录
第1章 引言 1
1.1 研究背景及意义 1
1.2 安全软件的现状 1
1.3 本文主要工作 2
1.4 本文的组织结构 2
第2章 Android的相关技术介绍及分析 3
2.1 搭建Android开发环境 3
2.1.1 搭建Ubuntu系统下Java开发环境 3
2.1.2 搭建Ubuntu系统下Android开发环境 3
2.2 Android项目目录结构 4
2.3 Activity 5
2.3.1 Activity生命周期方法 5
2.3.2 与其他应用程序交互 5
2.4 BroadcastReceiver 6
2.4.1 广播接收者的分类 6
2.4.2 注册广播接收者的两种方式 6
2.5 Service 7
2.5.1 什么是服务 7
2.5.2 本地服务 7
2.5.3 远程服务 7
第3章 手机安全卫士分析与设计 8
3.1 手机防盗功能需求分析与设计 8
3.2 通讯卫士功能需求分析与设计 9
3.3 软件管理功能需求分析与设计 10
3.4 进程管理功能需求分析与设计 10
3.5 程序锁功能需求分析与设计 10
3.6 手机杀毒功能需求分析与设计 11
3.7 系统优化功能需求分析与设计 12
3.8 自动升级功能需求分析与设计 12
第4章 手机安全卫士详细设计与实现 13
4.1 欢迎界面实现 13
4.1.1 检查升级功能实现 14
4.1.2 升级对话框显示功能实现 14
4.2 应用程序主界面实现 14
4.3 程序锁实现 16
4.4 手机防盗实现 18
4.5 手机杀毒实现 19
4.6 系统优化实现 21
4.7 通讯卫士实现 21
4.8 软件管理实现 23
4.9 高级工具实现 23
4.10 系统设置实现 25
第5章 结论与展望 27
5.1 结论 27
5.2 进一步工作的方向 27
参考文献 28
致 谢 29
第3章手机安全卫士分析与设计
手机防盗功能需求分析与设计
落地有声:由于我的眼镜是透明的,经常一觉睡醒找不到眼镜,每次这个时候都想能通过手机控制眼镜发出声音以便更快的找到眼镜。落地有声就是由这个想法演变来的,如果用户的爱机刚被盗不久,那么手机还在用户附近的,如果此时设定的安全号码手机可以用,只需要用安全手机发送一条警报指令给丢失的手机,那么丢失的手机就会播放报警音乐,以便用户在第一时间找回丢失的爱机。
换卡先知:Android手机换SIM卡都需要重启手机,每次手机重启的时候判断当前SIM卡的串号是否和被保护的SIM卡的串号是否相同,如果不相同,则手机将在后台自动发送短信给安全手机,这样就在小偷不知道的情况下第一时间得知小偷的手机号码,大大提升找回手机的可能性。
远程开启防盗:当用户爱机没有开起防盗功能的时候,使用任意的手机发送应用和密码和远程开启防盗功能命令时可以开起防盗功能,并设置当前手机号码安全手机号码,从而为找回手机打下基础。
通信拦截:获取丢失的爱机的外拨电话、来电号码、外发短信和收到的短信,并转发给安全手机。这样就可以爱机丢失的第一时间和盗窃者取得联系,也获取了盗窃者朋友的手机号码,进一步增加找回手机的可能性,也大大影响了丢失爱机的正常使用,使盗窃者觉得丢失的爱机拿来也无用,还给手机主人好些。
保护隐私:当用户的爱机丢失时,通过短信发送特定的指令,可将丢失手机通讯录里面的所有联系人、通话记录以及短信内容全部删除,及时保护用户的相关隐私信息。
充电防盗:在某些特殊的场合,用户的爱机急需充电,而用户又不在手机周围,这时开启手机充电防盗就能很好地监控手机的状况,一旦有其他人蓄意拔出正在充电的手机,手机就会立即发出警报音,并同时发送短信通知安全手机。
package com.bingoogol.frogcare;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.app.Activity;
import android.app.Application;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Process;
import com.bingoogol.frogcare.util.Constants;
import com.bingoogol.frogcare.util.DateUtil;
import com.bingoogol.frogcare.util.Logger;
import com.bingoogol.frogcare.util.SpUtil;
import com.bingoogol.frogcare.util.StorageUtil;
import com.bingoogol.frogcare.util.ToastUtil;
/**
* 保存应用程序全局状态的基类
*
* @author bingoogol@sina.com 2014-4-25
*/
public class App extends Application {
private static final String TAG = "App";
/**
* 应用程序中所有正在使用的activity集合,主要是用来实现完全退出应用程序功能
*/
private List<Activity> mActivities;
/**
* 上一次按下返回键时的时间戳
*/
private long lastTime;
@Override
public void onCreate() {
super.onCreate();
mActivities = new ArrayList<Activity>();
SpUtil.init(this);
Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
}
/**
* 添加activity到全局状态中
*
* @param activity
*/
public void addActivity(Activity activity) {
mActivities.add(activity);
}
/**
* 从全局状态中移除activity
*
* @param activity
*/
public void removeActivity(Activity activity) {
mActivities.remove(activity);
}
/**
* 双击返回键退出应用程序
*/
public void exitWithDoubleClick() {
if (System.currentTimeMillis() - lastTime <= 1500) {
exit();
} else {
lastTime = System.currentTimeMillis();
ToastUtil.makeText(this, R.string.exit_tips);
}
}
/**
* 退出应用程序
*/
public void exit() {
for (Activity activity : mActivities) {
activity.finish();
}
System.exit(0);
}
private class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
FileWriter fw = null;
try {
File file = new File(StorageUtil.getFeedbackDir(), DateUtil.dateToDayString(new Date()) + ".log");
boolean flag = file.exists();
// 这行执行完,file就存在了,所以得在这之前判断文件是否已经存在
fw = new FileWriter(file, true);
if (!flag) {
fw.write("当前应用版本:" + getCurrentVersionName() + "\n");
fw.write("当前设备信息:\n");
fw.write(getMobileInfo());
fw.write("----------------------------------------------------------------------------\n");
}
fw.write(getErrorInfo(ex));
fw.write("----------------------------------------------------------------------------\n");
fw.flush();
// TODO 正式发布后删掉
ex.printStackTrace();
} catch (Exception e) {
Logger.e(TAG, e.getMessage());
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
Logger.e(TAG, e.getMessage());
}
}
}
Process.killProcess(Process.myPid());
// TODO 定期上传错误日志到服务器
}
private String getErrorInfo(Throwable throwable) {
Writer writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
throwable.printStackTrace(pw);
pw.close();
return writer.toString();
}
private String getMobileInfo() {
StringBuffer sb = new StringBuffer();
// 通过反射获取系统的硬件信息
try {
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
// 暴力反射 ,获取私有的信息
field.setAccessible(true);
sb.append(field.getName() + "=" + field.get(null).toString());
sb.append("\n");
}
} catch (Exception e) {
Logger.e(TAG, e.getMessage());
}
return sb.toString();
}
}
/**
* 获取当前版本名称
*
* @return
*/
public String getCurrentVersionName() {
try {
return getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
} catch (Exception e) {
// 利用系统api getPackageName()得到的包名,这个异常根本不可能发生
return null;
}
}
/**
* 获取当前版本号
*
* @return
*/
public int getCurrentVersionCode() {
try {
return getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
} catch (Exception e) {
// 利用系统api getPackageName()得到的包名,这个异常根本不可能发生
return 0;
}
}
/**
* 获取安装apk文件的意图对象
*
* @param apkFile
* 要安装的apk文件
* @return
*/
public Intent getInstallApkIntent(File apkFile) {
Intent installApkIntent = new Intent();
installApkIntent.setAction(Intent.ACTION_VIEW);
installApkIntent.addCategory(Intent.CATEGORY_DEFAULT);
installApkIntent.setDataAndType(Uri.fromFile(apkFile), Constants.mime.APK);
return installApkIntent;
}
}