web-dev-qa-db-ja.com

Android単一のデータベースクエリで連絡先の表示名と電話番号?

表示名と電話番号(いずれかまたはすべて)を使用して、ネイティブデータベースから連絡先のリストを取得しようとしています。電話のデータベースに対するいくつかのクエリを使用してこの情報を取得する方法は多数ありますが、これによりかなりのオーバーヘッドが発生します。

ここに私が取り組んできたクエリがありますが、結果は

Uri uri                = ContactsContract.Contacts.CONTENT_URI;
String[] projection    = new String[] { ContactsContract.Contacts._ID,
                                        ContactsContract.Contacts.DISPLAY_NAME,
                                        ContactsContract.CommonDataKinds.Phone.NUMBER};
String selection       = ContactsContract.Contacts.HAS_PHONE_NUMBER + " = '1'";
String[] selectionArgs = null;
String sortOrder       = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";

Cursor people          = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);

int index_id    = people.getColumnIndex(ContactsContract.Contacts._ID);
int indexName   = people.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
int indexNumber = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

people.moveToFirst();
do {
    String _id    = people.getString(index_id);
    String name   = people.getString(indexName);
    String number = people.getString(indexNumber);
    // Do work...
} while (people.moveToNext());

そして、これが結果のエラーです。

E/AndroidRuntime(21549): Caused by: Java.lang.IllegalArgumentException: Invalid column data1
E/AndroidRuntime(21549):    at Android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.Java:144)
E/AndroidRuntime(21549):    at Android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.Java:114)
E/AndroidRuntime(21549):    at Android.content.ContentProviderProxy.bulkQueryInternal(ContentProviderNative.Java:372)
E/AndroidRuntime(21549):    at Android.content.ContentProviderProxy.query(ContentProviderNative.Java:408)
E/AndroidRuntime(21549):    at Android.content.ContentResolver.query(ContentResolver.Java:264)

考え?単一のクエリですべての列を取得するには、結合が必要になると思います。

49
Derek

このコードを試してください:

Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String[] projection    = new String[] {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER};

Cursor people = getContentResolver().query(uri, projection, null, null, null);

int indexName = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int indexNumber = people.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

if(people.moveToFirst()) {
    do {
        String name   = people.getString(indexName);
        String number = people.getString(indexNumber);
        // Do work...
    } while (people.moveToNext());
}
104
jamapag

連絡先APIは非常にトリッキーで、いくつかの暗黙的な結合があります。

時間に余裕がある場合は、 ContactContract および ContactsProvider2 をお読みください。

なんでしょう?テーブルは次のように連鎖します。

  • 連絡先1-未加工の連絡先
  • Raw Contact 1-*電話番号(データテーブル)

APIは次のように機能します。一番下の要素(電話番号)を選択し、一番上の要素(連絡先)に暗黙的に結合します。

PHONE URIケース(ContactsProvider2 /行4377)を使用します。これにより、すべての電話番号が選択され、連絡先に参加します。

PHONE uriをUIマジック(グループ化用)と組み合わせて、DISPLAY_NAMEとPHONE番号(DATA1?)を要求すると、問題を解決できるはずです。

14
treffer

電話番号は独自のテーブルに格納されており、個別に照会する必要があります。電話番号テーブルを照会するには、SDK変数ContactsContract.CommonDataKinds.Phone.CONTENT_URIに格納されているURIを使用します。 WHERE条件を使用して、指定した連絡先の電話番号を取得します。

private String displayName(Uri contactUri) {
        HashSet detail = ContactDetail.getInstance().getContactArray();
        Log.d("ITEM", contactUri.toString());
        String[] projection = new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};
        Cursor queryCursor = getActivity().getContentResolver()
                .query(contactUri, null, null, null, null);
        queryCursor.moveToFirst();
        String name = queryCursor.getString(queryCursor.getColumnIndex("display_name"));
        String id = queryCursor.getString(
                queryCursor.getColumnIndex(ContactsContract.Contacts._ID));

        if (Integer.parseInt(queryCursor.getString(queryCursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
            Cursor pCur = getActivity().getContentResolver().query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                    new String[]{id}, null);
            while (pCur.moveToNext()) {
                String number = pCur.getString(pCur.getColumnIndex("data1"));
                Log.d("Contact Name: ", number);
            }
            pCur.close();
        }


        return name;
    }

Android contacts SQLiteデータベースに対して2番目のクエリを実行します。電話番号は、ContactsContract.CommonDataKinds.Phone.CONTENT_URIに格納されているURIに対してクエリされます。連絡先IDは、ContactsContractとして電話テーブルに格納されます。 CommonDataKinds.Phone.CONTACT_IDおよびWHERE句は、返されるデータを制限するために使用されます。

1
rinkesh