Android(安卓)快速获取用户通信录联系人 姓名、电话、首字母 及排序
16lz
2021-01-24
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手机游戏开发知识点总结
- 纪念我开始学习android的文章
- Android(安卓)dp方式的屏幕适配工具使用(bat批处理方式)
- 神奇的 Magisk
- 对手机厂商来说,“Android”并不是一个功能
- 为手机定制ROM
- Android(安卓)硬解码 MediaCodec 遇到的(部分手机绿屏)API21
- TL-android通过USB使用真机调试程序