這樣一個需求,手機第一次啓動的時候,需要內置一個羣組,並且裏面有給定的聯繫人信息,
本來打算寫雙進程守護的,結果昨天接到一個這樣的任務,就先把它做了,發現裏面有些操作數據庫的東西還是值得看一下。
首先接到這樣一個需求第一眼就是懵逼,然後還是得硬着頭皮搞,接下來分析下這個需求需要怎麼搞:
1、首先第一次啓動 Android 有一個開機啓動的廣播;
2、啓動後去內置一個羣組;
3、內置客戶給的聯繫人;
4、把聯繫人加到羣組裏面。
根據這四個步驟我們來一步一步搞定(透漏一下這篇文章的精華所在 就是最後一步把聯繫人加到羣組裏面 這個網上找了好久都沒找到)
1、開機啓動廣播
由於我是基於源碼開發的即在android原生的contacts進行修改
android源碼中應用層關於contacts的代碼位於
packages\apps\Contacts
packages\apps\ContactsCommon
這兩個地方
基於源碼開發一般先要看看源碼中有沒有我們需要的開機廣播有的話我們就不需要重新去寫這些代碼了,一方面省事,另一方面既然源碼裏面已經有
了,我們在去重新寫 會顯得代碼比較混亂。
通過搜索發現有這樣一個類BootCmpReceiver.java
中有接受開機廣播的地方
else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
// fix ALPS01003520,when boot complete,remove the contacts if the
// card of a slot has been removed
if (!isPhbReady()) {
processBootComplete(context);
}
// [START] add for Preset service number
presetServiceNumber(context);
// [END]
}
private void presetServiceNumber(Context context) {
SIMProcessorBase processor = null;
LogUtils.d(TAG, "presetServiceNumber");
// processor = new PresetContactsImportProcessor(context, -1, null, null);
startSimService(context, -1, SIMServiceUtils.SERVICE_WORK_IMPORT_PRESET_CONTACTS);
}
private void startSimService(Context context, int subId, int workType) {
Intent intent = null;
intent = new Intent(context, SIMProcessorService.class);
intent.putExtra(SIMServiceUtils.SERVICE_SUBSCRIPTION_KEY, subId);
intent.putExtra(SIMServiceUtils.SERVICE_WORK_TYPE, workType);
LogUtils.d(TAG, "[startSimService]subId:" + subId + "|workType:" + workType);
context.startService(intent);
}
所以我在其中加了這幾段啓動服務的代碼 看這代碼結構也許跟google原生的不一樣這是我們公司修修改改後的結果 我們主要分析原理
首先找到開機廣播 在裏面加入我們的函數presetServiceNumber(context)
然後開啓服務去執行我們的內置羣組、聯繫人的操作
2、 內置羣組
private void addDefaultGroups() {
Uri uri = Groups.CONTENT_URI;
StringBuilder selection = new StringBuilder();
selection.append(Groups.DELETED + "=0");
selection.append(" AND " + Groups.TITLE + "='" + "ROAMING" + "'");
Cursor groupCursor = mContext.getContentResolver().query(uri,
new String[] { Groups._ID, Groups.TITLE }, selection.toString(), null, null);
try {
if (groupCursor != null && groupCursor.getCount() > 0) {
return;
} else {
String defaultGroups[] = "ROAMING";
final ArrayList operationList = new ArrayList();
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
ContentValues groupValues = new ContentValues();
groupValues.put(Groups.ACCOUNT_NAME,AccountType.ACCOUNT_NAME_LOCAL_PHONE);
groupValues.put(Groups.ACCOUNT_TYPE,AccountType.ACCOUNT_TYPE_LOCAL_PHONE);
groupValues.put(Groups.TITLE, defaultGroups);
groupValues.put(Groups.GROUP_IS_READ_ONLY, 1);
builder.withValues(groupValues);
operationList.add(builder.build());
try {
mContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operationList);
groupValues.clear();
operationList.clear();
} catch (RemoteException e) {
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
} catch (OperationApplicationException e) {
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
}
}
} finally {
if (groupCursor != null) {
groupCursor.close();
}
}
}
去掉不相關的代碼這就是我們內置羣組的核心代碼,
看上面代碼 首先我們去查詢羣組名爲“ROAMING”的羣組是否存在。
當Groups.DELETED=0的時候, 是 查詢沒有被刪除的聯繫人分組
當Groups.DELETED=1的時候,是查詢刪除的分組
如果存在就return了,不存在我們就是新建,新建羣組的大部分都都相似主要是
groupValues.put(Groups.TITLE, defaultGroups); //羣組的TITLE
groupValues.put(Groups.GROUP_IS_READ_ONLY, 1); //是否只讀
3、內置聯繫人
private void importDefaultReadonlyContact(){
for(int i = 0;i < INSERT_PRESET_NAME.length; i++) {
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(INSERT_PRESET_NUMBER[i]));
Cursor contactCursor = mContext.getContentResolver().query(uri,
new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup.PHOTO_ID}, null, null, null);
try {
if (contactCursor != null && contactCursor.getCount() > 0) {
return;
} else {
final ArrayList operationList = new ArrayList();
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
ContentValues contactvalues = new ContentValues();
contactvalues.put(RawContacts.ACCOUNT_NAME, AccountType.ACCOUNT_NAME_LOCAL_PHONE);
contactvalues.put(RawContacts.ACCOUNT_TYPE, AccountType.ACCOUNT_TYPE_LOCAL_PHONE);
contactvalues.put(RawContacts.INDICATE_PHONE_SIM, ContactsContract.RawContacts.INDICATE_PHONE);
contactvalues.put(RawContacts.IS_SDN_CONTACT, -2);
builder.withValues(contactvalues);
builder.withValue(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
operationList.add(builder.build());
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0);
builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
builder.withValue(Phone.TYPE, Phone.TYPE_MOBILE);
builder.withValue(Phone.NUMBER, INSERT_PRESET_NUMBER[i]);
builder.withValue(Data.IS_PRIMARY, 1);
operationList.add(builder.build());
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0);
builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
builder.withValue(StructuredName.DISPLAY_NAME, INSERT_PRESET_NAME[i]);
operationList.add(builder.build());
try {
mContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operationList);
} catch (RemoteException e) {
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
} catch (OperationApplicationException e) {
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
}
}
} finally {
if (contactCursor != null) {
contactCursor.close();
}
}
}
}
去掉不相關的代碼這就是我們內置聯繫人的核心代碼 其中INSERT_PRESET_NUMBER是我們的聯繫人號碼數組可以寫 如{“185…..”,”158…..”,”137….”}等
INSERT_PRESET_NAME是聯繫人姓名數組可以寫 如{“張三”,“李四”,“王五”}等
首先也是查詢數據庫看看我們的聯繫人號碼是否存在,存在的話就 return
不存在的話就去創建
聯繫人的操作大部分也都是一樣的
主要是
builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); //MIME類型
builder.withValue(Phone.TYPE, Phone.TYPE_MOBILE);//phone類型可以是 號碼 姓名之類的
builder.withValue(Phone.NUMBER, INSERT_PRESET_NUMBER[i]);//號碼
builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE); //MIME類型
builder.withValue(StructuredName.DISPLAY_NAME, INSERT_PRESET_NAME[i]);//姓名
還可以加入郵箱之類的,
builder.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE); //MIME類型
builder.withValue(Email.TYPE, Email.TYPE_MOBILE);//Email類型
builder.withValue(Email.DATA, email);//EMail
4、把聯繫人加到羣組裏面。
怎麼把聯繫人加入到羣組呢
有兩種方法 第一種是內置聯繫人是 在聯繫人中加入羣組標示;
第二中是內置羣組後,把聯繫人批量導入羣組
我們今天用第一種方式實現:
首先看聯繫人的操作
builder.withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);//MIME類型
builder.withValue(GroupMembership.GROUP_ROW_ID, grpId);//羣組
我們可以通過這樣把聯繫人加如羣組標籤
所以這裏我們關鍵的操作就是找到grpId即我們要加入羣組ID
Uri urigroup = Groups.CONTENT_URI;
StringBuilder selection = new StringBuilder();
selection.append(Groups.DELETED + "=0");
selection.append(" AND " + Groups.TITLE + "='" + "ROAMING CUSTOMER CARE" + "'");
Cursor groupCursor = mContext.getContentResolver().query(urigroup,
new String[] { Groups._ID, Groups.TITLE }, selection.toString(), null, null);
try {
if(groupCursor!=null && groupCursor.getCount()>0 ){
while (groupCursor.moveToNext()) {
grpId = groupCursor.getLong(groupCursor.getColumnIndex(Groups._ID));
}
}else{
addDefaultGroups();
}
}finally {
if (groupCursor != null) {
groupCursor.close();
}
}
跟內置羣組操作差不多一樣但是這麼我們如果查詢到的話就取出這個羣組的id如果不存在就是內置羣組,
經過上面這四步我們就能順利的吧聯繫人內置到羣組裏面了。