資料庫中刪除SIM卡聯絡人
4,SIM卡聯絡人
Contacts2.db資料庫中聯絡人其實包括2部分,手機上面的聯絡人以及SIM卡中的聯絡人。
當然, SIM卡中的聯絡人是儲存在單獨的資料庫中,其對應的Provider為IccProvider,在packages\services\Telephony 路徑下,也就是phone程序中。
AndroidManifest.xml對應的定義如下,
<provider android:name="IccProvider" android:authorities="icc" android:multiprocess="true" android:exported="true" android:readPermission="android.permission.READ_CONTACTS" android:writePermission="android.permission.WRITE_CONTACTS" />
IccProvider定義如下,
public class IccProvider extends com.android.internal.telephony.IccProvider {
public IccProvider() {
super();
}
}
直接繼承系統jar包中的IccProvider類。因此,增刪改查直接看jar包中的IccProvider類就可以了。
----找了好久都找不到對應的db資料庫。
在聯絡人相關介面上,可以看到,
1,拔出SIM卡,僅顯示phone中的聯絡人;
2,插上SIM卡,又會顯示SIM卡上的聯絡人。
因此,可以這樣推斷,當撥號SIM卡時,會從Contacts2.db資料庫中刪除SIM卡的聯絡人;
當插上SIM卡時,會將插上SIM卡中的聯絡人同步到Contacts2.db資料庫中。並且在這2種情況下,匯出Contacts2.db資料庫,的確是這樣的。到底是怎麼發生的呢?
分析SimContacts apk,路徑:vendor\qcom\proprietary\telephony-apps\SimContacts
4.1 刪除聯絡人
AndroidManifest.xml的SimStateReceiver服務,配置如下,
<receiver android:name="SimStateReceiver"> <intent-filter android:priority="1000"> <action android:name="android.intent.action.SIM_STATE_CHANGED"/> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="org.codeaurora.intent.action.ACTION_SIM_REFRESH_UPDATE"/> </intent-filter> </receiver>
註冊了三個廣播。分別是開機廣播,SIM卡狀態變化的廣播,SIM卡狀態更新的廣播。
SimStateReceiver的邏輯也很簡單,就是啟動SimStateReceiver服務完成真正的功能。
sendPhoneBoot/sendSimState/sendSimRefreshUpdate/這三個方法最後都會啟動SimContactsService服務,
mContext.startService(new Intent(mContext, SimContactsService.class).putExtras(args));
AndroidManifest.xml的SimStateReceiver服務,配置如下,
<receiver android:name="SimStateReceiver">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.SIM_STATE_CHANGED"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="org.codeaurora.intent.action.ACTION_SIM_REFRESH_UPDATE"/>
</intent-filter>
</receiver>
註冊了三個action,分別是開機,SIM卡狀態變化的廣播,SIM卡插拔的廣播。也就是說, SimContactsService服務在Android系統啟動之後就會啟動。
SimContactsService是利用Handler切換到UI執行緒來執行的。
當SIM卡狀態變化時, SimContactsService 的onCreate方法內的匿名Handler的handleMessage方法對應的處理如下,
case MSG_SIM_STATE_CHANGED:
•••
if (mSimState[slotId] == SimContactsConstants.SIM_STATE_NOT_READY
|| mSimState[slotId] == SimContactsConstants.SIM_STATE_ERROR) {
// To handle card absent/error, hot swap related cases.
deleteDatabaseSimContacts(slotId);
break;
•••
呼叫deleteDatabaseSimContacts方法刪除Contacts2.db資料庫中的SIM聯絡人。
deleteDatabaseSimContacts方法如下,
getContentResolver().delete(ContactsContract.RawContacts.CONTENT_URI,
SIM_DATABASE_SELECTION, getSimAccountDBSelectArgs(slotId));
呼叫ContentResolver的delete方法從Contacts2.db資料庫的raw_contacts表中刪除對應SIM卡聯絡人。
SIM_DATABASE_SELECTION變數如下,
static final String SIM_DATABASE_SELECTION = RawContacts.ACCOUNT_TYPE + "=?" + " AND " +RawContacts.ACCOUNT_NAME + "=?" + " AND " + RawContacts.DELETED + "=?";
getSimAccountDBSelectArgs方法如下,
return new String[] {
SimContactsConstants.ACCOUNT_TYPE_SIM,
SimContactsConstants.getSimAccountName(slotId), "0"
};
SimContactsConstants的ACCOUNT_TYPE_SIM定義如下,
public static final String ACCOUNT_TYPE_SIM = "com.android.sim";
SimContactsConstants的getSimAccountName方法如下,
if (TelephonyManager.getDefault().isMultiSimEnabled()) {
return ACCOUNT_NAME_SIM + (slotId + 1);
} else {
return ACCOUNT_NAME_SIM;
}
ACCOUNT_NAME_SIM定義如下,
public static final String ACCOUNT_NAME_SIM = "SIM";
因此,刪除語句意思為:
從raw_contacts表中刪除account_type為"com.android.sim", account_name為SIM1,並且deleted為0的聯絡人。
Contacts2.db資料庫的account表單部分如下,
raw_contacts表單部分如下,
分析這2張表單, deleted為0表示當前的聯絡人,為1表示已經刪除的聯絡人。
account_type為1的表示是phone聯絡人,其他的表示從SIM卡同步的聯絡人,當前還有雙卡的情況。
在此,就一目瞭然了。稍微有點不同的是,這裡並沒有在子執行緒中採用非同步的方法。