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

相關問題