在手机中预置联系人/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");
在手机中预置联系人/Service Number的更多相关文章
- 读取手机中的联系人信息(android.provider.ContactsContract)
本篇开始讲如何从Android中得到本机联系人的信息.由于Android较快的版本升级,部分API已经发生了变化.本篇探究的通过ContentProvider机制获取联系人的API从Android2. ...
- Android向手机通讯录中的所有的联系人(包括SIM卡),向手机通讯录中插入联系人
package com.example.myapi.phonepersion; import java.util.ArrayList; import java.util.List; import an ...
- Android-->发送短信页面实现(短信发送以及群发和从电话本中选择联系人)-----------》2
分析下怎么写 首先,我们需要一个输入框,可以手动的输入手机号码, 其次,很少有人愿意手动输入,那么我们需要提供一个按钮来给我们的用户选择自己电话本中的联系人(一次可以选择多个即群发) 然后,我们需要一 ...
- [UWP]UWP中获取联系人/邮件发送/SMS消息发送操作
这篇博客将介绍如何在UWP程序中获取联系人/邮件发送/SMS发送的基础操作. 1. 获取联系人 UWP中联系人获取需要引入Windows.ApplicationModel.Contacts名称空间. ...
- 【转】Android 增,删,改,查 通讯录中的联系人
一.权限 操作通讯录必须在AndroidManifest.xml中先添加2个权限, <uses-permission android:name="android.permission. ...
- 微软BI 之SSIS 系列 - 在 SSIS 中使用 Web Service 以及 XML 解析
开篇介绍 Web Service 的用途非常广几乎无处不在,像各大门户网站上的天气预报使用到的第三方 Web Service API,像手机客户端和服务器端的交互等都可以通过事先设计好的 Web Se ...
- Android 增,删,改,查 通讯录中的联系人
一.权限 操作通讯录必须在AndroidManifest.xml中先添加2个权限, <uses-permission android:name="android.permission. ...
- 从Android手机中取出已安装的app包,导出apk
从Android手机中取出已安装的app包,导出apk TAG:Android,提取,apk,adb,pm,root,导出apk 假设有这样一个场景,A君看到你手机上一个实用APP,想要安装到自己手机 ...
- 【Java EE 学习 24 下】【注解在数据库开发中的使用】【反射+注解+动态代理在事务中的应用service层】
一.使用注解可以解决JavaBean和数据库中表名不一致.字段名不一致.字段数量不一致的问题. 1.Sun公司给jdbc提供的注解 @Table.@Column.@Id.@OneToMany.@One ...
随机推荐
- ES6特性-带标签的模板字符串(tagged template)
tagged template: 加在模板字符串前面加一个标签(函数). let dessert = = '甜品' drink = '茶' let breakfast = kitchen`今天的早餐是 ...
- 【Codeforces Round #425 (Div. 2) A】Sasha and Sticks
[Link]: [Description] [Solution] 傻逼题; 获取n/k; 对n/k的奇偶性讨论一下就好 [NumberOf WA] 0 [Reviw] [Code] #include ...
- CCF模拟题 有趣的数
有趣的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都 ...
- c++中六种构造函数的实现以及9中情况下,构造函数的调用过程
六种构造函数的实现代码例如以下: #include<iostream> using namespace std; //c++中六种默认的构造函数 class Test { public: ...
- mysql通过字段凝视查找字段名称
有时候表的字段太多.仅仅是大致记得表的凝视,想通过字段凝视查找字段名称,能够用例如以下语句: SELECT COLUMN_NAME,column_comment FROM INFORMATION_SC ...
- vim 基础学习之查找
普通模式下 /->正向查找 n-向下查找 N-向上查找 ?->反向查找 N-向下查找 n-向上查找 <C-r><C-w> <C-r>-引用,例如引用寄存 ...
- elasticsearch index 之 Mapping
Lucene索引的一个特点就filed,索引以field组合.这一特点为索引和搜索提供了很大的灵活性.elasticsearch则在Lucene的基础上更近一步,它可以是 no scheme.实现这一 ...
- Css盒模型有哪几部分,标准盒模型和IE盒模型有哪些区别
首先介绍Css的盒模型也就是标准盒模型(BOX Model) 包含了 内容(content) 内边距(padding) 边框(border) 外边框(margin) 这是大家经常用到的,也是现在的标准 ...
- TensorFlow的学习
1.先判断python的版本(因为有些python版本自带pip,可以参考我写的对pip的认识的博客文章),选择是否安装pip,然后安装更新tensorflow如:sudo pip install - ...
- MathType下载和安装(与Visio搭配使用)
不多说,直接上干货! 福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号: 大数据躺过的坑 Java从入门到架构师 人工智能躺过的坑 ...