Androidの連絡先APIを扱うアプリケーションを開発しています。連絡先を挿入、更新、クエリするメソッドを実装しました。これまでのところ、すべてが機能していました(連絡先の書き込みと読み取り)。
私のプロジェクトのある時点で、私は奇妙な振る舞いを経験しています。
- バッチ モードを使用して連絡先を挿入します。RawContact への URI を受け取ります。これはバックグラウンド スレッドで行います。
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
int rawContactInsertIndex = ops.size();
// create rawContact
ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_TYPE, ConstantsContract.ACCOUNT_TYPE)
.withValue(RawContacts.ACCOUNT_NAME, accountName).build());
ops.add(createInsertOperation().withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex)
.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.DISPLAY_NAME, displayName).withValue(StructuredName.GIVEN_NAME, firstName)
.withValue(StructuredName.FAMILY_NAME, lastName).build());
ContentProviderResult[] results = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
if (results.length > 0) {
result = results[0];
}
- 次に、ルックアップURIをリクエストして保存します
RawContacts.getContactLookupUri(this.getContentResolver(), myContantRawContactUri);
- (同じスレッドで) 挿入した直後に rawContactUri を使用して連絡先を照会できます。ルックアップ uri は null を返します。
Uri rawContactUri = appUser.getRawContactUri(ctx);
if (rawContactUri == null) {
return null;
}
String lastPathSegment = rawContactUri.getLastPathSegment();
long rawContactId = Long.decode(lastPathSegment);
if (rawContactUri != null) {
contact = readContactWithID(rawContactId, ContactsContract.Data.RAW_CONTACT_ID);
- プロジェクトの別の場所で、保存されたルックアップ uri または生の連絡先 uri によって挿入された連絡先を照会したいと考えています。どちらも、コンテンツ プロバイダーから行を返しません。メインスレッドと別のバックグラウンドスレッドで試しました。
ctx.getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?", new String[] { contactID + "", ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE }, null);
私の最初の考えは、それが context.getContentResolver() に関連している可能性があるということでした。しかし、Android のドキュメントには、ContentResolver オブジェクトのスコープはアプリケーションのパッケージであると記載されているため、アプリ全体で ContentResolver を使用しています。私は正しいですか?
私は何を間違っていますか?同じ rawContactUri がある場所では連絡先を返し、別の場所では返さないのはなぜですか? そして、まったく機能していない未加工の連絡先からルックアップ uri を取得するのはなぜですか?
更新: sqlite を使用してデータベースを分析しました。連絡先を挿入すると、raw_contacts と連絡先の行が作成されます。削除済みフラグは 0 に設定されているため、削除対象としてマークされていません。その後、アプリケーションの別の場所で連絡先を読み取ると、null が返されます。この時点でのデータベース ダンプには、連絡先の行は含まれていません。
更新 2: バージョン 2.3.3、4.0、および 4.1 のエミュレーターでアプリをテストしました。説明されている動作は、4.1 Jelly Bean でのみ発生します。