android - 按数据 ID 更新联系人数据

标签 android android-contentprovider android-contacts

我的应用程序使用联系人 ContentProvider 来存储它的一些数据。当我将联系人加载到内存中时,我想保存它的 ID(以便我知道以后如何保存更改),以及它正在使用的所有数据字段的 ID (因此它们可以直接更新)。这是我的一些代码:

    Uri entityUri = Uri.withAppendedPath(
            ContentUris.withAppendedId(RawContacts.CONTENT_URI, id),
            Entity.CONTENT_DIRECTORY);

    Cursor resultData = context.getContentResolver().query(
            entityUri,
            new String[]{RawContacts.SOURCE_ID, Entity.DATA_ID, Entity.MIMETYPE, Entity.DATA1},
            null, null, null);
    resultData.moveToFirst();

    this.id = id;
    while (resultData.isAfterLast() == false) {
        this.source_id = resultData.getInt(0);
        if (!resultData.isNull(1)) {
            if (resultData.getString(2).equals(Fields.DISPLAY_NAME)) {
                this.display_name = resultData.getString(3);
                this.display_name_id = resultData.getInt(1);
            }
        }
        resultData.moveToNext();
    }
    resultData.close();
    return this;

查询 ContentProvider 并从数据中获取 DISPLAY_NAME 字段。数据记录的ID 存储在display_name_id 变量中。当我在我的设备上运行它时,它显示为 4612

我尝试保存它,但它没有按预期更新。为了调试,我添加了一个查询,试图找到正确的数据表记录。

    Cursor c = context.getContentResolver().query(ContactsContract.Data.CONTENT_URI,
            new String[] {ContactsContract.Data._ID, CommonDataKinds.StructuredName.DISPLAY_NAME},
            ContactsContract.Data._ID + "=?",
            new String[] {String.valueOf(this.display_name_id)}, null);

但是,此游标返回时长度为 0。怎么会这样?为什么ID不对?

最佳答案

我在本地试过,它对我有用,这里是我的代码,根据你的稍微改编:

public void testContacts(final @Nonnull Context context, final int rawContactId, final @Nonnull String expectedDisplayName) {
    Uri entityUri = Uri.withAppendedPath(
            ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId),
            ContactsContract.RawContacts.Entity.CONTENT_DIRECTORY);

    Cursor resultData = context.getContentResolver().query(
            entityUri,
            new String[]{
                    ContactsContract.RawContacts.SOURCE_ID,
                    ContactsContract.RawContacts.Entity.DATA_ID,
                    ContactsContract.RawContacts.Entity.MIMETYPE,
                    ContactsContract.RawContacts.Entity.DATA1
            },
            null, null, null);

    int displayNameId = -1;
    try {
        final int columnIndexDataId = resultData.getColumnIndex(ContactsContract.RawContacts.Entity.DATA_ID);
        final int columnIndexMimetype = resultData.getColumnIndex(ContactsContract.RawContacts.Entity.MIMETYPE);
        final int columnIndexData = resultData.getColumnIndex(ContactsContract.RawContacts.Entity.DATA1);
        while (resultData.moveToNext()) {
            if (!resultData.isNull(columnIndexDataId)) {
                if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE.equals(resultData.getString(columnIndexMimetype)) &&
                        expectedDisplayName.equals(resultData.getString(columnIndexData))) {
                    displayNameId = resultData.getInt(1);
                    break;
                }
            }
        }
    } finally {
        resultData.close();
    }

    String reLookedUpDisplayName = null;
    if (displayNameId != -1) {
        Cursor reLookupCursor = context.getContentResolver().query(
                ContactsContract.Data.CONTENT_URI,
                new String[] {
                        ContactsContract.Data._ID,
                        ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME
                },
                ContactsContract.Data._ID + "=?",
                new String[] {String.valueOf(displayNameId)},
                null);
        try {
            final int columnIndexId = reLookupCursor.getColumnIndex(ContactsContract.Data._ID);
            final int columnIndexDisplayName = reLookupCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME);
            while (reLookupCursor.moveToNext()) {
                reLookedUpDisplayName = reLookupCursor.getString(columnIndexDisplayName);
            }
        } finally {
            reLookupCursor.close();
        }
    }

    Toast.makeText(
            context,
            reLookedUpDisplayName != null ? "Found re-looked up name: " + reLookedUpDisplayName : "Didn't find name re-looking it up",
            Toast.LENGTH_LONG)
            .show();
}

与您的代码没有太大区别,因此请比较或尝试替换其中的一些部分以查看您的问题所在。确保为每个查询使用新的 Cursor,并在之后正确关闭它(在 finally 子句中)。

另一件事,确保 if (resultData.getString(2).equals(Fields.DISPLAY_NAME)) 确实是您想要做的(它将条目 mime 类型与 Fields.DISPLAY_NAME),但既然你说你得到了正确的数据 ID,这应该不是问题。

关于android - 按数据 ID 更新联系人数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21594024/

相关文章:

android - 如何通过 CursorLoader 使用 ContentProvider 的 insert() 方法将值正确地插入到 SQLite 数据库中?

android - google 的 People API 与 contacts API

android 检查联系人是否安装了 android 应用程序(如 whatsapp)

android - 如何使用 RxJava 将嵌套的 double 值列表转换为 Java 类?

android - 弹出对话框在android中显示两次

android - 在 DownloadManager DOWNLOAD_COMPLETE 广播接收器上接收广播 Intent 时出错

android - 从联系人中检索 IP 地址

java - 使用 Powermock 调用私有(private)方法

android - Android 2.2 API 级别 8 中的 INSTALL_FAILED_MISSING_SHARED_LIBRARY 错误

android - android库项目中的ContentProvider