您的位置:首页 > 移动开发 > Android开发

预置联系人

2016-09-28 11:17 92 查看
预置联系人

此方法比较适合预置联系人的数目不是特别多的情况

解决方法:


本方案实现预置联系人(包含姓名、号码信息)至手机中;并保证该联系人是只读的,无法被删除/编辑。            
代码分为两部分:
[b]Part One将预置的联系人插入到数据库中;[/b]
[b]Part Two保证预置联系人只读,无法被编辑删[/b]
(在三个地方屏蔽对预置联系人进行编辑处理:联系人详情界面、联系人多选界面、新建联系人选择合并联系人时)。
[b]【注意】[/b]
如果您不需要限制预置联系人的删除/编辑操作,加入Part One部分代码即可,并去掉第一步”新增函数“  中的语句:contactvalues.put(RawContacts.IS_SDN_CONTACT, -2);

Part One

新建 PresetContactsImportProcessor.java


Path: alps\packages\apps\Contacts\src\com\mediatek\contacts\simservice

package com.mediatek.contacts.simservice;

import com.mediatek.contacts.simservice.SIMProcessorManager.ProcessorCompleteListener;

import android.content.Context;

import android.content.Intent;

import android.util.Log;

import android.content.ContentProviderOperation;

import android.content.ContentValues;

import android.content.OperationApplicationException;

import android.database.Cursor;

import android.net.Uri;

import android.provider.ContactsContract;

import android.provider.ContactsContract.CommonDataKinds.Email; //for usim

import android.provider.ContactsContract.CommonDataKinds.GroupMembership;

import android.provider.ContactsContract.CommonDataKinds.Phone;

import android.provider.ContactsContract.CommonDataKinds.StructuredName;

import android.provider.ContactsContract.Data;

import android.provider.ContactsContract.Groups;

import android.provider.ContactsContract.RawContacts;

import com.android.contacts.common.model.account.AccountType;

import android.os.RemoteException;

import java.util.ArrayList;

import com.mediatek.contacts.simservice.SIMProcessorManager.ProcessorCompleteListener;

import com.mediatek.contacts.simservice.SIMServiceUtils;

import com.mediatek.contacts.simservice.SIMServiceUtils.ServiceWorkData;

import com.mediatek.contacts.simcontact.SimCardUtils;

import com.mediatek.contacts.util.LogUtils;

import android.provider.ContactsContract.PhoneLookup;

public class PresetContactsImportProcessor extends SIMProcessorBase {

private static final String TAG = "PresetContactsImportProcessor";

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",...};   //各预置联系人的号码

private int mSlotId;

private Context mContext;

public PresetContactsImportProcessor(Context context, int slotId, Intent intent, ProcessorCompleteListener listener) {

super(intent, listener);

mContext = context;

mSlotId = slotId;

}

@Override

public int getType() {

return SIMServiceUtils.SERVICE_WORK_IMPORT_PRESET_CONTACTS;

}

@Override

public void doWork() {

if (isCancelled()) {

LogUtils.d(TAG, "[doWork]cancel import preset contacts work. Thread id=" + Thread.currentThread().getId());

return;

}

importDefaultReadonlyContact();

}

private void importDefaultReadonlyContact(){

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 = 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 {

// 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();

}

} //END for

Log.i(TAG, "isRunningNumberCheck insert: " + sIsRunningNumberCheck);

sIsRunningNumberCheck = false;

}

}

}


2. 修改SIMServiceUtils.java
Path:alps\packages\apps\ContactsCommon\src\com\mediatek\contacts\simservice
添加

5. 修改BootCmpReceiver.java
Path:alps\packages\apps\Contacts\src\com\mediatek\contacts\simcontact

在BootCmpReceiver.java中onReceive()方法

public void onReceive(Context context, Intent intent) {

... ...

} 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);

}

}

... ...

}
修改为:

public void onReceive(Context context, Intent intent) {

... ...

} 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]

}

... ...

}


Part Two
1.  File:DefaultContactListAdapter.java  
Path:
alps\packages\apps\ContactsCommon\src\com\android\contacts\common\list
configureOnlyShowPhoneContactsSelection函数中如下语句:
selection.append(Contacts.INDICATE_PHONE_SIM + "= ?");

