Group添加联系人时,Contacts默认设计不会过滤已分组的联系人。之前看到小米,oppo都做过过滤,一直懒得改。

最近客户要求group添加成员时,不显示已分组的联系人,故记录一下实现过程。

public void pickMembers() {
Intent intent = new Intent(MultiPickContactActivity.ACTION_MULTI_PICK);
intent.putExtra(MultiPickContactActivity.IS_CONTACT,true);
//add by antoon, for group pick contacts
intent.putExtra(MultiPickContactActivity.IS_GROUP_MEMBER_PICK,true);//增加标记,表示Contacts多选界面进行的是group pick member
//end add
intent.setClass(mActivity, MultiPickContactActivity.class);
ContactListFilter filter = new ContactListFilter(ContactListFilter.FILTER_TYPE_ACCOUNT,
PhoneAccountType.ACCOUNT_TYPE, SimContactsConstants.PHONE_NAME, null, null);
intent.putExtra(AccountFilterActivity.KEY_EXTRA_CONTACT_LIST_FILTER, filter);
mActivity.startActivityForResult(intent, CODE_PICK_MEMBER);
}

MultiPickContactActivity处理

//add by antoon, for group pick contacts
public static final String IS_GROUP_MEMBER_PICK ="is_group_pick_contact"; public void onCreate(Bundle savedInstanceState) {
......
else if (ACTION_MULTI_PICK.equals(action)) {
if (!isContact) {
mMode = MODE_DEFAULT_PHONE;
} else {
mMode = MODE_DEFAULT_CONTACT;
//add by antoon, for group pick contacts
if(getIntent().getBooleanExtra(IS_GROUP_MEMBER_PICK, false))
setTitle(R.string.ungrouped_contacts);
//end add
}
}
......
}
public void startQuery() {
Uri uri = getUriToQuery();
ContactListFilter filter = (ContactListFilter) getIntent().getExtra(
AccountFilterActivity.KEY_EXTRA_CONTACT_LIST_FILTER);
if (filter != null) {
if (filter.filterType == ContactListFilter.FILTER_TYPE_ACCOUNT) {
// We should exclude the invisiable contacts.
uri = uri.buildUpon().appendQueryParameter(RawContacts.ACCOUNT_NAME,
filter.accountName).appendQueryParameter(RawContacts.ACCOUNT_TYPE,
filter.accountType)
.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
ContactsContract.Directory.DEFAULT+"").build(); //add by antoon, for group pick contacts
if(getIntent().getBooleanExtra(IS_GROUP_MEMBER_PICK, false)){
uri = uri.buildUpon().appendQueryParameter(IS_GROUP_MEMBER_PICK, "true").build();//传递查询条件参数给ContactsProvider2使用
}
//end add } else if (filter.filterType == ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS) {
// Do not query sim contacts in airplane mode.
if (!isShowSIM()) {
uri = uri.buildUpon().appendQueryParameter(RawContacts.ACCOUNT_TYPE,
SimAccountType.ACCOUNT_TYPE)
.appendQueryParameter(DefaultContactListAdapter.WITHOUT_SIM_FLAG,
"true").build();
}
}
}
String[] projection = getProjectionForQuery();
String selection = getSelectionForQuery();
String[] selectionArgs = getSelectionArgsForQuery();
mQueryHandler.startQuery(QUERY_TOKEN, null, uri, projection, selection,
selectionArgs, getSortOrder(projection));
}

最关键是在ContactsProvider2中增加数据库查询判断条件。

