2012-06-06 43 views
5

我想获取Android设备的联系人。 我发现了一个伟大的示例代码here获取联系人的性能问题

然而,试图填充ListActivityArrayAdapter正在使用的代码是服用大量的时间 - 银河S2将近4秒,旧设备上的更多。 我需要提高性能。我认为是实现Cursor将保存多个维度Cursor,并使用SimpleCursorAdapter作为列表适配器。
我看到一些问题这种方法:

  • 我不知道如何在特定位置获得项目。
  • 每个游标都有不同的列。

有没有更好/更简单的方法来做到这一点?

编辑:

这里是我的代码:

public List<ContactData> readContacts(){ 
    ContentResolver cr = getContentResolver(); 
    List<ContactData> cd = new ArrayList<ContactData>(); 
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, 
      null, null, null, ContactsContract.Contacts.DISPLAY_NAME); 

    if (cur.getCount() > 0) { 
     while (cur.moveToNext()) { 
      String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID)); 
      String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 
      if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) { 

       // get the phone number 
       Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, 
             ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", 
             new String[]{id}, null); 
       while (pCur.moveToNext()) { 
        String phone = pCur.getString(
          pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
        if (!Utils.isEmpty(phone)) { 
         cd.add(new ContactData(id, name, phone)); 
        } 
       } 
       pCur.close(); 


      } 
     } 
    } 
    return cd; 
} 

编辑2:

管理,改成只有一个查询来解决它:

public List<ContactData> readContacts(){ 
    ContentResolver cr = getContentResolver(); 
    List<ContactData> cd = new ArrayList<ContactData>(); 
       Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
         new String[]{ContactsContract.CommonDataKinds.Phone._ID,ContactsContract.CommonDataKinds.Phone.NUMBER,ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY}, 
         ContactsContract.CommonDataKinds.Phone.NUMBER + " IS NOT NULL", 
             null, 
             ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY); 
       while (pCur.moveToNext()) { 
        String phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
        String id = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID)); 
        String name = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY)); 
         ContactData cd1 = contactDataProvider.get(); 
         cd1.id = id; 
         cd1.name = name; 
         cd1.phone = phone; 
         cd.add(cd1); 
       } 
       pCur.close(); 
    return cd; 
} 
+0

什么是您想要在每个“ListFragment”行中呈现的来自联系人的完整和准确的数据片段列表? – CommonsWare

+0

我添加了代码示例,希望它解释(id,name,phone) – oshai

回答

4

你可以在你的电话号码,同时获得名称和ID:

String[] PROJECTION=new String[] {Contacts._ID, Contacts.DISPLAY_NAME, Phone.NUMBER}; 
Cursor pCur = cr.query(Phone.CONTENT_URI, PROJECTION, Phone.CONTACT_ID +" = ?", 
             new String[]{id}, null); 

这消除了每行的子查询。

+0

它的工作原理,谢谢!我使用它,但也删除了ID的过滤,以获得所有用户的所有电话。 – oshai

3

使用Cursor是解决这个问题的好方法。要从特定位置获取检索信息,可以使用Cursor.moveToPosition(int position)。然后,您可以使用Cursor.getString(int columnIndex)访问Cursor的任何字段,在本例中为String

查看Cursor文档以获取更多详细信息。

这种方法最好的部分是你可以实现一个CursorLoader为你做背景数据检索。它还会自动处理重新填充数据更改,方向更改等方面的ListView等。有关更多说明,请查阅this great tutorial

+1

CursorLoader是一个很好的方法。另外要小心嵌套在对方内部的查询。最后,你想确保你只选择你需要的信息。 –