Android项目:手机安全卫士(6)—— 手机防盗设置向导(二)
来源:互联网 发布:美国专利数据库 编辑:程序博客网 时间:2024/05/16 05:47
Android项目:手机安全卫士(6)—— 手机防盗设置向导(二)
1 介绍
前面的文章介绍了设置向导的界面与切换逻辑,今天来看看每个界面后面涉及到的代码逻辑,主要知识点有:
- 读取手机 sim 卡序列号
- 监听手机重启完成的广播
- 读取手机通讯录
关于项目相关文章,请访问:
- Android 项目:手机安全卫士(1)—— 闪屏界面
- Android 项目:手机安全卫士(2)—— 版本升级
- Android 项目:手机安全卫士(3)—— 主界面布局
- Android 项目:手机安全卫士(4)—— 自定义(组合)控件、属性
- Android 项目:手机安全卫士(5)—— 自定义弹窗
- Android 项目:手机安全卫士(6)—— 手机防盗设置向导
项目源码地址(实时更新):https://github.com/xwdoor/MobileSafe
2 读取手机 SIM 卡序列号
读取 sim 卡序列号,然后通过 SharedPreferences 保存,下面是代码:
//获取系统服务 TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); //获取 sim 卡序列号 String simSerialNumber = tm.getSimSerialNumber();
仅仅只是这样,系统会报错的: java.lang.SecurityException: Requires READ_PHONE_STATE: Neither user 10053 nor current process has android.permission.READ_PHONE_STATE.
这是因为没有添加权限的结果,需要添加读取手机状态的权限: <uses-permission android:name="android.permission.READ_PHONE_STATE" />
3 监听手机重启完成的 Receiver 广播
绑定 sim 卡后,接下来需要做的就是在手机每次启动完成后,检测手机 sim 卡是否发生变化,创建广播接收器 BootCompleteReceiver,继承自 BroadcastReceiver:
public class BootCompleteReceiver extends BroadcastReceiver { public BootCompleteReceiver() { } @Override public void onReceive(Context context, Intent intent) { String serialNumber = PrefUtils.getString(BaseActivity.PREF_BIND_SIM,"",context); if(!TextUtils.isEmpty(serialNumber)){ TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); String simSerialNumber = tm.getSimSerialNumber(); if(serialNumber.equals(simSerialNumber)){ Log.i(BaseActivity.TAG_LOG,"手机安全"); }else { Log.i(BaseActivity.TAG_LOG,"SIM卡发生变化,危险"); } } } }
当然,这个时候还没有添加代码的处理逻辑,只是输出日志。注意,接收该广播还需要添加权限: <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
创建完成后,需要注册该广播接收器,且它的 action 是:BOOT_COMPLETED,代码如下:
<receiver android:name=".receiver.BootCompleteReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver>
4 读取手机通讯录
通过访问系统的 ContentProvider 来读取通讯录,系统有三张表,分别是 raw_contacts, data, mimetypes,我们的大概思路是:
- 读取 raw_contacts, 获取 contact_id
- 根据 contact_id, 从 data 中读取具体信息(姓名/电话 ) data1, mimetype_id
- 根据 mimetype_id, 从 mimetypes 中查到具体类型
/** * 读取联系人 */ private ArrayList<HashMap<String, String>> readContacts() { // raw_contacts, data, mimetypes // 1. 读取raw_contacts, 获取contact_id // 2. 根据contact_id, 从data中读取具体信息(姓名/电话 ) data1, mimetype_id // 3. 根据mimetype_id, 从mimetypes中查到具体类型 // 1. 读取raw_contacts, 获取contact_id Cursor rawCursor = getContentResolver().query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"contact_id"}, null, null, null); ArrayList<HashMap<String, String>> listContacts = new ArrayList<>(); if (rawCursor != null) { while (rawCursor.moveToNext()) { String contactId = rawCursor.getString(rawCursor.getColumnIndex("contact_id")); // 2. 根据contact_id, 从data中读取具体信息(姓名/电话 ) data1, mimetype_id // 系统在查询data表时, 实际上查询的时view_data这个视图, 视图将data和mimetypes两个表的信息整合在了一起 Cursor cursor = getContentResolver().query(Uri.parse("content://com.android.contacts/data"), new String[]{"data1", "mimetype"}, "raw_contact_id=?", new String[]{contactId}, null); HashMap<String, String> map = new HashMap<>(); if (cursor != null) { while (cursor.moveToNext()) { String data = cursor.getString(cursor.getColumnIndex("data1")); String mimetype = cursor.getString(cursor.getColumnIndex("mimetype")); if ("vnd.android.cursor.item/name".equals(mimetype)) { //姓名 map.put("name", data); } else if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) { //电话 map.put("phone", data); } } cursor.close(); if (!TextUtils.isEmpty(map.get("name")) && !TextUtils.isEmpty(map.get("phone"))) {// 过滤掉脏数据 listContacts.add(map); } } } rawCursor.close(); } return listContacts; }
仅仅只是这样,系统会报错的: java.lang.SecurityException: Permission Denial: reading com.android.providers.contacts.ContactsProvider2 requires android.permission.READ_CONTACTS, or grantUriPermission().
需要添加权限: <uses-permission android:name="android.permission.READ_CONTACTS"/>
5 总结
我觉得今天的知识点很有用,使用了系统提供的一些服务,这些服务一般都需要访问权限,所以不要忘了加权限,我也是忘了好几次,谨记。
关于项目相关文章,请访问:
- Android 项目:手机安全卫士(1)—— 闪屏界面
- Android 项目:手机安全卫士(2)—— 版本升级
- Android 项目:手机安全卫士(3)—— 主界面布局
- Android 项目:手机安全卫士(4)—— 自定义(组合)控件、属性
- Android 项目:手机安全卫士(5)—— 自定义弹窗
- Android 项目:手机安全卫士(6)—— 手机防盗设置向导
项目源码地址(实时更新):https://github.com/xwdoor/MobileSafe
- Android项目:手机安全卫士(6)—— 手机防盗设置向导(二)
- Android项目:手机安全卫士(6)—— 手机防盗设置向导(二)
- Android项目:手机安全卫士(6)—— 手机防盗设置向导
- 【边做项目边学Android】手机安全卫士09-手机防盗界面设置向导1
- Android项目:手机安全卫士(7)—— 手机防盗功能
- Android手机安全卫士(二)---设置、自定义控件属性、md5加密、手机防盗
- Android项目:手机安全卫士(2)—— 版本升级
- Android项目:手机安全卫士(8)—— 管理员权限
- Android项目:手机安全卫士(14)—— 短信备份
- Android项目:手机安全卫士(16)—— 复杂 ListView
- 【边做项目边学Android】手机安全卫士11-设置向导之设置安全号码
- 【边做项目边学Android】手机安全卫士10-设置向导之绑定SIM卡
- Android项目:手机安全卫士(15)—— 获取手机安装应用与存储空间
- Android项目实战--手机卫士09--防盗逻辑以及设置向导的完成
- Android项目:手机安全卫士(12)—— 通讯卫士之电话短信黑名单设置与拦截
- Android项目:手机安全卫士(12)—— 通讯卫士之电话短信黑名单设置与拦截
- 13、手机防盗--向导设置完成界面
- 练手小项目(5)安全卫士——手机加速
- Linux cups 打印总结备忘
- VIM文本替换命令
- 10章作业page219-3题
- Xcode新建工程无网络状况解决办法
- Intel 82599 ixgbe & ixgbevf CNA 卡驱动分析03——部分功能代码分析
- Android项目:手机安全卫士(6)—— 手机防盗设置向导(二)
- Gym 100231BIntervals
- Git的学习笔记(二)——提交流程与暂存区
- [BUG]-Assertion failure in void _UIPerformResizeOfTextViewForTextContainer
- c语言中cJson的使用
- URAL 1017 Staircases
- ECMAScript 6 类 应用
- OOM与memory leak区别
- EXTJS学习笔记:grid之gridview