protected Cursor queryLocal(final Uri uri, final String[] projection, String selection,
String[] selectionArgs, String sortOrder, final long directoryId,
final CancellationSignal cancellationSignal) { final SQLiteDatabase db = mDbHelper.get().getReadableDatabase(); SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
...... final int match = sUriMatcher.match(uri);
switch (match) {
case SYNCSTATE:
case PROFILE_SYNCSTATE:
return mDbHelper.get().getSyncState().query(db, projection, selection,
selectionArgs, sortOrder); case CONTACTS: {
setTablesAndProjectionMapForContacts(qb, uri, projection);
appendLocalDirectoryAndAccountSelectionIfNeeded(qb, directoryId, uri);//设置查询条件,where字句
break;
}
private void appendLocalDirectoryAndAccountSelectionIfNeeded(SQLiteQueryBuilder qb,
long directoryId, Uri uri) {
final StringBuilder sb = new StringBuilder();
if (directoryId == Directory.DEFAULT) {
sb.append("(" + Contacts._ID + " IN " + Tables.DEFAULT_DIRECTORY + ")");
} else if (directoryId == Directory.LOCAL_INVISIBLE){
sb.append("(" + Contacts._ID + " NOT IN " + Tables.DEFAULT_DIRECTORY + ")");
} else {
sb.append("(1)");
} ...... //add by nxd 2015-5-18, for local group pick contacts
String isGroupMemPick = getQueryParameter(uri, IS_GROUP_MEMBER_PICK );
if("true".equals(isGroupMemPick)){
sb.append(" AND (" + Contacts.NAME_RAW_CONTACT_ID + " NOT IN (" +
"SELECT " + Data.RAW_CONTACT_ID + " FROM "
+ Tables.DATA +
" WHERE " + Data.MIMETYPE + "_id =("
                      + "SELECT _id FROM mimetypes "
                      + "WHERE mimetype='vnd.android.cursor.item/local-groups')))");// mimetype_id=local-groups对应id,说明已分组
        }
//end add
qb.appendWhere(sb.toString());
}

Contacts群组添加成员,多选列表过滤已添加数据的更多相关文章

  1. mssql sqlserver 使用sql脚本获取群组后,按时间排序(asc)第一条数据的方法分享

    摘要: 下文讲述使用sql脚本,获取群组后记录的第一条数据业务场景说明: 学校教务处要求统计: 每次作业,最早提交的学生名单下文通过举例的方式,记录此次脚本编写方法,方便以后备查,如下所示: 实现思路 ...

  2. 1 实现添加功能 1.1 定义一个学员类(Student),在Student类中定义姓名、性别和年龄属性,定义有 参数的构造方法来初始化所以的成员属性 1.2 创建学员类对象来存放学员信息,并且为每一个学生对象添加的相应的编号。并将 学员类对象添加到Map<Integer,Student>集合中 1.3 添加完成后,显示所有已添加的学员姓名 1.4 限制年龄文本框只能输入正整数,否则的会采

    学生类 package com.lanxi.demo1_3; public class Student { private String name; private String sex; priva ...

  3. #Linux学习笔记# Linux文件的所有者、群组和其他人

    1.关于所有者.群组和其他人 在Linux系统中,每个文件都具有User.Group和Others三种身份的权限配置.那这三种身份分别表示什么意思呢?配置这三种身份的权限有啥意义呢? (1)文件所有者 ...

  4. apache Subversion 直接支持LDAP域群组

    如果你的Subversion已经用apache的ldap支持用户认证功能,你是否常常在想,既然都用ldap支持认证,为什么不直接支持域群组, 反而在authz文件里面一个一个的手工定义,或者有人用脚本 ...

  5. JBoss 系列十七:使用JGroups构建块MessageDispatcher 构建群组通信应用

    内容概要 本部分说明JGroups构建块接口MessageDispatcher,具体提供一个简单示例来说明如何使用JGroups构建块MessageDispatcher 构建群组通信应用 示例描述 构 ...

  6. chmod a+w . 权限控制 su、sudo 修改文件所有者和文件所在组 添加用户到sudoer列表中 当前用户信息

    对当前目录对所有用户开放读写权限 chmod a+r . $ sudo chmod -R a+w /usr/lib/python2.7 所有用户添加文件的写权限 [linux]su.sudo.sudo ...

  7. 添加群组表AppGroup和群组详细表AppGroupDetails

    添加群组表AppGroup和群组详细表AppGroupDetails CREATE TABLE [dbo].[AppGroup]( ) NOT NULL PRIMARY KEY, ) NOT NULL ...

  8. XMPP系列(七)---获取群组列表

    上一篇介绍了如何创建群组,这一篇就介绍一下,如何获取自己的群组列表. 在上一篇有提到,如果我们创建的群组是公共的群组,那么获取自己的群组列表时,会获取到自己的群组列表和那些公共的群组.而实际做社交的应 ...

  9. JBoss 系列十九:使用JGroups构建块RspFilter对群组通信返回消息进行过滤

    内容概述 本部分说明JGroups构建块接口RspFilter,具体提供一个简单示例来说明如何使用JGroups构建块RspFilter对群组通信返回消息进行过滤. 示例描述 我们知道构建块基于通道之 ...

随机推荐

  1. 封装实现一个自己的tabbar

    实现效果:

  2. linux命令行与shell脚本编程大全---更多bash shell命令

    进程状态:0代表正在运行:S代表在休眠:R代表可运行,正等待运行:Z代表僵化,进程已经结束但父进程已不存在:T代表停止. 查看有那些进程运行:ps  -ef 基本的linux文件系统: 1.ext文件 ...

  3. 我的ZJ解题心得

    想要学好程序设计第一是要养成你的编程思维,也就是你对编程的一种概念和思维定式,长期的解题会让你产生解题经验进而形成一种思维定式,比如看到一个题目就立即想出这题要用什么方法解题这样.编程思维我认为还包括 ...

  4. Xcode取消某条警告

      [Xcode取消某条警告] 像下面这样,把双引号“”内的内容替成实际的警告类型即可. #pragma clang diagnostic push #pragma clang diagnostic ...

  5. 安卓:drawable

    <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http: ...

  6. Zepto源码

    // Zepto.js // (c) 2010-2016 Thomas Fuchs // Zepto.js may be freely distributed under the MIT licens ...

  7. json格式的时间转换

    //yyyy-MM-dd HH:mm:SS function JsonDateToDate(jsondate) { var date = new Date(parseInt(jsondate.repl ...

  8. leetcode 137

    137. Single Number II Given an array of integers, every element appears three times except for one. ...

  9. 使用percona-xtrabackup实现对线上zabbix监控系统数据库mariadb5.5.47的主从同步

    使用percona-xtrabackup实现对线上zabbix监控系统数据库的主从同步 业务背景: zabbix3.0.4是业务的主要监控,部署在一台单机中,为避免数据丢失先对其做数据主从同步,因主数 ...

  10. "Asp.Net Web Api MediaTypeFormatter Error for x-www-formurlencoded data" 解决方法

    遇到标题中所说的问题原因是使用 jQuery AJAX 以 POST 方式调用 Asp.Net Web API .解决办法请看以下代码中有注释的部分. public static class WebA ...