在手机中预置联系人/Service Number

代码分为两部分:

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

Part Two 保证预置联系人只读,无法被编辑删除(在三个地方屏蔽对预置联系人进行编辑处理:联系人详情界面、联系人多选界面、新建联系人选择合并联系人时)。

【注意】如果您不需要限制预置联系人的删除/编辑操作,加入Part One部分代码即可,并去掉第三步”新增函数“  中的语句:contactvalues.put(RawContacts.IS_SDN_CONTACT, -1);

Part One:

File:AbstractStartSIMService.java

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

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

(1)configureSelection函数中有五处 RawContacts.IS_SDN_CONTACT + " = 0",都改为:RawContacts.IS_SDN_CONTACT + " < 1"

(2)configureOnlyShowPhoneContactsSelection函数中如下语句:

selection.append(Contacts.INDICATE_PHONE_SIM + "= ?");

selectionArgs.add("-1");

之后增加下面的代码

selection.append(" AND " + 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");

}

8.File:AggregationSuggestionEngine.java Path:alps\packages\apps\contacts\src\com\android\contacts\editor

在configureSelection函数最后的语句

在语句:   sb.append(" AND " + Contacts.INDICATE_PHONE_SIM + "=-1");

之后添加: sb.append(" AND " + Contacts.IS_SDN_CONTACT + "!=-1");

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 + "!=-1");

【After JB5】

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

代码分为两部分:

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

Part Two 保证预置联系人只读,无法被编辑删除(在三个地方屏蔽对预置联系人进行编辑处理:联系人详情界面、联系人多选界面、新建联系人选择合并联系人时)。

【注意】如果您不需要限制预置联系人的删除/编辑操作,加入Part One部分代码即可,并去掉第一步”新增函数“  中的语句:contactvalues.put(RawContacts.IS_SDN_CONTACT, -2);

Part One:

1.新建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<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, -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();

}

}//for

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

sIsRunningNumberCheck = false;

}

}

}

2. 修改SIMServiceUtils.java

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

添加

public static final int SERVICE_WORK_IMPORT_PRESET_CONTACTS = 5;

3. 修改SIMProcessorManager.java

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

在SIMProcessorManager.java中createProcessor函数里添加

else if (workType == SIMServiceUtils.SERVICE_WORK_IMPORT_PRESET_CONTACTS) {

processor = new PresetContactsImportProcessor(context, slotId, intent, listener);

}

4. 修改BootCmpReceiver.java

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

在BootCmpReceiver.java中processBootComplete()方法最后添加代码

startSimService(-1, SIMServiceUtils.SERVICE_WORK_IMPORT_PRESET_CONTACTS);

Part Two

1.  File:DefaultContactListAdapter.java

Path: alps\packages\apps\ContactsCommon\src\com\android\contacts\common\list

(1)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 by MTK---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.is InternationalDialNumber()&&  !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 isInstanceOfContactsMultiDeletionFragment(){

return false;

}

在onCreateLoader函数中,倒数第二句mAdapter.configureLoader(loader, directoryId);之前增加语句:

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

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

}

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

时间: 2024-07-31 21:49:58

在手机中预置联系人/Service Number的相关文章

利用手机中存储的电话号码给联系人打电话与发短信

1.将存储在数据库中的数据布局到手机界面上,其操作请见http://blog.csdn.net/xia09222826/article/details/28660653 2.三种效果显示出的效果分别是: 1)自定义的效果 2)单选的效果 3)多选的效果 3.点击某一个联系人进行拨打电话或者发送短信(以自定义的效果为例) 1)效果视图(比如点击了序号1的联系人):从手机电话备份界面跳转到PhoneandemailActitvity界面 2)程序实现 ①注册点击事件         lv_users

android GB2/GB3版本预置联系人且不可编辑或删除

一.针对GB2.GB3等版本,预置联系人可以 中Part one这部分即可. 例如:在AbstractStartSIMService类的开始增加的定义如下: public static final int  INSERT_NUMBER_COUNT = 4;    //定义要预置的联系人的个数 public static final String  defaultNumbers[] = {"xxxx", "xxxx", "xxxx" , "

从通讯录中导入联系人并去重

首先给出实现完的界面图 上面是给出来的实现结果图. 从本地联系人中导出联系人,需要使用ContentProvider来获取通讯录中的联系人. 从通讯录中获取联系人方法如下: /** 得到手机通讯录联系人信息 **/ private void getPhoneContacts() { ContentResolver resolver = ContactsActivity.this.getContentResolver(); // 获取手机联系人 Cursor cursor = resolver.q

Android手机获取通讯录联系人信息及短信广播实现

现在越来越多的android应用在注册时都要用到手机号码,通过获取手机验证码来完成注册.也有不少应用提供了手机通讯录备份功能,获得你的允许后把你的通讯录中的手机号码保存到服务器中,你要的时候又可以down下来,比如微信,QQ等就有这们的功能.那我们怎么样获取用户通讯录中的手机号码呢?Android已经为我们做好了准备: ---------------------------------获取通讯录联系人信息----------------------------------------------

Android 增,删,改,查 通讯录中的联系人

一.权限 操作通讯录必须在AndroidManifest.xml中先添加2个权限, <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission> <uses-permission android:name="android.permission.WRITE_CONTACTS"></uses-permission>

关于鼠标事件和手机中的各个事件的几点总结

今天就来盘点一下鼠标的事件和手机触摸事件. 一.鼠标事件 onmousedown事件,当鼠标左键按下时触发. 如:当鼠标元素boxq1上按下时,改变它的背景颜色. var box1 = document.getElementById("box1"); box1.onmousedown = function(){ box1.style.backgroundColor = 'green'; }; 2. onmouseup事件,当鼠标左键抬起时触发.如:鼠标按下之前元素box1背景颜色为红色

25.Unity3D手机中Input类touch详解-Unity触屏事件解析到底(Twisted Fate)

首先贴一下Unity支持的模型文件类型,以前没有收集过. Unity支持两种类型的3D文件格式: 1.  通用的"出口型"3D文件 如.fbx..dae..3ds..dxf..obj等文件格式. 2.  3D软件专用的3D文件格式 如Max, Maya, Blender,Cinema4D, Modo, Lightwave & Cheetah3D 等软件所支持的格式,如.MAX, .MB, .MA等等. Unity3D手机中Input类touch详解: 1.Input.touch

如何在Ubuntu手机中使用前置照相机

我们可以在Ubuntu QML的API文档中看到Camera的用法,但是里面没有写到任何的前置Camera的调用方法.对于一些应用来说,前置Camera的使用是重要的.我们必须使用Qt C++代码来实现这个功能.在这篇文章中,我们来介绍如何使用Ubuntu手机中的前置照相机. 1)创建一个最基本的QML应用         这样我们就生成了一个含有plugin的项目. 2)在项目中加入CameraSelector来选择照相机 为了能够调用Camera的一些API,我们在plugin中加入如下的C

NetworkInfo 手机中的网络类型

04-27 21:56:54.442: E/NetworkInfo(26457): NetworkInfo: type: mobile[EDGE], state: DISCONNECTED/IDLE, reason: (unspecified), extra: (none), roaming: false, failover: true, isAvailable: false;ni.typename=mobile 04-27 21:56:54.442: E/NetworkInfo(26457):