本文共 5558 字,大约阅读时间需要 18 分钟。
实现预置联系人(包含姓名、号码信息)至手机中;并保证该联系人是只读的,无法被删除/编辑。 代码分为两部分: Part One 将预置的联系人插入到数据库中; Part Two 实现在联系人详情和联系人多选界面中无法删除/编辑预置联系人。 【注意】如果您不需要限制预置联系人的删除/编辑操作,那么仅加入Part One部分代码即可,并去掉第三步”新增函数“ 中的语句:contactvalues.put(RawContacts.IS_SDN_CONTACT, -1); File:alps\packages\apps\Contacts\src\com\mediatek\contacts\simcontact\AbstractStartSIMService.java 1.引入包 import android.provider.ContactsContract.PhoneLookup; 2.增加变量 private static boolean sIsRunningNumberCheck = false; private static final int INSERT_PRESET_NUMBER_COUNT = xxx; //预置联系人的个数 private static final String INSERT_PRESET_NAME[] = {"xxx1","xxx2",...}; //各预置联系人的姓名 private static final String INSERT_PRESET_NUMBER[] = {"xxx1","xxx2",...}; //各预置联系人的号码 3.增加函数(将预置联系人信息写入数据库中): private void importDefaultReadonlyContact() { new Thread(new Runnable() { @Override public void run() { Log.i(TAG, "isRunningNumberCheck before: " + sIsRunningNumberCheck); if (sIsRunningNumberCheck) { return; } sIsRunningNumberCheck = true; for(int i = 0;i < INSERT_PRESET_NUMBER_COUNT; i++) { Log.i(TAG, "isRunningNumberCheck after: " + sIsRunningNumberCheck); Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri .encode(INSERT_PRESET_NUMBER[i])); Log.i(TAG, "getContactInfoByPhoneNumbers(), uri = " + uri); Cursor contactCursor = 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<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>(); 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, -1); 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 { 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 { // when this service start,but the contactsprovider has not been started yet. // the contactCursor perhaps null, but not always.(first load will weekup the provider) // so add null block to avoid nullpointerexception if (contactCursor != null) { contactCursor.close(); } } }//for Log.i(TAG, "isRunningNumberCheck insert: " + sIsRunningNumberCheck); sIsRunningNumberCheck = false; } }).start(); } 4.onStart中调用这个函数: public void onStart(Intent intent, int startId) { ..... //add by MTK---Preset Contacts importDefaultReadonlyContact(); log("[onStart]" + intent + ", startId " + startId); if (intent == null) { return; } ..... } Part Two 1.File:DefaultContactListAdapter.java Path:alps\packages\apps\contacts\src\com\android\contacts\list configureSelection函数中有五处 RawContacts.IS_SDN_CONTACT + " = 0",都改为:RawContacts.IS_SDN_CONTACT + " < 1" 2.File:ProfileAndContactsLoader.java Path:alps\packages\apps\contacts\src\com\android\contacts\list loadSDN函数中有两处 RawContacts.IS_SDN_CONTACT + " = 0",都改为:RawContacts.IS_SDN_CONTACT + " < 1" 3. File:Contact.java Path:alps\packages\apps\contacts\src\com\android\contacts\model 增加如下函数: //add by MTK---Preset Contacts public boolean isReadOnlyContact() { return mIsSdnContact == -1; } 4. File:ContactLoaderFragment.java Path:alps\packages\apps\contacts\src\com\android\contacts\detail 将isContactEditable函数修改为: public boolean isContactEditable() { return mContactData != null && !mContactData.isDirectoryEntry() && !mContactData.isSdnContacts() && !mContactData.isReadOnlyContact() ; } 5. File:ContactEntryListAdapter.java Path:alps\packages\apps\contacts\src\com\android\contacts\list 在文件最后增加以下代码: public boolean showReadOnlyContact = true; public void setShowReadOnlyContact(boolean canDelete) { showReadOnlyContact = canDelete; } 6. File:ContactEntryListFragment.java Path:alps\packages\apps\contacts\src\com\android\contacts\list 引入如下包: import com.mediatek.contacts.list.ContactsMultiDeletionFragment; 在onCreateLoader函数中,倒数第二句mAdapter.configureLoader(loader, directoryId);之前增加语句: mAdapter.setShowReadOnlyContact((this instanceof ContactsMultiDeletionFragment) ? false : true); 8 7.File:MultiContactsBasePickerAdapter.java Path:alps\packages\apps\contacts\src\com\mediatek\contacts\list 在configureSelection函数最后的语句 loader.setSelection(selection.toString());之前增加语句: if (!showReadOnlyContact ) { selection.append(" AND " + Contacts.IS_SDN_CONTACT + "=0"); }转载地址:http://kegdi.baihongyu.com/