10.Android通讯录-联系人查询

相关内容:

  1. 联系人数据库结构
  2. 内容提供者(略)

官方文档:https://developer.android.com/guide/topics/providers/contacts-provider.html

1.数据库结构

相关表共三个:Contacts、RawContacts、Data

1.ContactsContract.Contacts 原始联系表
---- URI: ContactsContract.Contacts.CONTENT_URI
表示不同联系人的行,基于聚合的原始联系人行。

字段说明:
1.Contacts.CONTENT_DIRECTORY | Constant Value:"photo"         |
2.Contacts.DISPLAY_PHOTO:    | Constant Value:"display_photo" | 全尺寸照片
3.Contacts.PHOTO:            | Constant Value:"data15"        | 照片缩略图
4.Contacts.PHOTO_FILE_ID:    | Constant Value:"data14"        | 全尺寸照片的文件ID (用此查询,See: ContactsContract.DisplayPhoto)

2.ContactsContract.RawContacts联系人数据摘要表
---- URI: ContactsContract.RawContacts.CONTENT_URI
包含联系人数据摘要的行,针对特定用户帐户和类型。

字段说明:
1.RawContacts._ID  - long                |  id   不解释 ,永远唯一
2.RawContacts.CONTACT_ID  - long
3.RawContacts.AGGREGATION_MODE - int
4.RawContacts.DELETED - int              |  是否删除  0:正常 , 1:删除
5.RawContacts.TIMES_CONTACTED  - int     |  联系的次数
6.RawContacts.LAST_TIME_CONTACTED - long |  最近联系时间
7.RawContacts.STARRED -int               |  是否是常用联系人  0:不是 ,1:是
8.RawContacts.CUSTOM_RINGTONE  - String  |  自定义铃声
9.RawContacts.SEND_TO_VOICEMAIL - int    |  是否使用语音信息  0:不是 ,1:是
10.RawContacts.ACCOUNT_NAME - String     |  账户名称 与ACCOUNT_TYPE对应
11.RawContacts.ACCOUNT_TYPE  - String    |  账户类型 比如:Gmail 
12.RawContacts.DATA_SET - String         |  账户数据
13.RawContacts.SOURCE_ID - String        |   
14.RawContacts.VERSION - int             |  当前版本号
15.RawContacts.DIRTY - int               |  标记此条记录是否更改过

3.ContactsContract.Data 联系人详细信息表
---- URI: ContactsContract.Data.CONTENT_URI 或 ContactsContract.Phone.CONTENT_URI
包含原始联系人详细信息(例如电子邮件地址或电话号码)的行。

字段说明:
1.Data._ID - long             
2.Data.MIMETYPE - String       |  数据类型,详细见下段
3.Data.RAW_CONTACT_ID - long   |  同RawContacts.CONTACT_ID  
4.Data.IS_PRIMARY - int        |  标记重要  0 or 1
5.Data.IS_SUPER_PRIMARY - int  |  默认使用此条数据 0 or 1
6.Data.DATA_VERSION  - int     |  数据版本
7.Data.Data1                   |  与MIMETYPE有关,当为Phone.CONTENT_ITEM_TYPE时,Data1 就是电话号码
8.Data.Data2~~Data.Data15     

2.Data.MIMETYPE  参数列表 : 
StructuredName.CONTENT_ITEM_TYPE
Phone.CONTENT_ITEM_TYPE
Email.CONTENT_ITEM_TYPE
Photo.CONTENT_ITEM_TYPE
Organization.CONTENT_ITEM_TYPE
Im.CONTENT_ITEM_TYPE
Nickname.CONTENT_ITEM_TYPE
Note.CONTENT_ITEM_TYPE
StructuredPostal.CONTENT_ITEM_TYPE
GroupMembership.CONTENT_ITEM_TYPE
Website.CONTENT_ITEM_TYPE
Event.CONTENT_ITEM_TYPE
Relation.CONTENT_ITEM_TYPE
SipAddress.CONTENT_ITEM_TYPE

2.查询联系人列表

知道表结构后就可以很快的查取数据了,这里不讲内容提供者如何查询,直接上代码
重点在getContactsList() 和 getContactList() 两个方法
getContactsList() 返回数据结构:ContactsBean(String name, List number)的List集合
getContactList() 返回数据结构 :ContactBean(String name, String number)的List集合

  • 看情况选择:getContactsList() 数据结构清晰 ,getContactList() 速度快

