實現預置連絡人(包含姓名、號碼資訊)至手機中;並保證該連絡人是唯讀,無法被刪除/編輯。
代碼分為兩部分:
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");
}