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