Android读取通讯录联系人

本文介绍如何在Android应用中封装通讯录读取功能,包括读取联系人姓名和电话号码的方法,并对号码进行格式化及验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Android开发中,读取通讯录算是一个比较常用的功能,很多app都会读取你的通讯录做一些匹配,或者从通讯录邀请好友等。虽然Android系统提供了接口让你读取通讯录,但在使用的过程中并不方便,因为需要你自己通过API去从数据库的表里面读。既然读取通讯录的这个功能这么常用,我们不妨封装一下。
在封装之前,我们先简单介绍一下Android系统中对联系人的存储方式。android系统中联系人的姓名和电话其实是分开存储的,不知道为什么要这么设计。在两个表当中,他们都有一个ID字段,如果知道了对应的ID,我们就能查到联系人的姓名和电话。
ContactsContract.CommonDataKinds.Phone.CONTENT_URI表中存储的电话号码字段,我们可以通过如下查询语句来获得通讯录中所有联系人的电话号码和ID字段:

Cursor phoneNumberCursor;
String[] phoneProjection = {ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.NUMBER};
phoneNumberCursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, phoneProjection, null, null, null);

ContactsContract.Contacts.CONTENT_URI表中存储的是联系人的姓名,通过下面的查询来获得联系人的姓名:

Cursor nameCursor;
String[] nameProjection = {ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};
nameCursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, nameProjection, null, null, null);

两个表靠_id字段关联,这样我们就可以利用两个表的信息来得到联系人的姓名和电话号码。
为了使用方便,我们可以定义联系人对象的数据结构,最常用的是姓名和电话字段,所以我们暂时只添加这两个字段:

class PersonInfo{
    String name;
    String phone;
}

根据定义好的联系人对象,从两个表中读取对应的字段构建PersonInfo对象

//正则表达式,判断是否是手机号
private boolean isMobilePhoneNumber(String phoneNumber) {

        Pattern pattern = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$");
        Matcher matcher = pattern.matcher(phoneNumber);
        return matcher.matches();
    }
//格式化电话号码结构
private String phoneNumberFormat(String rawPhoneNumber) {
        if (rawPhoneNumber == null || rawPhoneNumber.length() == 0 || rawPhoneNumber.length() < 11)
            return rawPhoneNumber;
        if (rawPhoneNumber.contains("-")) {
            rawPhoneNumber = rawPhoneNumber.replace("-", "");
        }
        if (rawPhoneNumber.contains(" ")) {
            rawPhoneNumber = rawPhoneNumber.replace(" ", "");
        }
        if (rawPhoneNumber.startsWith("+86")) {
            rawPhoneNumber = rawPhoneNumber.substring(3, rawPhoneNumber.length());
        }
        return rawPhoneNumber;
    }

//读取联系人电话号码
private void getPhoneNumList() {

        Cursor phoneNumberCursor;
        String[] phoneProjection = {ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.NUMBER};
        phoneNumberCursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, phoneProjection, null, null, null);
        if (phoneNumberCursor == null) {
            return;
        }
        if (phoneNumberCursor.getCount() == 0) {
            phoneNumberCursor.close();
            return;
        }
        if (phoneNumberCursor.moveToFirst()) {
            int idIndex = phoneNumberCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
            int phoneNumIndex = phoneNumberCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
            do {
                String idValue = phoneNumberCursor.getString(idIndex);
                String phoneNumValue = phoneNumberCursor.getString(phoneNumIndex);
                String processedNumValue = phoneNumberFormat(phoneNumValue);
                if (isMobilePhoneNumber(processedNumValue)) {
                    PersonInfo personInfo = new PersonInfo();
                    personInfo.setId(idValue);
                    personInfo.setPhoneNumber(processedNumValue);
                    personInfoArrayList.add(personInfo);
                }
            } while (phoneNumberCursor.moveToNext());
            if (!phoneNumberCursor.isClosed()) {
                phoneNumberCursor.close();
            }
        }
    }
//读取联系人姓名
private void buildPersonInfo() {

        Cursor nameCursor;
        String[] nameProjection = {ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};
        nameCursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, nameProjection, null, null, null);
        if (nameCursor == null) {
            return;
        }
        if (nameCursor.getCount() == 0) {
            nameCursor.close();
            return;
        }
        int _idIndex = nameCursor.getColumnIndex(ContactsContract.Contacts._ID);
        int _nameIndex = nameCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        for (PersonInfo obj : personInfoArrayList) {
            if (nameCursor.moveToFirst()) {
                do {
                    String _id = nameCursor.getString(_idIndex);
                    String _name = nameCursor.getString(_nameIndex);
                    if (obj.getId().equals(_id)) {
                        obj.setName(_name);
                    }
                } while (nameCursor.moveToNext());
            }
        }
        nameCursor.close();
    }

通过上面两个方法,我们就可以得到构建好的联系人列表,在处理的过程中,我们针对读取出来的手机号码进行了简单的格式化,去掉手机号中除了数字之外的不必要字符,同时针对处理后的号码进行正则匹配,保证读取出来的都是手机号码。
核心的代码就是从两个表中读取对应的信息,然后进行组合。通讯录的模块比较常用,我们可以将上述实现封装成一个类,对外只提供一个接口,直接返回personInfoArrayList对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值