さて、掘りたくさんの後、私は私が答えであると信じるものを見つけました。私が見つけたソリューションは、使用しているAndroid APIレベルによって異なります。しかし、彼らはすべてではないので、より良い解決策があるなら、私は知りたいです。
いずれの場合も、最初の手順では、Intent.ACTION_PICKから返されたURIに対してクエリを実行して、連絡先のIDを取得します。ここにいる間、表示名と連絡先に電話番号があるかどうかを表す文字列も取得する必要があります。 (私たちは、近代的な解決のためにそれらを必要としませんが、我々は、従来のソリューションのためにそれらを必要とします。)レコードの
String id, name, phone, hasPhone;
int idx;
Cursor cursor = getContentResolver().query(contactUri, null, null, null, null);
if (cursor.moveToFirst()) {
idx = cursor.getColumnIndex(ContactsContract.Contacts._ID);
id = cursor.getString(idx);
idx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
name = cursor.getString(idx);
idx = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
hasPhone = cursor.getString(idx);
}
、カラムはこのURIから返されたがのほとんどのフィールドは定数で表されますContactsContract.Profileクラス(他のインターフェイスから継承した定数を含む)。 PHOTO_FILE_ID、PHOTO_THUMBNAIL_URI、またはPHOTO_URIは含まれません(PHOTO_ID はです)。
IDを取得しましたので、関連するデータを取得する必要があります。最初の(そして最も簡単な)解決策は、エンティティを照会することです。エンティティクエリは、連絡先または生の連絡先のすべての連絡先データを一度に取得します。各行は、ContactsContract.Contacts.Entityの定数を使用してアクセスされる1つのRaw Contactを表します。通常、RAW_CONTACT_ID、DATA1、およびMIMETYPEにのみ関係します。ただし、最初と最後の名前を別々に指定する場合、Name MIMEタイプはDATA2の最初の名前とDATA3の最後の名前を保持します。
MIMETYPE列をContactsContract.CommonDataKinds定数に一致させることによって変数をロードします。たとえば、電子メールのMIMEタイプはContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPEです。
// Build the Entity URI.
Uri.Builder b = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, id).buildUpon();
b.appendPath(ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);
URI contactUri = b.build();
// Create the projection (SQL fields) and sort order.
String[] projection = {
ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
ContactsContract.Contacts.Entity.DATA1,
ContactsContract.Contacts.Entity.MIMETYPE };
String sortOrder = ContactsContract.Contacts.Entity.RAW_CONTACT_ID + " ASC";
cursor = getContentResolver().query(contactUri, projection, null, null, sortOrder);
String mime;
int mimeIdx = cursor.getColumnIndex(ContactsContract.Contacts.Entity.MIMETYPE);
int dataIdx = cursor.getColumnIndex(ContactsContract.Contacts.Entity.DATA1);
if (cursor.moveToFirst()) {
do {
mime = cursor.getString(mimeIdx);
if (mime.equalsIgnoreCase(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
email = cursor.getString(dataIdx);
}
if (mime.equalsIgnoreCase(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
phone = cursor.getString(dataIdx);
}
// ...etc.
} while (cursor.moveToNext());
}
残念なことに、エンティティは、このコードは、(これを書いているような)市場におけるAndroidデバイスの約65%と非互換であることを意味unti API 11(アンドロイド3.0、ハニカム)、導入されませんでした。試してみると、URIからIllegalArgumentExceptionが得られます。それはですので、
// Get phone number - if they have one
if ("1".equalsIgnoreCase(hasPhone)) {
cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = "+ id,
null, null);
if (cursor.moveToFirst()) {
colIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
phone = cursor.getString(colIdx);
}
cursor.close();
}
// Get email address
cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + id,
null, null);
if (cursor.moveToFirst()) {
colIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
email = cursor.getString(colIdx);
}
cursor.close();
// ...etc.
明らかに、この方法は、別々のデータベースクエリの多くになります:
第2の解決策は、クエリ文字列を構築し、各データは、使用したいタイプごとに1つのクエリを作ることです効率の理由から推奨されません。私はこれが誰かの役に立てば幸い
try {
// Build the Entity URI.
Uri.Builder b = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, id).buildUpon();
b.appendPath(ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);
// ...etc...
} catch (IllegalArgumentException e) {
// Get phone number - if they have one
if ("1".equalsIgnoreCase(hasPhone)) {
// ...etc...
} finally {
// If you want to display the info in GUI objects, put the code here
}
:
私が作ってみたソリューションは、エンティティのクエリを使用するバージョンを試してみてください、IllegalArgumentExceptionをキャッチし、catchブロック内のレガシーコードを配置することです。そして、もう一度、これを行う良い方法があれば、私はすべての耳です。
私はparams [0]の警告を受け取りますか? –
あなたの答えに多くの感謝! – Chisko
@GerardGrundy Karlは、AsyncTask内でこのソリューションを実装しています。これは、コンテンツリゾルバにクエリを実行する際に長時間実行される可能性があるため推奨されます。params []配列(あなたが望む名前でも構いませんが、 "params"と "args"は共通名です)は、データがAsyncTaskにどのように渡されるかです。詳細については、[AsyncTask](https://developer.android.com/reference/android/os/AsyncTask.html)のドキュメントを参照してください。 – Slerig