5

Androidデバイスの連絡先を取得しようとしています。ここで素晴らしいサンプルコードを見つけました

ListActivityただし、そのコードを使用しているを入力しようとするとArrayAdapter、多くの時間がかかります。Galaxys2ではほぼ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:

1つのクエリのみに変更することで修正できました。

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

2 に答える 2

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

これにより、行ごとのサブクエリが削除されます。

于 2012-06-06T21:06:16.133 に答える
3

aを使用することCursorは、この問題に対する優れたアプローチです。特定の位置から情報を取得するには、を使用できますCursor.moveToPosition(int position)。次に、を使用しCursorて、の任意のフィールド(この場合はa )にアクセスできます。StringCursor.getString(int columnIndex)

詳細については、カーソルのドキュメントを参照してください。

このアプローチの最良の部分は、CursorLoaderを実装して、バックグラウンドデータの取得を実行できることです。ListViewまた、データの変更や向きの変更などの再入力も自動的に処理します。詳細については、このすばらしいチュートリアルを確認してください。

于 2012-06-06T19:56:42.677 に答える