Android SIM卡聯絡人操作總結
--- by Ruiming.Lv
在Android中,對SIM中的聯絡人進行操作,需要通過系統提供的Content Provider進行,該Provider就是Telphony中的IccProvider。但是,由於SIM卡儲存的一些特性,在操作上,與ContactsProvider有很多不一樣。
1 IccProvider工程相關
IccProvider是Telephony中實現的Content Provider(IccProvider),它提供SIM卡聯絡人的相關操作。IccProvider原始碼所在的工程路徑為:packages\services\Telephony。在該工程中,IccProvider的宣告如下:
<providerandroid:name="IccProvider"
android:authorities="icc"
android:multiprocess="true"
android:exported="true"
android:readPermission="android.permission.READ_CONTACTS"
android:writePermission="android.permission.WRITE_CONTACTS"/>。
IccProvider相關功能的具體實現主要在如下Java檔案中:frameworks/opt/telephony/src/java/com/android/internal/telephony/IccProvider.java。另外,Telephony的包名為:com.android.phone,生成的APK的名稱為:TeleService.apk
2 IccProvider提供的URI
一般情況下,IccProvider對外提供的URI為:“content://icc/and”。如果系統支援雙卡,用此URI操作的SIM卡為使用者首選的SIM卡。對於雙卡,某些晶片廠商會針對不同的SIM卡定義不同的URI,具體格式為:“content://icc/adn/subId/SubId”。其中SubId的值需要根據SIM卡當前的Subscription Id進行填充。例如,如果SIM1和SIM2的SubId分別為0和1,那麼,這個兩張SIM卡的URI為:“content://icc/adn/subId/0”和“content://icc/adn/subId/1”。
注意:
1.SubId可以通過SubscriptionInfo物件獲取;
2.對於地址“content://icc/adn/subId/SubId”,並不是所有的IccProvider都支援。
3.對於某些SIM卡(型別為USIM或者CSIM)卡,可以支援如下格式的URI:content://icc/pbr/subId/SubId;而某些型別的SIM卡(型別為UIM或者SIM),支援的URI為:content://icc/adn/subId/SubId。Android的標準介面並沒有提供獲取SIM卡型別的介面,需要通過晶片廠商提供的介面獲取(例如,MTK平臺就專門提供了這樣的介面)。不同的URI,所能操作的儲存空間可能不一樣,例如,電信的UIM卡,如果用ADN,則只能儲存250個聯絡人;用PBR,則可以儲存500個聯絡人。但是移動和聯通卡的ADN和PBR都可以儲存500個聯絡人。
3 SIM卡聯絡人資料庫表的欄位
IccProvider中返回的SIM卡聯絡人的欄位如下:index, name, number, emails, additionalNumber, groupIds, _id, aas, sne。
4 IccProvider在聯絡人操作上的差異
1.1 查詢聯絡人
在查詢聯絡人時,不支援條件查詢。
1.2 插入聯絡人
1.姓名欄位不能為空;
2.號碼欄位不能有空格或者其它非數字字元;
3.在填充ContentValues的資料時,聯絡人姓名的Key並不是“name”,而是“tag”;
示例程式碼如下:
ContentResolver contentResolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put("tag", "test");
contentValues.put("number", "123");
Uri insertUri = contentResolver.insert(simUri, contentValues);
1.3 刪除聯絡人
支援條件刪除,可以用index欄位作為條件。
注意:
1.清除SIM卡聯絡人,再新增新的聯絡人到SIM卡,index並不會一直遞增,而是複用;同樣,_id欄位也是複用的。
1.4 修改聯絡人
在修改聯絡人時,IccProvider需要通過原來的姓名和電話號碼來匹配要更新的聯絡人,因此,除了指定更新後的姓名和電話號碼之外,還需要指定原來的姓名和電話號碼。
示例程式碼如下:
ContentResolver contentResolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put("tag", "test");
contentValues.put("number", "123");
contentValues.put("newTag", "update");
contentValues.put("newNumber", "456");
int result = contentResolver.update(simUri, contentValues, null, null);
5 IccProvider各操作返回值的定義
呼叫IccProvider的增刪改這些介面時,會返回這些操作的狀態資訊,這些狀態資訊的說明在IccProvider.java中定義,如下:
/**
* Error code: success.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_SUCCESS = 1;
/**
* Error code: unkonwn error.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_UNKNOWN = 0;
/**
* Error code: number too long.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_NUMBER_TOO_LONG = -1;
/**
* Error code: text too long.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_TEXT_TOO_LONG = -2;
/**
* Error code: storage full.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_STORAGE_FULL = -3;
/**
* Error code: not ready.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_NOT_READY = -4;
/**
* Error code: password error.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_PASSWORD_ERROR = -5;
/**
* Error code: ANR too long.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_ANR_TOO_LONG = -6;
/**
* Error code: generic failure.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_GENERIC_FAILURE = -10;
/**
* Error code: ADN list not exist.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_ADN_LIST_NOT_EXIST = -11;
/**
* Error code: Email full.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_EMAIL_FULL = -12;
/**
* Error code: Email too long.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_EMAIL_TOO_LONG = -13;
/**
* Error code: ANR save failed.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_ANR_SAVE_FAILURE = -14;
/**
* Error code: wrong ADN format.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_WRONG_ADN_FORMAT = -15;
/**
* Error code: SNE full.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_SNE_FULL = -16;
/**
* Error code: SNE too long.
*
* @internal
*/
publicstatic final int ERROR_ICC_PROVIDER_SNE_TOO_LONG = -17;