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