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 和 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 回答