2012-06-06 8 views
5

私はアンドロイドデバイスの連絡先を取得しようとしています。 それは多くの時間取ってそのコード使用しているArrayAdapterListActivity移入しようとしたとき、私は、しかし、偉大なサンプルコードhere連絡先のパフォーマンスの問題を取得する

を発見した - 銀河S2に、ほぼ4秒とはるかに古いデバイス上に。 私はそのパフォーマンスを改善する必要があります。私が考えたのは、Cursorを実装し、複数のディメンションCursorを保持し、リストアダプターとしてSimpleCursorAdapterを使用することです。
は、私はこのアプローチにいくつかの問題を参照してください。

  • 私は特定の位置にアイテムを取得する方法がわかりません。
  • 各カーソルには異なる列があります。

もっと簡単な方法がありますか?

EDIT:

ここ

が私のコードです:

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; 
} 

EDIT 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、名前、電話番号) – 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の任意のフィールドにアクセスできます。この場合はStringCursor.getString(int columnIndex)を使用します。

詳細については、Cursorのドキュメントをご覧ください。

このアプローチの最も重要な点は、CursorLoaderを実装して、バックグラウンドでデータを取得できることです。また、データの変更や方向の変更などについてもListViewの再充填を自動的に処理します。詳細はthis great tutorialをご覧ください。

+1

CursorLoaderは素晴らしい方法です。また、お互いの内部で照会のネストにも注意してください。最後に、必要な情報のみを選択するようにします。 –

関連する問題