Android:使用原始联系人 ID 正确访问和查询

Posted

技术标签:

【中文标题】Android:使用原始联系人 ID 正确访问和查询【英文标题】:Android: Accessing and querying properly using Raw Contact Id 【发布时间】:2011-07-15 14:39:06 【问题描述】:

所以我的应用正在尝试将同步适配器集成到 android 原生联系人管理器中。这一切都运行顺利,除了一旦同步联系人,我无法更新它。可以在此处找到有关此特定问题的详细信息:Android: Content resolver query returning 0 rows when it ought not to 但我可以简单地总结一下,我相信我的内容解析器查询返回 0 值,因为我查询的是错误的 URI。

当我将原始联系人 ID 写入手机时,我使用以下代码:

public ContactSyncOperations(Context context, String username,
        String accountName, BatchOperationForSync batchOperation) 

    this(context, batchOperation);
    mBackReference = mBatchOperation.size();
    mIsNewContact = true;
    mValues.put(RawContacts.SOURCE_ID, username);
    mValues.put(RawContacts.ACCOUNT_TYPE, "com.tagapp.android");
    mValues.put(RawContacts.ACCOUNT_NAME, accountName);
    mBuilder = newInsertCpo(RawContacts.CONTENT_URI, true).withValues(mValues);
    mBatchOperation.add(mBuilder.build());

当您将新联系人添加到同步列表时会调用此构造方法:

private static void addContact(Context context, String account, Contact contact, BatchOperationForSync batchOperation) 
    ContactSyncOperations contactOp = ContactSyncOperations.createNewContact(context, contact.getUsername(), account, batchOperation);//constructor called @ this line
    contactOp.addName(contact.getFirstName(), contact.getLastName());
    contactOp.addEmail(contact.getEmail());
    contactOp.addPhone(contact.getPhoneNumber(), Phone.TYPE_MOBILE);
    contactOp.addPhone(contact.getHomePhone(), Phone.TYPE_HOME);
    contactOp.addPhone(contact.getWorkPhone(), Phone.TYPE_WORK);
    contactOp.addProfileAction(contact.getUsername());
    Log.e("Adding contact", "Via sync");

正如你在构造函数中看到的,我正在调用一个名为newInsertCpo的方法,可以在这里查看:

private void addInsertOp() 
    if(!mIsNewContact) 
        mValues.put(Phone.RAW_CONTACT_ID, mRawContactId);
    
    mBuilder = newInsertCpo(addCallerIsSyncAdapterParameter(Data.CONTENT_URI), mYield);
    mBuilder.withValues(mValues);
    if(mIsNewContact) 
        mBuilder.withValueBackReference(Data.RAW_CONTACT_ID, mBackReference);
    
    mYield = false;
    mBatchOperation.add(mBuilder.build());

现在您可以看到代码,让我解释一下问题。当我创建和编写原始联系人 ID 时,我正在这样做 RawContacts.CONTENT_URI:

mBuilder = newInsertCpo(RawContacts.CONTENT_URI, true).withValues(mValues);

但是,当我查询 uri 时,我是这样查询的:

Cursor cursor = resolver.query(Data.CONTENT_URI, DataQuery.PROJECTION, DataQuery.SELECTION, new String[] String.valueOf(rawContactId), null);

来自 Data.CONTENT_URI。我相信这是我的问题发生的地方。我使用了来自 Android 官方开发网站的示例代码并针对我自己的用途对其进行了定制,但这部分与示例非常吻合。然而它不起作用。我的线索就是我所说的,我正在写信给一个 Uri 并查询另一个。但是我尝试将查询更改为 RawContacts.CONTENT_URI(这会导致异常),并将我写入的 Uri 更改为 Data.CONTENT_URI,这也会导致异常。更令人困惑的是,当我执行 lookupRawContactId 方法时,我会从 Data.CONTENT_URI 获取原始联系人 ID:

private static long lookupRawContact(ContentResolver resolver, String username) 
    Log.e("Looking up Raw Contact", username);
    long authorId = 0;
    Cursor cursor = resolver.query(Data.CONTENT_URI, UserIdQuery.PROJECTION, UserIdQuery.SELECTION, new String[] username, null);

    try 
        if(cursor != null && cursor.moveToFirst()) 
            authorId = cursor.getLong(UserIdQuery.COLUMN_ID);
        
     finally 
        if(cursor != null) 
            cursor.close();
        
    
    return authorId;

所以是的,如果我得到一个返回 rawcontactId 的游标,为什么我会得到 0 个值来查询具有相同 rawcontactId 我返回的相同 Uri?这没有任何意义!有没有人有任何见识?谢谢大家。

【问题讨论】:

什么是 BatchOperationForSync ?并检查您是否存储了正确的反向引用。 【参考方案1】:

lookupRawContactId 方法应如下所示:

private static long lookupRawContact(ContentResolver resolver, String username) 
    Log.e("Looking up Raw Contact", username);
    long authorId = 0;
    Cursor cursor = resolver.query(RawContacts.CONTENT_URI, UserIdQuery.PROJECTION, UserIdQuery.SELECTION, new String[] username, null);

    try 
        if(cursor != null && cursor.moveToFirst()) 
            authorId = cursor.getLong(UserIdQuery.COLUMN_ID);
        
     finally 
        if(cursor != null) 
            cursor.close();
        
    
    return authorId;

请注意,查询正在搜索 RawContacts.CONTENT_URI。

【讨论】:

JMRboosties,请告诉我 UserIdQuery.PROJECTION 是什么意思。我应该为 UserIdQuery 声明什么 我需要 Raw ContactID 请告诉我如何获取 RawContactID static final class UserIdQuery private UserIdQuery() public final static String[] PROJECTION = new String[]RawContacts._ID;公共最终静态 int COLUMN_ID = 0; public static final String SELECTION = RawContacts.ACCOUNT_TYPE + "='" + "com.tagapp.android" + "' AND " + RawContacts.SOURCE_ID + "=?"; 光标 cursor =getContentResolver().query(RawContacts.CONTENT_URI, UserIdQuery.PROJECTION, UserIdQuery.SELECTION, new String[]first_name, null);尝试 if(cursor.moveToNext()) authorId = cursor.getLong(UserIdQuery.COLUMN_ID);

以上是关于Android:使用原始联系人 ID 正确访问和查询的主要内容,如果未能解决你的问题,请参考以下文章

使用 Android 联系人应用程序编辑由自定义 ContentProvider 添加的原始联系人

访问 android 联系人所有详细信息的最佳方式

Android 原始联系人行应创建自己的专属聚合联系人行

访问 Android 联系人组名称

访问原始联系人数据

JDBC增删改查和查唯一的完整代码