Implement preset contacts (including names and numbers) to the mobile phone. Ensure that the contacts are read-only and cannot be deleted or edited.
The code is divided into two parts:
Part One inserts the preset contacts into the database;
In Part Two mode, you cannot delete or edit a preset contact on the contact details and contact multi-choice interface.
[Note] If you do not need to restrict the delete/edit operations of the preset contact, add only Part of the Part One code and remove the statement contactvalues in step 3 "add function. put (RawContacts. IS_SDN_CONTACT,-1 );
File: alps \ packages \ apps \ Contacts \ src \ com \ mediatek \ contacts \ simcontact \ AbstractStartSIMService. java
1. Import package
Import android. provider. ContactsContract. PhoneLookup;
2. Add variable
Private static boolean sIsRunningNumberCheck = false;
Private static final int INSERT_PRESET_NUMBER_COUNT = xxx; // Number of Preset contacts
Private static final String INSERT_PRESET_NAME [] = {"xxx1", "xxx2",...}; // name of each preset contact
Private static final String INSERT_PRESET_NUMBER [] = {"xxx1", "xxx2",...}; // The number of each preset contact
3. Add a function (write the preset contact information to the database ):
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 );
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 ();
}
}
} //
Log. I (TAG, "isRunningNumberCheck insert:" + sIsRunningNumberCheck );
SIsRunningNumberCheck = false;
}
}). Start ();
}
4. onStart calls this function:
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: defacontcontactlistadapter. java Path: alps \ packages \ apps \ contacts \ src \ com \ android \ contacts \ list
The configureSelection function contains five RawContacts. IS_SDN_CONTACT + "= 0", all of which are changed to RawContacts. IS_SDN_CONTACT + "<1"
2. File: ProfileAndContactsLoader. java Path: alps \ packages \ apps \ contacts \ src \ com \ android \ contacts \ list
The loadSDN function contains RawContacts. IS_SDN_CONTACT + "= 0", both of which are changed to RawContacts. IS_SDN_CONTACT + "<1"
3. File: Contact. java Path: alps \ packages \ apps \ contacts \ src \ com \ android \ contacts \ model
Add the following functions:
// 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
Modify the isContactEditable function:
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
Add the following code at the end of the file:
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
Introduce the following package:
Import com. mediatek. contacts. list. ContactsMultiDeletionFragment;
In the onCreateLoader function, add the following statement to the penultimate sentence 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 the Final Statement loader in the configureSelection function. setSelection (selection. toString (); previously added the statement:
If (! ShowReadOnlyContact ){
Selection. append ("AND" + Contacts. IS_SDN_CONTACT + "= 0 ");
}