预置联系人

预置联系人

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


解决方法:

本方案实现预置联系人(包含姓名、号码信息)至手机中;并保证该联系人是只读的,无法被删除/编辑。            

代码分为两部分:

Part One预置的联系人插入到数据库中;

Part Two保证预置联系人只读,无法被编辑删

(在三个地方屏蔽对预置联系人进行编辑处理:联系人详情界面、联系人多选界面、新建联系人选择合并联系人时

【注意】

如果您不需要限制预置联系人的删除/编辑操作,加入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

Pathalps\packages\apps\ContactsCommon\src\com\mediatek\contacts\simservice

添加

public static final int SERVICE_WORK_IMPORT_PRESET_CONTACTS = 5;

3. 修改SIMProcessorManager.java

Pathalps\packages\apps\Contacts\src\com\mediatek\contacts\simservice

else if (workType == SIMServiceUtils.SERVICE_WORK_IMPORT_PRESET_CONTACTS) {
 
    processor = new PresetContactsImportProcessor(context, slotId, intent, listener);
 
}

4. 修改BootCmpReceiver.java

Pathalps\packages\apps\Contacts\src\com\mediatek\contacts\simcontact

在BootCmpReceiver.java中添加如下方法:

/**
 
* when boot complete,preset the service number directly.
 
*/
 
private void presetServiceNumber(Context context) {
 
    LogUtils.d(TAG, "presetServiceNumber");
 
    startSimService(context, -1, SIMServiceUtils.SERVICE_WORK_IMPORT_PRESET_CONTACTS);
 
}

5. 修改BootCmpReceiver.java

Pathalps\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

Pathalps\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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值