我正在开发一个处理 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 和 contacts 中的行。已删除标志设置为 0,因此未将其标记为删除。如果我随后在应用程序的另一个位置读取联系人,它会返回 null。此时的数据库转储不再包含联系人的行。
更新 2: 我在 2.3.3、4.0 和 4.1 版本中使用模拟器测试了我的应用程序。所描述的行为仅出现在 4.1 Jelly Bean 中。