selectionArgs.add("-1");
之后增加下面的代码
selection.append(" AND " + RawContacts.IS_SDN_CONTACT + " > -2");

2.  File:Contact.java 
Path:alps\packages\apps\ContactsCommon\src\com\android\contacts\common\model 
增加如下函数:
//add for Preset Contacts

public boolean isReadOnlyContact() {

return mIsSdnContact == -2;

}

3.  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.isInternationalDialNumber() && !mContactData.isReadOnlyContact() ;

}

 4.File:ContactEntryListAdapter.java 
Path:alps\packages\apps\contactscommon\src\com\android\contacts\common\list  
在文件最后增加以下代码:

public boolean showReadOnlyContact = true;

public void setShowReadOnlyContact(boolean canDelete) {

showReadOnlyContact = canDelete;

}


5.  File:ContactEntryListFragment.java  
Path:alps\packages\apps\contactscommon\src\com\android\contacts\common\list
添加代码:
protected boolean isInstanceOf ContactsMultiDeletionFragment(){

return false;

}

在onCreateLoader函数中,倒数第二句
mAdapter.configureLoader(loader, directoryId);

之前增加语句: 

mAdapter.setShowReadOnlyContact(isInstanceOfContactsMultiDeletionFragment() ? false : true);

mAdapter.configureLoader(loader, directoryId);


6. File:
ContactsMultiDeletionFragment.java

Path:alps\packages\apps\Contacts\src\com\mediatek\contacts\list

添加代码:
protected boolean isInstanceOfContactsMultiDeletionFragment(){

return true;

}

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");

}

loader.setSelection(selection.toString());

8.File:AggregationSuggestionEngine.java
Path:alps\packages\apps\contacts\src\com\android\contacts\editor
在loadAggregationSuggestions函数最后的语句
在语句:
sb.append(" AND " + Contacts.INDICATE_PHONE_SIM + "=-1");
之后添加:
sb.append(" AND " + Contacts.IS_SDN_CONTACT + "!=-2");

9.File:JoinContactListAdapter.java
Path:packages\apps\contacts\src\com\android\contacts\list  
函数:public void configureLoader(CursorLoader cursorLoader, long directoryId)
将:
loader.setSelection(Contacts._ID + "!=?"+" AND " + Contacts.INDICATE_PHONE_SIM + "=-1");
修改为:

loader.setSelection(Contacts._ID + "!=?"+" AND " + Contacts.INDICATE_PHONE_SIM + "=-1" + " AND " + Contacts.IS_SDN_CONTACT + "!=-2");


如果需要过CTS,添加如下修改:

    PresetContactsImportProcessor.java

//contactvalues.put(RawContacts.ACCOUNT_NAME, AccountType.ACCOUNT_NAME_LOCAL_PHONE);
//contactvalues.put(RawContacts.ACCOUNT_TYPE, AccountType.ACCOUNT_TYPE_LOCAL_PHONE);
contactvalues.put(RawContacts.ACCOUNT_NAME, "PreSet Contacts");
contactvalues.put(RawContacts.ACCOUNT_TYPE, "Preset Contacts Account");


packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java 
/*
* Bug Fix by Mediatek Begin.
*
*   CR ID: ALPS000111101
*   Descriptions:
*/
private boolean canDeleteAccount(AccountWithDataSet accountWithDataSet) {
if (accountWithDataSet.getDataSet() == null) {
if ((accountWithDataSet.getAccountName().equals("Phone") && accountWithDataSet
.getAccountType().equals("Local Phone Account"))
|| accountWithDataSet.getAccountName().equals("Tablet")
|| accountWithDataSet.getAccountType().equals("SIM Account")
|| accountWithDataSet.getAccountType().equals("USIM Account")
|| accountWithDataSet.getAccountType().equals("UIM Account")
|| accountWithDataSet.getAccountType().equals("CSIM Account")
// Segon add
|| accountWithDataSet.getAccountType().equals("Preset Contacts Account")
) {
Log.d(TAG, "[canDeleteAccount] -> not delete: " + accountWithDataSet);
return false;
}
}
return true;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息