使用CursorLoader显示包含多个电话号码的联系人

时间:2017-06-22 19:57:44

标签: android android-contacts android-cursoradapter android-cursorloader

这似乎是一个简单的用例,但我无法找到一种方法来做到这一点。 我想检索Android手机中的所有联系人及其所有电话号码。 让我们说下面是我手机上的联系人列表及其电话号码:

A - 1111(移动),2222(家庭),3333(工作)

B - 4444(手机),5555(家庭)

C - 6666(移动),7777(家庭),8888(工作)

我想以下列方式显示联系人,但使用CursorLoader。

enter image description here

我尝试过的事情:

  • 一次获取所有联系人及其电话号码,并将其保存在自定义联系人对象的数组列表中,并使用它们在RecyclerView中显示列表。
    • 问题是,如果有很多电话号码,那么重新访问此屏幕会导致空白屏幕,原因可能是资源不足或内存泄漏问题。

Stackoverflow不会正确缩进代码,所以这里是:https://pastebin.com/y9i5R5iN

final Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(contactListCursor.getLong(ContactsQuery.ID)));
                    Uri thisContactUri = ContactsContract.Contacts.lookupContact(context.getContentResolver(), uri);
                    final UserContact contact = new UserContact();
                    contact.setName(contactListCursor.getString(contactListCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
                    final ArrayList<PhoneType> multipleContacts = new ArrayList<>();
                    final Uri phoneNumUri = Uri.withAppendedPath(thisContactUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
                    final Cursor contactPhoneNumCursor = contentResolver.query(phoneNumUri, ContactPhoneQuery.PROJECTION, ContactPhoneQuery.SELECTION, null, null);
  • 通过查询ContactsContract.Contacts.CONTENT_URI并获取ID和DISPLAY_NAME_PRIMARY,使用CursorLoader和CursorAdapter获取所有联系人。在getView()方法中,我认为我可以初始化第二个CursorLoader来调用第一个光标给我的联系人的详细信息。这样的事情:

如果用户有多个联系人,则显示单选按钮列表,否则显示具有唯一编号的文本视图。

我的代码在这里:https://bitbucket.org/soulpatch/contactlistdemo/src/7c49c1e79fbbd7da90630c8967ae6daffa4efd72/?at=first_draft

这似乎是提前加载电话号码而不是稍后更新视图。或者是因为有延迟或我不确定的事情。 有人可以帮我这个。 检查

2 个答案:

答案 0 :(得分:0)

找到了一种方法。 使用CursorLoader传递给CustomAdapter以进行联系人的初始查询,然后使用_ID字段查找联系人并为联系人创建URI,并在CustomAdapter的getView方法本身中查找Phone特定的详细信息。

我试图在两者中使用CursorLoaders或在两者中使用Bulk加载。混合方法效果最好。

希望这有助于某人。 :)

答案 1 :(得分:0)

您可以使用单个查询获取数据库中的所有电话号码及其联系人ID和联系人姓名。

我会运行此单个查询一次,将所有数据存储在地图中(contact-id =&gt; name,phone,...) 然后使用自定义适配器将地图显示为联系人列表。

以下是查询所有手机以及联系人ID和姓名的代码(确保从ContactsContract导入所有内容):

Map<Long, List<String>> contacts = new HashMap<Long, List<String>>();

String[] projection = { Data.CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3 };
String selection = Data.MIMETYPE + " IN ('" + Phone.CONTENT_ITEM_TYPE + "')";
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);

while (cur != null && cur.moveToNext()) {
    long id = cur.getLong(0);
    String name = cur.getString(1);
    String mime = cur.getString(2); // type of data (e.g. "phone")
    String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234
    int type = cur.getInt(4); // a numeric value representing type: e.g. home / office / personal
    String label = cur.getString(5); // a custom label in case type is "TYPE_CUSTOM"

    String labelStr = Phone.getTypeLabel(getResources(), type, label);
    Log.d(TAG, "got " + id + ", " + name + ", " + kind + " - " + data + " (" + labelStr + ")");

    // add info to existing list if this contact-id was already found, or create a new list in case it's new
    List<String> infos;
    if (contacts.containsKey(id)) {
        infos = contacts.get(id);
    } else {
        infos = new ArrayList<String>();
        infos.add("name = " + name);
        contacts.put(id, infos);
    }
    infos.add(kind + " = " + data + " (" + labelStr + ")");
}

注意:地图的值是字符串列表,仅用于代码清晰度。您应该将其更改为自定义Contact对象,该对象在正确的Java对象中包含电话的名称和列表