15

AutoCompleteTextViewを実装していますが、すべての連絡先の名前と電子メールが必要です。非同期で実行しているこのスニペットを見つけましたが、非常に低速です。

ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

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

        Cursor emailCur = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id}, null); 

            while (emailCur.moveToNext()) { 

                String email = emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
                    autoCompleteAdapter.add(name + " - " + email);
            }

            emailCur.close();
        }
    }
}

私はある種の内部クエリを実行していますが、それが問題だと思います。それを調整してより速くする方法はありますか?

4

3 に答える 3

56
private static final String[] PROJECTION = new String[] {
    ContactsContract.CommonDataKinds.Email.CONTACT_ID,
    ContactsContract.Contacts.DISPLAY_NAME,
    ContactsContract.CommonDataKinds.Email.DATA
};

...

ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, PROJECTION, null, null, null);
if (cursor != null) {
    try {
        final int contactIdIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID);
        final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        final int emailIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
        long contactId;
        String displayName, address;
        while (cursor.moveToNext()) {
            contactId = cursor.getLong(contactIdIndex);
            displayName = cursor.getString(displayNameIndex);
            address = cursor.getString(emailIndex);
            ...
        }
    } finally {
        cursor.close();
    }
}

いくつかのメモ:

  • ContactsContract.CommonDataKinds.Email.CONTENT_URI必要な情報を取得するためだけに使用します。クエリできる列については、 ContactsContract.CommonDataKinds.Emailを参照してください。
  • プロジェクションを使用して、本当に必要な列のみを取得します。メモリを節約し、クエリのパフォーマンスを向上させます
  • whileサイクルの直前に、列インデックスを1回だけ取得します
于 2012-08-25T11:42:10.527 に答える
6

直接ContactsContract.Contactsに問い合わせないでください

メールデータの種類を使用して、 ContactsContract.CommonDataKindsに対してクエリを1つだけ実行します。

ContactsContract.CommonDataKinds.Emailは、プロジェクションの構築に使用できる他の多くのインターフェースを継承します。(ドキュメントから継承された定数を参照してください)

例えば ​​:

import android.provider.ContactsContract.CommonDataKinds.Email;

[...]

public static final String[]  EMAILS_PROJECTION = new String[] {
    Email._ID,
    Email.DISPLAY_NAME_PRIMARY,
    Email.ADDRESS
};

で使用する

Email.CONTENT_URI

電子メールデータの種類から直接、多くの情報(ユーザーID、ユーザー表示名など)を取得できます。

編集:

AutoCompleteTextViewを構築しようとしていることに気づきました。

runQueryOnBackgroundThreadCursorAdapterのメソッドとをオーバーライドし、Email.CONTENT_FILTER_URIconvertToStringを使用する必要があります

ApiDemoサンプルをご覧になることを強くお勧めします。

特に、ここにあるAutoComplete4.javaサンプル。

于 2012-08-24T13:02:38.340 に答える
0
ContentResolver cr = mContext.getContentResolver(); 
Cursor cursor = mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, PROJECTION, "HAS_PHONE_NUMBER <> 0", null, null); 

if (cursor!= null) 
{ 
    final int displayNameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); 
    final int numberIndex = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER); 
    final int idIndex= cursor.getColumnIndex(ContactsContract.Contacts._ID); 
    String displayName, number = null, idValue; 

    while (cursor.moveToNext()) 
    {
        displayName = cursor.getString(displayNameIndex);
        idValue= cursor.getString(idIndex);

        Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, "contact_id = '" + idValue + "'", null, null);
        phones.moveToFirst();

        try 
        {
            number = phones.getString(phones.getColumnIndex("data1"));
        }
        catch (CursorIndexOutOfBoundsException e)
        {
        }

        phones.close();
        userList.add(new ContactModel(displayName, number, null));
    }
}
于 2016-07-31T09:34:04.837 に答える