0

这看起来像是一个简单的用例,但我无法找到一种方法来做到这一点。 我想要检索Android手机中的所有联系人及其所有电话号码。 比方说,下面是我的手机上的联系人与他们的电话号码一起名单:使用CursorLoader显示多个电话号码的联系人

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

乙 - 4444(移动),5555 (首页)

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

我想显示在下面的方式,但使用CursorLoader的联系人。

enter image description here

事情我已经尝试:

  • 获取所有的联系人和电话号码的时间和它们保存在自定义联系人对象的数组列表,并使用它们显示在列表中一个RecyclerView。
    • 问题是,如果有很多电话号码,则重新访问此屏幕会导致空白屏幕,可能是由于资源不是空闲或内存泄漏问题。

#1不会缩进的代码可以正确所以在这里,它是: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); 
  • 使用CursorLoader并通过查询ContactsContract.Contacts.CONTENT_URI一个CursorAdapter获取所有联系人并获取ID和DISPLAY_NAME_PRIMARY。在getView()方法中,我认为我可以初始化第二个CursorLoader以调用第一个光标给我的联系的详细信息。像这样:

如果用户有多个联系人,然后显示单选按钮的列表,否则显示一个文本视图与他们唯一的数字。

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

这似乎预先加载的电话号码,而不是稍后更新视图。要么是因为有延迟或者我不确定。 有人可以帮助我这个。 检查

回答

0

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

我正在尝试在两者中都使用CursorLoaders或在两者中使用CursorLoaders。这种混合方式的效果最好。

希望这可以帮助别人。 :)

+0

您应该真的避免在getView上执行光标读取,这会导致某些设备出现可怕的性能,滚动性能不佳。明天我会发布一个更简单的解决方案,如果我有时间 – marmor

+0

是的我同意,而且我在一些旧手机中滚动时看到性能问题,但是当你说我应该避免在getView中读取光标时,你的意思是我不应该这么做第二部分我查找_ID字段并获取联系人的所有电话号码?或者你的意思是我不应该在listview上使用CustomAdapter的游标加载器?因为Android开发人员页面上的示例使用游标加载联系人姓名,并使用第二个游标来获取onClick中的详细信息。如果您能够提出更好的方法,我会很高兴,因为这可以使旧设备上的滚动更平滑。 – LeoNeo

0

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

我会运行这个单个查询一次,将所有数据存储在地图中(contact-id => 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 + ")"); 
} 

注意:map的值是一个字符串列表,只是代码 - 明晰。您应该将其更改为自定义的Contact对象,该对象在适当的Java对象中包含电话的名称和列表

+0

我之前尝试过这样做,但是当手机在600-1000范围内有很多联系人时,则1)它会冻结联系人资源。因此,切换到联系人列表屏幕并退出联系人列表屏幕会导致空白屏幕。 2)它也使屏幕反应不灵敏。 3)它可能会占用堆空间,万一得到GC-ed,那么当屏幕加载导致问题#1时,我将不得不调用它的重新加载。纠正我,如果我的理解错误 – LeoNeo

+0

听起来像你想要在主线程上运行查询,你应该在屏幕上显示一个加载动画,并加载联系人地图在'AsyncTask',你可以预先获取联系人在用户进入屏幕之前列出,以减少甚至消除加载时间。 – marmor

相关问题