Android 快速获取用户通信录联系人 姓名、电话、首字母 及排序

Android快速获取通信录列表、首字母、并排序

关键点

  • 只使用一个Cursor 同时获取 手机号、首字母、并排序 (200多联系人大概在20ms左右)
  • 首字母的获取根据不同版本获取方式不同,在Android5.0以上使用 phonebook_label字段,在5.0 以下使用 ContactsContract.Contacts.SORT_KEY_PRIMARY也就是sort_key字段, 国内部分机型发现在 5.0以上 并不存在 phonebook_label字段,根据这种情况坐做了适配。
  • 实际开发中无法完美覆盖所有机型,所以需要对可能的异常情况做 catch (比如手机本地没有用户首字母)

关键代码

public class ContactInfoUtils {

    private ContactInfoUtils(){};

    /**
     * 从手机通信录中 检索 用户联系人 姓名及手机号信息
     * @param context
     * @return
     */

    /**
     * 从 手机本地通信录 加载 联系人信息
     * @param context
     * @return
     */
    public static List loadContactInfo(Context context){
        List contactInfos = new ArrayList<>();
        Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        ContentResolver reslover = context.getContentResolver();

        String[] projection = {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Contacts.SORT_KEY_PRIMARY};

        if (Build.VERSION.SDK_INT >= 19){ //5.0 以上 ,sort_key_primary 是原汉字,排序字段变成了 phonebook_label
            projection[2] = "phonebook_label";
            Cursor testCursor = null;
            try {
                testCursor = reslover.query(uri, new String[]{"phonebook_label"}, null, null, null);
            }catch (Exception e){
                //有些手机厂商 没有 phonebook_label 这个字段
                projection[2] = ContactsContract.Contacts.SORT_KEY_PRIMARY;
            }finally {
                if (testCursor!=null){
                    testCursor.close();
                }
            }

        }

        Cursor cursor = reslover.query(uri, projection, null, null,
                projection[2]);


        if (cursor == null)
            return Collections.EMPTY_LIST;

        while (cursor.moveToNext()) {

            // 联系人姓名
            String name = cursor
                    .getString(0);

            // 获得联系人手机号 ,过滤空格 和"-"符号
            String phoneNumber = cursor.getString(1)
                    .replaceAll(" ","")
                    .replaceAll("-","");
            if (phoneNumber.length() > 11){
                phoneNumber = phoneNumber.substring(phoneNumber.length()-11,phoneNumber.length());
            }

            //只取有 name 的情况 (根据自己的业务需求来)
            if (name == null || !isValidPhone(phoneNumber))
                continue;

            // Sort Key,读取的联系人按照姓名从 A->Z 排序分组。
            String sort_key_primary = cursor
                    .getString(2);

            ContactInfo contactInfo = new ContactInfo();
            contactInfo.setUserName(name);
            String firstLetterOfName = null;

            if (name.length() > 0){
                //如果 手机本地有 优先取手机的 首字母
                if (sort_key_primary!=null && sort_key_primary.length()>0){
                    sort_key_primary = sort_key_primary.toUpperCase();
                    if (sort_key_primary.charAt(0) >='A' && sort_key_primary.charAt(0) <='Z'){
                        firstLetterOfName = sort_key_primary.substring(0,1);
                    }
                }else {//如果手机本地没有保存首字母,则使用第三方控件自己获取
                    String selling = CharacterParser.convert(name.substring(0, 1));

                    if (selling!= null && selling.length()>0){
                        String character = selling.substring(0, 1).toUpperCase();
                        if (character.charAt(0)>='A' && character.charAt(0)<='Z'){
                            firstLetterOfName = character;
                        }
                    }
                }
            }


            if (firstLetterOfName == null)
                firstLetterOfName ="#";

            contactInfo.setFirstLetterOfName(firstLetterOfName);

            contactInfo.setMobilePhone(phoneNumber);

            if (contactInfo.getUserName()!=null && contactInfo.getMobilePhone()!=null){
                contactInfos.add(contactInfo);
            }
        }
        cursor.close();
        return contactInfos;
    }

    /**
     * 提供 类似 手机通信录的 排序规则 ,保证将# 排在最下面
     */
    private static Comparator  COMPARE_LIKE_PHONE_CONTACTS = new Comparator (){
        private int compareUserName(ContactInfo lhs,ContactInfo rhs){
            if (lhs.getUserName() == null && rhs.getUserName() == null)
                return 0;
            else if (lhs.getUserName() == null)
                return -1;
            else if (rhs.getUserName() == null)
                return 1;
            else return lhs.getUserName().compareTo(rhs.getUserName());
        }


        @Override
        public int compare(ContactInfo lhs, ContactInfo rhs) {
            int result;
            //先比较 首字母大小

            // 因为 默认的 "#" 符号比较 char code 是 比 'A'小的,所以 需要特殊处理 '#'的情况
            if (lhs.getFirstLetterOfName().equals("#")){
                if (!rhs.getFirstLetterOfName().equals("#"))
                    return 1;
                else
                    return compareUserName(lhs,rhs);
            }else if (rhs.getFirstLetterOfName().equals("#")){
                return -1;
            }
            result = lhs.getFirstLetterOfName().compareTo(rhs.getFirstLetterOfName());
            //如果首字母大小一样,则 使用 姓名,比较规则 是Java默认的 字符串比较规则
            if (result == 0){
                return compareUserName(lhs,rhs);
            }
            return result;
        }
    };
}

你可能感兴趣的:(----,Android项目开发实践,--Android)