Android开发之获取手机通讯录,按A-Z顺序排列,并解决Fortify代码扫描可能出现的CodeDex问题
最近公司需要获取手机通讯录,并按照A-Z顺序排列,查了些资料好些写的比较复杂,实际上在用cursor.query查找通讯录时,有排序的参数。
具体实现过程如下:
首先,在AndroidManifest.xml文件中添加读取联系人的权限:
<uses-permission android:name="android.permission.READ_CONTACTS" />
然后再新建一个类,用于通讯录的数据封装,由于一个人可能有多个电话号码的情况,号码用List集合来写
public class ContactListInfo { private String name; private List<String> phoneNumList; private String thumb; private String contactId; public ContactListInfo() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<String> getPhoneNumList() { return phoneNumList; } public void setPhoneNumList(List<String> phoneNumList) { this.phoneNumList = phoneNumList; } public String getThumb() { return thumb; } public void setThumb(String thumb) { this.thumb = thumb; } public String getContactId() { return contactId; } public void setContactId(String contactId) { this.contactId = contactId; } }
获取通讯录主要是用 context.getContentResolver()方法来获得通讯录 ,这个方法返回一个游标的数据类型,通过moveToNext()方法来获取所有的手机号码信息,将获得的手机号码信息放入列表中。
方法如下:
private void getContactPhoneNumber() { ContentResolver contentResolver = getContentResolver(); // 获得所有的联系人 Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); if (cursor == null) { return; } // 循环遍历 if (cursor.moveToNext()) { int idColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID); int displayNameColumn = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); int thumbColumn = cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI); do { ContactListInfo listInfo = new ContactListInfo(); String contactId = cursor.getString(idColumn);// 获得联系人的ID号 String disPlayName = cursor.getString(displayNameColumn);// 获得联系人姓名 String thumb = cursor.getString(thumbColumn);// 获得联系人头像 // 查看该联系人有多少个电话号码。如果没有这返回值为0 int phoneCount = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)); //在联系人数量不为空的情况下执行 if (phoneCount > 0) { // 获得联系人的电话号码列表 Cursor phonesCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null); List<String> list3 = new ArrayList<>(); if (phonesCursor.moveToFirst()) { do { // 遍历所有的电话号码 String phoneNumber = phonesCursor.getString(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); list3.add(phoneNumber); } while (phonesCursor.moveToNext()); } //在电话号码不为空的情况下设置添加数据 listInfo.setContactId(contactId); listInfo.setName(disPlayName); listInfo.setThumb(thumb); listInfo.setPhoneNumList(list3); } infoAllPhoneList.add(listInfo); } while (cursor.moveToNext()); } cursor.close(); if (infoAllPhoneList != null && infoAllPhoneList.size() > 0) { adapter.setData(infoAllPhoneList); } }
在contentResolver.query方法中有五个参数,分别是
@RecentlyNonNull Uri uri, @RecentlyNullable String[] projection, @RecentlyNullable String selection, @RecentlyNullable String[] selectionArgs, @RecentlyNullable String sortOrder
第一个参数,uri,这个参数就是查找通讯录的URI;
第二个参数,projection,这个参数告诉Provider要返回的内容(列Column),null 为所有行;
第三个参数,selection,设置条件,相当于SQL语句中的where,例:"packageName = ?"
第四个参数,selectionArgs,这个参数是要配合第三个参数使用的。例:new String[]{packageName}
第五个参数,sortOrder,按照什么进行排序,相当于SQL语句中的Order by
从参数中可以看到,如果需要A-Z排序,则将contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);的最后一个参数变为:ContactsContract.CommonDataKinds.Phone.SORT_KEY_PRIMARY 就行。
不同公司有不同代码检测工具,配置的方法和条件也不同,如果用Fortify代码扫描 在上述 获取联系人的电话号码 时可能会出现CodeDEX问题。在我们公司就出现这个问题了,经查找各种原因并看Google上都是这样的写法,不知道在我们公司怎么就出现CodeDEX问题编译不通过,最后只能换种方法来写。
方法如下,在获得联系人的电话号码列表时弃用
Cursor phonesCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);
并将获取通讯录的数据改为一条条获取然后再重新整合,具体代码如下:
private void getContactList() {
ContentResolver cr = getContentResolver(); Cursor cursor = cr.query(PHONE_URI, new String[]{CONTACT_ID, NAME, NUM, THUMB}, null, null, ContactsContract.CommonDataKinds.Phone.SORT_KEY_PRIMARY); if (cursor == null) { return; } while (cursor.moveToNext()) { String contact_id = cursor.getString(cursor.getColumnIndex(CONTACT_ID)); if (contact_id != null) { ContactInfo info = new ContactInfo(cursor.getString(cursor.getColumnIndex(CONTACT_ID)), cursor.getString(cursor.getColumnIndex(NAME)), cursor.getString(cursor.getColumnIndex(NUM)), cursor.getString(cursor.getColumnIndex(THUMB))); infoList.add(info); } } cursor.close(); if (infoList != null && infoList.size() != 0) { Map<String, ContactListInfo> groupMap = new HashMap<>(); List<String> idList = new ArrayList<>(); infoAllPhoneList.clear(); if (groupMap != null) { for (ContactInfo contactInfo : infoList) { if (groupMap.containsKey(contactInfo.getContactId())) { groupMap.get(contactInfo.getContactId()).getPhoneNumList() .add(contactInfo.getPhoneNum().trim().replace(" ", "")); } else { idList.add(contactInfo.getContactId());//存储ContactId,以便后期根据id获取value存入List集合中 ContactListInfo listInfo = new ContactListInfo(); listInfo.setContactId(contactInfo.getContactId()); listInfo.setName(contactInfo.getName().trim()); listInfo.setThumb(contactInfo.getThumb()); List<String> list3 = new ArrayList<>(); list3.add(contactInfo.getPhoneNum().trim().replace(" ", "")); listInfo.setPhoneNumList(list3); groupMap.put(contactInfo.getContactId(), listInfo); } } int size = groupMap.size(); for (int j = 0; j < size; j++) { infoAllPhoneList.add(groupMap.get(idList.get(j))); } } } if (infoAllPhoneList != null && infoAllPhoneList.size() > 0) { adapter.setData(infoAllPhoneList); } }
其中ContactInfo类为:
public class ContactInfo { private String name; private String phoneNum; private String thumb; private String contactId; public ContactInfo(String contactId, String name, String phoneNum, String thumb) { this.contactId = contactId; this.name = name; this.phoneNum = phoneNum; this.thumb = thumb; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhoneNum() { return phoneNum; } public void setPhoneNum(String phoneNum) { this.phoneNum = phoneNum; } public String getThumb() { return thumb; } public void setThumb(String thumb) { this.thumb = thumb; } public String getContactId() { return contactId; } public void setContactId(String contactId) { this.contactId = contactId; } }
- Android设备获取扫码枪扫描的内容与可能遇到的问题解决
- Android开发中调用系统相册上传图片到服务器OPPO等部分手机上出现短暂的显示桌面问题的解决方法
- 【ArcGIS Android开发】重启Eclipse后可能出现两个问题
- Google Maps API v2 android版本开发 国内手机不支持google play Service相关问题解决--图文教程
- 【COCOS2DX-LUA 脚本开发之十三】解决lua项目编译Android出现get data from file failed以及路径等问题
- Android开发中ANR问题出现及解决
- 解决android手机刷新后tabs选项卡出现在浏览器上边的问题
- ubuntu12.04下android连接真机开发找不到手机问题解决
- 解决Mac上Android开发时adb连接不到手机问题
- 解决Android手机自带内部存储路径存在但是却获取不到内容的问题
- 解决main.out.xml文件出现问题---android开发
- android开发代码顺序影响程序运行的问题
- 关于android开发出现“你的手机上未安装应用程序”问题
- android开发出现R cannot be resolved to a variable 问题解决办法之一
- Android 获取手机通讯录信息 — 头像、姓名和A-Z的快速查询
- Mac下Eclipse+ADT开发Android工程出现"Errors running builder"问题解决
- adb连接Android 4.2.2版本手机时出现offline或unauthorized问题的解决方法
- 配置android开发环境时出现eclipse获取不到ADT的解决方法
- 解决Android4.4及以上系统获取系统图片失败的问题,例如华为手机,调系统图库的时候就出现异常
- android拍照后图片路径的获取(解决不同手机存在拍照后旋转的问题)