21

少なくとも 1 つの電話番号ですべての連絡先を取得したいのですが、すべての連絡先のすべての電話番号とすべてのメールも取得したいと考えています。

現在のコード:

// To get All Contacts having atleast one phone number.

Uri uri = ContactsContract.Contacts.CONTENT_URI;
String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + " > ?";
String[] selectionArgs = new String[] {"0"};
Cursor cu = applicationContext.getContentResolver().query(uri, 
                null, selection, selectionArgs, null);

// For getting All Phone Numbers and Emails further queries : 
while(cu.moveToNext()){
String id = cu.getString(cu.getColumnIndex(ContactsContract.Contacts._ID));


 // To get Phone Numbers of Contact
    Cursor pCur = context.getContentResolver().query(
    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,  null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?",
 new String[]{id}, null);

// To get Email ids of Contact
Cursor emailCur = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",
new String[]{id}, null); 

// Iterate through these cursors to get Phone numbers and Emails
}

デバイスに 1000 を超える連絡先がある場合、時間がかかりすぎています。連絡先ごとに 2 つの追加クエリを実行するのではなく、単一のクエリですべてのデータを取得するにはどうすればよいですか?

または、最適化する他の方法はありますか?

前もって感謝します。

4

2 に答える 2

48

ICS:クエリを実行するData.CONTENT_URIと、関連付けられているすべての行がContactすでに結合されています。つまり、これは機能します。

ContentResolver resolver = getContentResolver();
Cursor c = resolver.query(
        Data.CONTENT_URI, 
        null, 
        Data.HAS_PHONE_NUMBER + "!=0 AND (" + Data.MIMETYPE + "=? OR " + Data.MIMETYPE + "=?)", 
        new String[]{Email.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE},
        Data.CONTACT_ID);

while (c.moveToNext()) {
    long id = c.getLong(c.getColumnIndex(Data.CONTACT_ID));
    String name = c.getString(c.getColumnIndex(Data.DISPLAY_NAME));
    String data1 = c.getString(c.getColumnIndex(Data.DATA1));

    System.out.println(id + ", name=" + name + ", data1=" + data1);
}

HAS_PHONE_NUMBER2.3をターゲットにしている場合は、クエリ時に使用される結合では利用できないという事実を考慮する必要がありますData

楽しい

これは、たとえば、連絡先に電話番号が必要であるという要件をスキップし、代わりに「少なくとも電話番号または電子メールアドレスを持つ連絡先」を選択することで解決できます

Cursor c = resolver.query(
        Data.CONTENT_URI, 
        null, 
        Data.MIMETYPE + "=? OR " + Data.MIMETYPE + "=?", 
        new String[]{Email.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE},
        Data.CONTACT_ID);

それがオプションでない場合は、いつでも恐ろしくハッキーなサブ選択を行うことができます。

Cursor c = resolver.query(
        Data.CONTENT_URI, 
        null, 
        "(" + Data.MIMETYPE + "=? OR " + Data.MIMETYPE + "=?) AND " + 
        Data.CONTACT_ID + " IN (SELECT " + Contacts._ID + " FROM contacts WHERE " + Contacts.HAS_PHONE_NUMBER + "!=0)", 
        new String[]{Email.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE}, Data.CONTACT_ID);

または、2つ Cursorのsを使用して解決します。

Cursor contacts = resolver.query(Contacts.CONTENT_URI, 
        null, Contacts.HAS_PHONE_NUMBER + " != 0", null, Contacts._ID + " ASC");
Cursor data = resolver.query(Data.CONTENT_URI, null, 
        Data.MIMETYPE + "=? OR " + Data.MIMETYPE + "=?", 
        new String[]{Email.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE}, 
        Data.CONTACT_ID + " ASC");

int idIndex = contacts.getColumnIndexOrThrow(Contacts._ID);
int nameIndex = contacts.getColumnIndexOrThrow(Contacts.DISPLAY_NAME);
int cidIndex = data.getColumnIndexOrThrow(Data.CONTACT_ID);
int data1Index = data.getColumnIndexOrThrow(Data.DATA1);
boolean hasData = data.moveToNext();

while (contacts.moveToNext()) {
    long id = contacts.getLong(idIndex);
    System.out.println("Contact(" + id + "): " + contacts.getString(nameIndex));
    if (hasData) {
        long cid = data.getLong(cidIndex);
        while (cid <= id && hasData) {
            if (cid == id) {
                System.out.println("\t(" + cid + "/" + id + ").data1:" + 
                        data.getString(data1Index));
            }
            hasData = data.moveToNext();
            if (hasData) {
                cid = data.getLong(cidIndex);
            }
        }
    }
}
于 2012-08-08T10:30:31.157 に答える