查询到数据后应注意:

  1. 查询后的联系人姓名可能为空
  2. 查询后的电话号码可能有空格
  3. 查询后的电话号码可能为空
  4. 查询后的电话号码可能不是数字
    下面代码已经做了相应处理, 代码仅供参考,暂不考虑性能,自行优化(静态Bean类)

获取联系人列表流程

  1. 通过ContentResolver查询数据库, Uri可根据上表合理选择(此处选择Contacts表的uri),得到返回的cusor
  2. 遍历cusor获取所有的联系人姓名
  3. 根据联系人姓名查询其拥有的联系电话(不止一个),(此处选择Data表)
public static List getContactsList(Context context) {
        Logger.d("SMSHelper", "-----------SMSHelper#getContactsList()----------");
        Logger.d("SMSHelper", "开始查询 Contacts 表");
        List list = new ArrayList();
        ContactsBean bean = null;
        ContentResolver resolver = context.getContentResolver();
        Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

        if (cursor == null && cursor.getCount() <= 0) {
            return null;
        }
        Logger.d("SMSHelper", "cursor.getCount():" + cursor.getCount());

        while (cursor.moveToNext()) {
            bean = new ContactsBean();

            String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));//姓名

            wirteNumbers(resolver, name, bean);
            list.add(bean);
        }
        cursor.close();
        return list;
    }

   /**
     * 根据联系人姓名查询电话
     * 并写入
     */
    private static void wirteNumbers(final ContentResolver contentResolver, String name, final ContactsBean bean) {
        Logger.d("SMSHelper", "开始查询 Data 表 : 查询联系人:" + name);
        Cursor dataCursor = contentResolver.query(ContactsContract.Data.CONTENT_URI,
                new String[]{ContactsContract.Data.DATA1},
                ContactsContract.Data.DISPLAY_NAME + "= ? ",
                new String[]{name}, null);
        if (dataCursor == null) {
            Logger.w("SMSHelper", "dataCursor == null ");
            return;
        }
        if (dataCursor.getCount() > 0) {
            bean.setName(name);
            Logger.w("SMSHelper", " 电话信息 -- size: " + dataCursor.getCount());
            while (dataCursor.moveToNext()) {
                String number = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DATA1));
                if (TextUtils.isEmpty(number) || !TextUtils.isDigitsOnly(number = number.replace(" ", ""))) {
                    Logger.w("SMSHelper", " 电话信息(异常) -- number: " + number);
                    continue;
                }
                bean.getNumList().add(number);
                Logger.w("SMSHelper", " 电话信息 -- number: " + number);
            }
            dataCursor.close();
        } else {
            Logger.w("SMSHelper", " 无电话信息 -- name: " + name);
        }
        return;
    }

完整代码

package app.utils;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.telephony.SmsManager;
import android.text.TextUtils;

import com.google.common.collect.Lists;

