安卓项目实战----收集用户信息(一)
2016-01-21 21:37
239 查看
前言
大家好!欢迎继续来访我的网站。从今天起,我将在这个专题记录我的一个安卓项目实战,我将在此中分享一些个人经验见解,希望能带给大家一点帮助,这个项目将帮助学习安卓SQLite的使用、反射工程、广播服务等等,甚至一些设计模式相关知识(其实目前我也不太懂,只是在读《设计之禅》中形成一点意识,另外也强烈推荐此书)OK,就这样不多说,开始吧!项目简介
首先介绍一下整个项目,这个项目是关于信息安全方面的,主要是后台悄悄采集用户的程序使用情况,然后将采集到的数据上传到服务器,以供服务器端分析利用数据。难点在于如何隐蔽在后台采集数据,具体需求如下:需求
实时检测程序(包括一部分系统程序和所有的用户程序 )是否在运行,获取程序的运行信息获取手机短信并以文件形式储存在SD卡等待上传
>3. 控制手机一些设备的开启关闭,比如蓝牙
项目框架
动工第一步便是搭建整个项目的框架,首先工程大体分为两大类,一个是引擎类,主要包含用于获取程序使用情况和获取短信等的操作类,另一个是服务类,包含广播接收者服务和管理各服务运行的服务。这两个大类都需要抽象出接口,便于后期维护扩展。笔者使用的是Android Studio开发,工程视图如下图所示:![image](AP151116/1-PS.jpg 工程视图)
获取短信操作类
工程的框架搭好之后,我们先从简单的开始,就是获取短信的操作。这个类的工作分为两步,第一步获取短信,第二步则是保存数据。那么如何获取短信呢?学完安卓基础的都知道,安卓的通讯录、短信都是储存在SQLite数据的,所以获取短信就是简单的查询数据库操作。ok,开始吧。首先提一下短信收件箱的URI,通过这个URI才可以连接上我们所需要的数据库表单:
/** * 短信收件箱数据库 URI */ private final String SMS_INBOX_URI = "content://sms/inbox";
以下是数据库查询操作:
Uri smsUri = Uri.parse(SMS_INBOX_URI); ContentResolver resolver = mContext.getContentResolver(); String[] projection = {"_id", "address", "person", "body", "date", "type"}; Cursor cursor = resolver.query(smsUri, projection, null, null, "date desc");
PS:在这里提一下,我在博客只是粘贴一些关键部分的代码,大家可以去我的[github](https://github.com/a-voyager/MoniterDemo github)网站上去看所有源码
数据库查询没什么讲的,就是查询{“_id”, “address”, “person”, “body”, “date”, “type”}这几列的内容,查询完成之后返回一个游标集cursor。
接下来便要遍历游标集,在此之前需要准备工作:建立一个实例类SmsEntity,用于保存每一个短信短信实例。
public class SmsEntity { private String name; private int id; private long person; private String body; private long date; private int type; ... }
准备工作做好之后就可以开始遍历并保存在List列表中了。
int i = 1; SmsEntity sms = null; List<SmsEntity> list = new ArrayList<>(); while (cursor.moveToNext()) { sms = new SmsEntity(); sms.setId(i++); sms.setBody(cursor.getString(3)); sms.setDate(cursor.getLong(4)); sms.setType(cursor.getInt(5)); sms.setName(cursor.getString(2)); sms.setPerson(cursor.getLong(1)); Log.i(TAG, sms.toString()); list.add(sms); }
遍历完成之后当然就是保存文件咯,xml解析保存到SD卡就好了,见代码:
/** * 将获取到的短信数据保存到文件 * * @param list 短信列表 */ private boolean saveToFile(List<SmsEntity> list) { FileOutputStream fos = null; XmlSerializer xmlSerializer = Xml.newSerializer(); File fileDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + Constants.SMS_SAVE_FILE_DIR); if (!fileDir.exists()) fileDir.mkdirs(); File file = new File(fileDir, Constants.SMS_SAVE_FILE); try { fos = new FileOutputStream(file); xmlSerializer.setOutput(fos, "utf-8"); //开始解析 xmlSerializer.startDocument("utf-8", true); xmlSerializer.startTag(null, "SMSs"); xmlSerializer.attribute(null, "num", String.valueOf(list.size())); for (SmsEntity sms : list) { xmlSerializer.startTag(null, "sms"); xmlSerializer.attribute(null, "id", String.valueOf(sms.getId())); xmlSerializer.startTag(null, "type"); xmlSerializer.text(String.valueOf(sms.getType())); xmlSerializer.endTag(null, "type"); xmlSerializer.startTag(null, "name"); xmlSerializer.text(sms.getName() == null ? "" : sms.getName()); xmlSerializer.endTag(null, "name"); xmlSerializer.startTag(null, "person"); xmlSerializer.text(String.valueOf(sms.getPerson())); xmlSerializer.endTag(null, "person"); xmlSerializer.startTag(null, "date"); xmlSerializer.text(String.valueOf(sms.getDate())); xmlSerializer.endTag(null, "date"); xmlSerializer.startTag(null, "body"); xmlSerializer.text(sms.getBody()); xmlSerializer.endTag(null, "body"); xmlSerializer.endTag(null, "sms"); } xmlSerializer.endTag(null, "SMSs"); xmlSerializer.endDocument(); } catch (Exception e) { Log.e(TAG, "saveToFile() failed", e); return false; } finally { try { if (fos != null) fos.close(); } catch (IOException e) { Log.e(TAG, "fos close failed"); } } return true; }
Bingo!就这样,实现了查询短信并保存到文件的功能。
期间注意几个问题:
读取短信权限问题,记得加入和权限安卓单元测试中,不能够直接在Test类中直接执行测试代码,因为此时Test类还没有构造完成,一些功能尚不完整,比如this.getContext()
xml解析过程start..()/end..()函数建议和打括号一样成对地写
特别注意由于IDE的自动补全功能太过智能,有可能会把安卓权限给大写,导致权限存在但不正确,也不会报错,只是无法执行相关操作,笔者表示在这里被害惨了-_-||
待续…
相关文章推荐
- 三种实现servlet的方式有什么区别?--转载
- 20160121--Spring
- linux系统构架 - LB集群之LVS的NAT
- 【BZOJ1030】文本生成器
- 浅析C# 中object sender与EventArgs e
- 当Scheduler拿不到url的 时候,不能立即退出
- Activity深入理解(一)
- 当Scheduler拿不到url的 时候,不能立即退出
- ubuntu启动各项功能配置+开机自动启动
- poj 3273 Monthly Expense (二分)
- 【Hdu 4117】GRE Words
- x265-1.7版本-common/bitstream.h注释
- centos7 64位 伪分布安装cdh5.5.1,及其测试笔记
- To the Virgins, to Make Much of Time
- PagedDataSource数据绑定控件和AspNetPager分页控件结合使用列表分页
- Nginx负载均衡集群
- 机器学习课程知识总结
- php字符串处理
- 【HDU2222】Keywords Search
- TextView 字体渐变