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,我们的大概思路是:

  1. 读取 raw_contacts, 获取 contact_id
  2. 根据 contact_id, 从 data 中读取具体信息(姓名/电话 ) data1, mimetype_id
  3. 根据 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

0 0
原创粉丝点击