/**
 * 短信电话相关工具类
* 目录:
* 1.发送短信 sendSMS()
* 2.拨打电话短信 callPhone()
* 3.获取所有短信记录getAllSms()
* 4.获取所有联系人getContactsList()
* 5.获取所有联系人getContactList() : 与第4条所生成的数据结构不同
* :使用时请添加相关权限 * * @author 赵LW QQ:739043667 */ public class SMSHelper { /** * 发送短信 (需要权限SMS_Send) * * @param num 电话 * @param text 短信内容 */ public static void sendSMS(String num, String text) { SmsManager.getDefault().sendTextMessage(num, null, text, null, null); } public static void callPhone(Context context, String num) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:" + num)); // 开启系统拨号器 context.startActivity(intent); } /** * 获取所有联系人 需要权限 * * 数据结构:ContactBean(String displayName, String numList) * * @param * @return */ public static List getContactList(Context context) { Logger.d("SMSHelper", "-----------SMSHelper#getContactList()----------"); Logger.d("SMSHelper", "开始查询 Data 表"); List list = new ArrayList(); ContactsContract.Data._ID ContentResolver resolver = context.getContentResolver(); Cursor cursor = resolver.query(ContactsContract.Data.CONTENT_URI, null, null, null, null); if (cursor == null && cursor.getCount() <= 0) { return null; } Logger.d("SMSHelper", "cursor.getCount():" + cursor.getCount()); while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)); String number = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.DATA1)); //数据清洗 if (TextUtils.isEmpty(number)) { continue; } if (!TextUtils.isDigitsOnly(number = number.replace(" ", ""))) { continue; } if (TextUtils.isEmpty(name)) { name = number; } list.add(new ContactBean(name, number)); } cursor.close(); return list; } /** * 获取所有联系人 * 数据结构:ContactsBean(String displayName, List numList) *

* 需要权限: * * * @param * @return List */ public static List getContactsList(Context context) { Logger.d("SMSHelper", "-----------SMSHelper#getContactsList()----------"); Logger.d("SMSHelper", "开始查询 Contacts 表"); List list = new ArrayList(); ContactsBean bean = null; ContentResolver resolver = context.getContentResolver(); Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); if (cursor == null && cursor.getCount() <= 0) { return null; } Logger.d("SMSHelper", "cursor.getCount():" + cursor.getCount()); while (cursor.moveToNext()) { bean = new ContactsBean(); String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));//姓名 wirteNumbers(resolver, name, bean); list.add(bean); } cursor.close(); return list; } /** * 根据联系人姓名查询电话 * 并写入 */ private static void wirteNumbers(final ContentResolver contentResolver, String name, final ContactsBean bean) { Logger.d("SMSHelper", "开始查询 Data 表 : 查询联系人:" + name); Cursor dataCursor = contentResolver.query(ContactsContract.Data.CONTENT_URI, new String[]{ContactsContract.Data.DATA1}, ContactsContract.Data.DISPLAY_NAME + "= ? ", new String[]{name}, null); if (dataCursor == null) { Logger.w("SMSHelper", "dataCursor == null "); return; } if (dataCursor.getCount() > 0) { bean.setName(name); Logger.w("SMSHelper", " 电话信息 -- size: " + dataCursor.getCount()); while (dataCursor.moveToNext()) { String number = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DATA1)); if (TextUtils.isEmpty(number) || !TextUtils.isDigitsOnly(number = number.replace(" ", ""))) { Logger.w("SMSHelper", " 电话信息(异常) -- number: " + number); continue; } bean.getNumList().add(number); Logger.w("SMSHelper", " 电话信息 -- number: " + number); } dataCursor.close(); } else { Logger.w("SMSHelper", " 无电话信息 -- name: " + name); } return; } /** * 获取短信记录 (需要bean: Smsinfo.java和 Read_SMS权限) *

* * * @return List * @author zlw QQ:739043667 */ public static List getAllSms(Context context) { List smsinfos = new ArrayList(); Uri uri = Uri.parse("content://sms/"); ContentResolver resolver = context.getContentResolver(); Cursor cursor = resolver.query(uri, new String[]{"address", "date", "type", "body"}, null, null, null); SmsInfo smsinfo = null; while (cursor.moveToNext()) { String address = cursor.getString(0); String date = cursor.getString(1); String type = cursor.getString(2); String body = cursor.getString(3); smsinfo = new SmsInfo(address, date, type, body); smsinfos.add(smsinfo); } cursor.close(); return smsinfos; } /** * 短信信息Bean 类 * * @param * @author zlw QQ:739043667 * @return */ public static class SmsInfo { String address; String date; String type; String body; public SmsInfo(String address, String date, String type, String body) { super(); this.address = address; this.date = date; this.type = type; this.body = body; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } } /** * 联系人集合Bean类 */ public static class ContactsBean { private String name; private List numList; public String getName() { return name; } public void setName(String name) { this.name = name; } public List getNumList() { return numList; } public void setNumList(List numList) { this.numList = numList; } public ContactsBean() { numList = Lists.newArrayList(); } public ContactsBean(String displayName, List numList) { super(); this.name = displayName; if (numList == null) { this.numList = Lists.newArrayList(); } else { this.numList = numList; } } @Override public String toString() { return "ContactsBean [name=" + name + ", numList=" + numList + "]"; } } /** * 联系人Bean类 */ public static class ContactBean { private String name; private String number; public ContactBean() { } public ContactBean(String name, String number) { this.name = name; this.number = number; } public String getName() { return name; } @Override public String toString() { return "ContactBean{" + "name='" + name + '\'' + ", number='" + number + '\'' + '}'; } public void setName(String name) { this.name = name; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } } }

你可能感兴趣的:(10.Android通讯录-联系人查询)