0

Androidの連絡先APIを扱うアプリケーションを開発しています。連絡先を挿入、更新、クエリするメソッドを実装しました。これまでのところ、すべてが機能していました(連絡先の書き込みと読み取り)。

私のプロジェクトのある時点で、私は奇妙な振る舞いを経験しています。

  1. バッチ モードを使用して連絡先を挿入します。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];
}
  1. 次に、ルックアップURIをリクエストして保存します
RawContacts.getContactLookupUri(this.getContentResolver(), myContantRawContactUri);
  1. (同じスレッドで) 挿入した直後に 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);
  1. プロジェクトの別の場所で、保存されたルックアップ 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 でのみ発生します。

4

1 に答える 1

0

わかりました、私は解決策を見つけました。それは実際には私自身のせいでした。カスタム アカウントを AccountManager に追加する前に、連絡先を追加しました。同じアカウント タイプが設定されていたため、明らかに連絡先が削除されました。

于 2012-09-22T15:54:31.563 に答える