原来读取联系人都是,先从Contacts表中读取所有联系人的contact_id,在通过contact_id去raw_contacts表中读取raw_contact_id,再有raw_contact_id到data表读取所有信息,这是一个循环套循环的过程,当联系人数量超过200条时,读取速度就不行了;最近在网上看到一篇资料:http://www.cnblogs.com/error404/archive/2013/03/12/2956123.html;
介绍了查询
android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI时所查询的内容,发现通过该url可以查找几乎所有的信息,避免循环嵌套,大幅度提醒速度;200条联系人的速度基本在600ms,完全可以接受;
获取Phone Number的URI:
contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);编译后的内容:
SELECT data_version, contact_id, lookup, data12, data11, data10, mimetype, data15, data14, data13, data_sync1, data_sync3, data_sync2, data_sync4, account_type, custom_ringtone, status_updates.status AS status, data1, data4, data5, data2, data3, data8, data9, group_sourceid, data6, account_name, data7, display_name, in_visible_group, contacts_status_updates.status_res_package AS contact_status_res_package, is_primary, contacts_status_updates.status_ts AS contact_status_ts, raw_contact_id, times_contacted, contacts_status_updates.status AS contact_status, status_updates.status_res_package AS status_res_package, status_updates.status_icon AS status_icon, contacts_status_updates.status_icon AS contact_status_icon, presence.mode AS mode, version, last_time_contacted, res_package, _id, status_updates.status_ts AS status_ts, dirty, is_super_primary, photo_id, send_to_voicemail, contacts_status_updates.status_label AS contact_status_label, status_updates.status_label AS status_label, starred, agg_presence.mode AS contact_presence, sourceid FROM view_data_restricted data LEFT OUTER JOIN agg_presence ON (agg_presence.presence_contact_id=contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id) LEFT OUTER JOIN presence ON (presence_data_id=data._id) LEFT OUTER JOIN status_updates ON (status_updates.status_update_data_id=data._id) WHERE (1 AND mimetype = 'vnd.android.cursor.item/phone_v2')主要的信息为:
SELECT * FROM view_data_restricted where mimetype = 'vnd.android.cursor.item/phone_v2'
修改后的查询通讯录所有联系人的方法:
/** * 获取所有拥有手机号的联系人 * @param context * @return */ public static List<UserExaminee> getAllPhoneContacts(Context context){ List<UserExaminee> listContacts = new ArrayList<UserExaminee>(); int id = -1; ContentResolver cr = context.getContentResolver(); long timeStart = new Date().getTime(); String[] mContactsProjection = new String[] { ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.PHOTO_ID }; String contactsId; String phoneNum; String name; long photoId; byte[] photoBytes = null; //查询contacts表中的所有数据 Cursor cursor = cr.query(Phone.CONTENT_URI, mContactsProjection, null, null, null); if(cursor.getCount() > 0){ while (cursor.moveToNext()){ contactsId = cursor.getString(0); phoneNum = cursor.getString(1); name = cursor.getString(2); photoId = cursor.getLong(3); if(photoId > 0){//有头像 Cursor cursorPhoto = cr.query(ContactsContract.RawContactsEntity.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Photo.PHOTO}, ContactsContract.RawContactsEntity.CONTACT_ID + " = ? and " + ContactsContract.RawContactsEntity.MIMETYPE + " = ? and " + ContactsContract.RawContactsEntity.DELETED + " = ?", new String[]{contactsId, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE, "0"}, null); if(cursorPhoto.moveToNext()){ photoBytes = cursorPhoto.getBlob(0); } cursorPhoto.close(); }else{ photoBytes = null; } // 对手机号码进行预处理(去掉号码前的+86、首尾空格、“-”号等) phoneNum = phoneNum.replaceAll("^(\\+86)", ""); phoneNum = phoneNum.replaceAll("^(86)", ""); phoneNum = phoneNum.replaceAll("-", ""); phoneNum = phoneNum.replaceAll(" ", ""); phoneNum = phoneNum.trim(); // 如果当前号码是手机号码 if (CheckUtil.PhoneNumberCheck(phoneNum)) { UserExaminee user = new UserExaminee(); user.setId(String.valueOf(id)); user.setUsername(name); user.setPhonenumber(phoneNum); user.setContactPhoto(photoBytes); user.setModelType(2); listContacts.add(user); id -= 1; } } } cursor.close(); LogUtils.e(TAG + "time used " + (new Date().getTime() - timeStart) + " ms"); return listContacts; }