背景
通讯录上的联系人可以有一个帐户数据附加到他们。每个应用程序都可以有一个帐户,然后为联系人添加自己的信息。
应用程序,如电报,WhatsApp,Viber,.-所有创建一个帐户,添加信息和/或行动的联系人。
下面是一个具有WhatsApp和Viber帐户的联系人的示例:

问题所在
我想弄清楚如何获取所有有指定帐户的联系人。
因为WhatsApp是我所知道的最流行的,所以我的测试集中在它上。
我的问题是,有些用户声称我几乎没有回复联系人,而有些人则声称它连一个都没有显示。它似乎通常是有效的,在我的例子中,它总是有效的,但是在代码上可能有些不好的地方。
我试过的
我需要做下一个代码,在我看来,这是工作的,得到一个电话到联系信息的地图,所有的WhatsApp联系人。
这样做的目的是获取WhatsApp联系人的所有可能信息,与所有基本联系人数据进行比较,并将匹配相同查找键的联系人合并。
我试图使用更好的加入查询,但失败了。也许这也是可能的,也可能更有效率。
下面是代码:
/**
* returns a map of lookup-key to contact-info, of all WhatsApp contacts
*/
@NonNull
public HashMap<String, ContactInfo> getAllWhatsAppPhones(Context context) {
ContentResolver cr = context.getContentResolver();
final HashMap<String, ContactInfo> phoneToContactInfoMap = new HashMap<>();
final HashMap<String, String> whatsAppLookupKeyToPhoneMap = new HashMap<>();
final String phoneMimeType = Phone.CONTENT_ITEM_TYPE;
final Cursor whatsAppCursor;
whatsAppCursor = cr.query(Data.CONTENT_URI,
new String[]{Phone.NUMBER, Phone.LOOKUP_KEY},
Phone.MIMETYPE + " = ?", new String[]{WhatsAppStuff.WHATS_APP_MIME_TYPE}, null);
if (whatsAppCursor == null)
return phoneToContactInfoMap;
Cursor contactCursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
//null,
new String[]{
Contacts.LOOKUP_KEY, Contacts._ID, Contacts.PHOTO_THUMBNAIL_URI,
ContactsContract.Contacts.DISPLAY_NAME, // ContactsContract.CommonDataKinds.Phone.NUMBER,
},
"(" + Phone.MIMETYPE + " IS NULL OR " + Phone.MIMETYPE + " = '" + phoneMimeType + "') AND ("
+ ContactsContract.RawContacts.ACCOUNT_TYPE + " = 'com.google' OR " + ContactsContract.RawContacts.ACCOUNT_TYPE + " IS NULL)",
null, null);
if (contactCursor == null) {
whatsAppCursor.close();
return phoneToContactInfoMap;
}
int progress = 0;
final int phoneNumberIdx = whatsAppCursor.getColumnIndex(Phone.NUMBER);
final int lookupKeyIdx = whatsAppCursor.getColumnIndex(Phone.LOOKUP_KEY);
while (whatsAppCursor.moveToNext()) {
final String phoneNumberValue = whatsAppCursor.getString(phoneNumberIdx);
final int endIndex = phoneNumberValue.indexOf("@");
if (endIndex < 0)
continue;
String lookupKey = whatsAppCursor.getString(lookupKeyIdx);
final String phone = phoneNumberValue.substring(0, endIndex);
if (!phone.isEmpty() && StringUtil.isAllDigits(phone)) {
//Log.d("AppLog", "whatsApp phone:" + phone + " " + lookupKey);
whatsAppLookupKeyToPhoneMap.put(lookupKey, phone);
}
if (markedToCancel != null && markedToCancel.get()) {
whatsAppCursor.close();
contactCursor.close();
return phoneToContactInfoMap;
}
if (progressListener != null)
progressListener.onProgressUpdate(progress++, maxProgress);
}
whatsAppCursor.close();
if (whatsAppLookupKeyToPhoneMap.isEmpty())
return phoneToContactInfoMap;
//Log.d("AppLog", "getting info about whatsapp contacts");
final int idColIdx = contactCursor.getColumnIndex(Contacts._ID);
final int displayNameColIdx = contactCursor.getColumnIndex(Contacts.DISPLAY_NAME);
final int lookupKeyColIdx = contactCursor.getColumnIndex(Contacts.LOOKUP_KEY);
final int photoColIdx = contactCursor.getColumnIndex(Contacts.PHOTO_THUMBNAIL_URI);
while (contactCursor.moveToNext()) {
String lookupKey = contactCursor.getString(lookupKeyColIdx);
String phoneNumber = whatsAppLookupKeyToPhoneMap.get(lookupKey);
if (phoneNumber == null)
continue;
ContactInfo contactInfo = new ContactInfo();
contactInfo.lookupKey = lookupKey;
contactInfo.displayName = contactCursor.getString(displayNameColIdx);
contactInfo.photoThumbUriStr = contactCursor.getString(photoColIdx);
contactInfo.whatsAppPhoneNumber = phoneNumber;
contactInfo.contactId = contactCursor.getLong(idColIdx);
phoneToContactInfoMap.put(phoneNumber, contactInfo);
if (markedToCancel != null && markedToCancel.get()) {
contactCursor.close();
return phoneToContactInfoMap;
}
if (progressListener != null)
progressListener.onProgressUpdate(progress++, maxProgress);
}
contactCursor.close();
return phoneToContactInfoMap;
}问题是
正如我所写的,上面的代码通常只起作用。
为什么它通常只起作用?有什么东西没修好吗?
我应该使用Contacts.getLookupUri而不是查找键吗?如果是这样的话,我应该如何更改上面的代码来代替它呢?
我尝试使用URI而不是查找键,但是它在普通联系人中没有找到其中的任何一个。
发布于 2017-08-16 07:40:03
我看到的主要问题可以解释为什么用户看不到代码的结果,因为您假设所有联系人都存储在Google帐户上。
虽然这是某些设备的默认行为,但并不是所有设备上的默认行为,用户也可以自由地将联系人存储更改到任何其他位置(雅虎联系人、MS exchange、仅手机(未同步)等)。
话虽如此,如果你唯一的要求是
获取具有指定帐户的所有联系人。
我认为这是一个比您的两个查询更好的选择(其中一个查询覆盖所有联系人,而不仅仅是所需的):
// Uri to query contacts that have a RawContact in the desired account
final Uri.Builder builder = Contacts.CONTENT_URI.buildUpon();
builder.appendQueryParameter(RawContacts.ACCOUNT_NAME, whatsappAccountName);
builder.appendQueryParameter(RawContacts.ACCOUNT_TYPE, whatsappAccountType);
Uri uri = builder.build();
String[] projection = new String[]{ Contacts.LOOKUP_KEY, Contacts._ID Contacts.DISPLAY_NAME }; // add more if needed
// boo-yaa!
Cursor cur = cr.query(uri, projection, null, null, null);https://stackoverflow.com/questions/45701809
复制相似问题