经过一个多月的不懈努力,终于完成了这个手机卫士的项目。时间都是挤出来的,不容易啊。现在稍稍的总结一下
,分享给大家http://pan.baidu.com/s/1qY10Ffu
(一)splash界面
1,网络访问数据
URL url= new URL(“地址”);
HttpUtils 异步访问服务器,回调结果在主线中执行
case LOADMAIN: // 加载主界面
case ERROR://有异常
case SHOWUPDATEDIALOG:// 显示更新版本的对话框
2, 数据拷贝
把assets目录的数据拷贝到/data/data/包名/files目录
子线程拷贝
//拷贝数据库
copyDB("address.db");
3,动画效果
AlphaAnimation 渐变动画
AnimationSet 动画集
RotateAnimation 旋转动画(设置锚点)
ScaleAnimation 比例动画(设置锚点)
TranslateAnimation 位置动画
4,获取版本号版本名
PackageManager pm = getPackageManager();
PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
// 版本号
versionCode = packageInfo.versionCode;
// 版本名
versionName = packageInfo.versionName;
5,异常处理
针对不同的异常做不同的处理,如404,4001,4002,4003等
6,安装apk
Intent intent = new Intent("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
String type = "application/vnd.android.package-archive";
Uri data = Uri.fromFile(new File("/mnt/sdcard/xx.apk"));
intent.setDataAndType(data, type);
startActivityForResult(intent, 0);
7,解析json数据
JSONObject
简单的json数据
Gson(未在该项目中)
复杂json数据
8,代码规范
尽量方法功能单一,注意共有功能的抽取
如:
initView();
initData();
initEvent();
(二)主界面
1,GridView
和ListView双胞胎,多了指定列的选项
adapter = new MyAdapter();
gv_menus.setAdapter(adapter);// 设置gridview适配器数据
2, 事件和适配器和ListView的处理方式完全一样
3,自定义对话框
AlertDailog.Builder ab;
ab.setView(自定义View);
自定义View 注意对话框的关闭处理 ab.create().dismiss();
4, SpTool用法
5, MD5加密
1,文件
病毒的判断
2,字符串
加密处理,不可逆
加密3次以上 基本上解不出来,银行支付宝密码都采用多次加密
(三)手机防盗
1,功能抽取(设置向导)
动画效果
界面跳转
事件处理
2,检查服务是否运行
通过ActivityManager获取运行的服务,判断服务是否存在
3, 弹出窗体
弹出要想播放动画,要设置背景资源
显示的位置: pw.showAtLocation(rl_root, Gravity.LEFT | Gravity.TOP,
width / 4, height / 4);
和自定义对话框的区别: 弹出窗体可以设置任意的位置,对话框只能在屏幕中间显示
4, 自定义菜单
监听menu键的事件
keyCode == KeyEvent.KEYCODE_MENU
5,sim卡变更报警
1,监听开机启动的广播
android.intent.action.BOOT_COMPLETED
2,获取sim信息
TelephoneManager 获取sim卡
3, 原来的sim卡信息保存sp中,进行判断
6,gps
wifi 网络ip 3g/4g 基站 gps 卫星
LocationManager处理定位,设置定位监听
放到服务中去监听
7,设备管理器用法
一键锁屏
激活设备管理员,锁屏,远程清除数据等
获取设备管理
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
dpm.resetPassword("123", 0);
//一键锁屏
dpm.lockNow();
dpm.wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE);
8,报警音乐
音乐播放器
为了防止重复播放
mp.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//音乐播放完毕,触发此方法
isPlay = false;
}
});;
(四)黑名单数据
1,自定黑名单数据库
继承SQLiteOpenHelper类
2,分页
1,设置显示数据的个数
2,取所有数据 计算出多少页
3, 取出每页的数据
select * from blacktb order by _id desc limit 数据个数 offset 起始位置;
select * from blacktb limit 起始位置 , 结束位置;
3,sql语句优化
只是判断是否有数据,select 常量 from 表名
结构设计:
三大范式
4, 界面显示黑名数据
耗时的处理
子线程访问数据
new Thread(){
public void run(){
发送不同的状态
//数据更新界面
adapter.notifyDataSetChange();
}
}.start();
handler = new Handler(){
public void handleMessage(Message msg){
//处理不同状态
}
}
5, adapter的用法
getCount();
界面调用该方法,来确定多少个数据显示
getView();
最重要
view缓存的复用
注意缓存view的类型
缓存:
解决频繁调用findViewById
getItem();
获取数据,通过调用listview.getItemAtPosition
调用该方法来获取
getItemId();
不用
注意: 界面显示的位置 ,同过这些位置取数据显示,界面不显示的位置,不取数据
6,启动app
// 通过包名获取意图
Intent launchIntentForPackage = pm.getLaunchIntentForPackage(packName);
注意没有界面的app处理
7,分享app
短信
分享微博
8,删除app
用户app
Intent intent = new Intent("android.intent.action.DELETE");
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(
Uri.parse("package:" + clickBean.getPackName()));
startActivity(intent);// 删除用户apk的Activity
系统app
//直接可以使用命令删除apk
RootTools.sendShell("mount -o remount rw /system", 8000);//设置命令的超时时间为8秒
System.out.println("安装路径:" + clickBean.getApkPath());
RootTools.sendShell("rm -r " + clickBean.getApkPath(), 8000);
RootTools.sendShell("mount -o remount r /system", 8000);
(五)进程管理
1,获取进程信息
ActivityManager 来获取运行中的进程
List<RunningAppProcessInfo> runningAppProcesses = am
.getRunningAppProcesses();
2,获取内存
总内存:读取文件来获取总内存大小 /proc/meminfo
可用内存:
MemoryInfo outInfo = new MemoryInfo();
// MemoryInfo 存放内存的信息
am.getMemoryInfo(outInfo);
// 把kb 转换成byte
size = outInfo.availMem;
3,迭代器操作数据
容器不能增删修改
list对象增删改中标记
if (ourList.modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
4,清理进程
am.killBackgroundProcesses(bean.getPackName());
5,listview过滤显示数据
只需要修改getCount方法
@Override
public int getCount() {
setTileMessage();
if (!SpTools.getBoolean(getApplicationContext(), MyConstants.SHOWSYSTEM, false)) {
//不显示系统进程
return userTasks.size() + 1;
}
return sysTasks.size() + 1 + userTasks.size() + 1;
}
(六)流量统计
真机: 流量信息的位置
/proc/uid_stat/id名/tcp_snd 发送流量
/proc/uid_stat/id名/tcp_rcv 接收流量
流量类型
//流量信息的管理类
cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
(七)杀毒
1,病毒数据库的创建
拷贝金山的病毒数据
病毒判断主要靠病毒文件的MD5值 或 sha1
2,病毒库更新
读取版本号判断
12 50 从数据库中动态取没有的病毒数据
3,查杀病毒
扫描系统中所有的文件 判断MD5值,删除文件(申请root权限)
(八)缓存清理
1,获取缓存
反射和aidl来获取缓存
参考setting的源码,找到获取缓存的代码
ApplicationState.java 787行
2, 清理缓存
1,单个app的缓存
系统app才可以有权限是清除
打开设置中心
2,清除所有缓存
pm.freeDataAndNotify
3,缓存回调信息
在子线程中执行
(九)高级工具
1,手机归属查询
手机归属地数据库
抖动(ApiDemo)
震动(真机)
监听文本的变化
2, 短信的备份和还原
json xml
界面的显示
接口完成界面的回调显示
3, 程序锁
1,数据
fragment来显示数据
程序锁数据库
数据缓存
数据一致
内容观察者
1,注册内容观察者
getContentResolver().registerContentObserver(LockedTable.uri, true, observer);
observer: 实现ContentObserver类的下面方法
@Override
public void onChange(boolean selfChange) {
new Thread(){
public void run() {
LockedDao dao = new LockedDao(getApplicationContext());
//读取dao层读取数据
List<String> allLockedDatas = dao.getAllLockedDatas();
//如果是实例变量 allLockedDatas.clear() .addAll();
lockedFragment.setAllLockedPacks(allLockedDatas);
unlockedFragment.setAllLockedPacks(allLockedDatas);
};
}.start();
super.onChange(selfChange);
}
uri: content://uricontent/xxtb/xxlie
2, 发送内容观察者通知(自定义)
// 发送内容观察者的通知
context.getContentResolver().notifyChange(LockedTable.uri, null);
注意:
uri要一致
动画效果:位移动画
2,看门狗服务
看门狗的监控任务栈
List<RunningTaskInfo> runningTasks = am.getRunningTasks(1);// 获取最新的任务栈
RunningTaskInfo runningTaskInfo = runningTasks.get(0);// 最新打开的任务栈
// 任务栈中获取顶部activity
String packName = runningTaskInfo.topActivity
.getPackageName();
判断是否拦截
如果是拦截
判断是否是熟人
广播来接受熟人的信息
不是熟人
输入密码的界面
如果输入的是正确的密码,发送熟人广播
(十)设置中心
黑名单拦截服务
电话拦截
如果是黑名单电话,挂断电话和删除电话日志
挂断电话:反射和aidl
删除电话日志:注册内容观察者
短信拦截
终止短信的广播传递
来电归属地:
自定义Toast来显示归属地
在WindowManager中 addView(土司的view)
触摸事件
土司的类型
归属的样式:
设置背景资源
是否更新:
在sp保存标记,在splash界面判断该标记