【问题标题】:update contacts display_name更新联系人 display_name
【发布时间】:2012-12-01 01:18:06
【问题描述】:

如何更新联系人的显示名称?下面代码中的操作在不抛出任何东西的情况下完成,并且似乎可以正常工作 - 也就是说,当我重新查询 ContactsContract.Contact 表时,返回一行并更改了名称。但是,当我尝试在平板电脑上运行股票“人”应用程序时,它崩溃了。显然我做错了什么。

这里是代码。早期,它从聚合联系人中获取一个 id,如下所示,其中 key 是 lookup_key:

  String[] projection = new String[] {
    Contacts._ID, // 0
    Contacts.DISPLAY_NAME, // 1
  };

  Uri uri = Uri.parse (Contacts.CONTENT_LOOKUP_URI + "/" + key);
  ContentResolver cr = getContentResolver();
  Cursor cursor = cr.query (uri, projection, null, null, null);
  if (!cursor.moveToNext()) // move to first (and only) row.
    throw new IllegalStateException ("contact no longer exists for key");
  origId = cursor.getLong(0);
  cursor.close();

然后,在用户完成编辑后,我调用这段代码来更新 display_name:

  ArrayList<ContentProviderOperation> opers = new ArrayList<ContentProviderOperation>();
  ContentProviderOperation.Builder builder = null;

  String[] args = { Long.toString (origId) };
  builder = ContentProviderOperation.newUpdate (Data.CONTENT_URI);
  builder.withSelection (RawContacts.CONTACT_ID + "=?", args);
  builder.withValue(CommonDataKinds.StructuredName.DISPLAY_NAME, name);
  opers.add(builder.build());

  ContentProviderResult[] results = null;
  try {
    results = getContentResolver().applyBatch(ContactsContract.AUTHORITY, opers);
  } catch ...

我意识到在这个示例中我不需要 ContentProviderOperation;那是为了以后我有更多东西要更新的时候。

说实话,我对自己实际使用的是哪个 ID 感到很困惑。这些名称对我来说不是很清楚,我可能为此操作使用了错误的 ID。

对于它的价值,在更新后查看 results 我看到结果代码为 5。我找不到任何文档,所以不知道这是否重要。

【问题讨论】:

    标签: android contacts updates


    【解决方案1】:

    ID(以及一般的更改联系人)可能会非常令人困惑......我也有一些戏剧性的事情让我印象深刻。

    这是我用于更新的一些工作代码。我可以看到的主要区别是您如何声明原始 ID;它需要作为内容值包含在其中。

    Cursor cursor = _context.getContentResolver().query(contactUri,
                new String[] { Contacts._ID }, null, null, null);
        try {
            if (cursor.moveToFirst()) {
                String rawContactId = cursor.getString(0);
                ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
                ContentValues contentValues = new ContentValues();
                contentValues.put(Data.RAW_CONTACT_ID, rawContactId);
    
                contentValues
                        .put(ContactsContract.Data.MIMETYPE,
                                ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
                contentValues.put(
                        ContactsContract.CommonDataKinds.Phone.NUMBER,
                        phoneNumber);
                contentValues.put(ContactsContract.CommonDataKinds.Phone.TYPE,
                        ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
    
                ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
                        .withValues(contentValues).build());
                String contactId = contactUri.getLastPathSegment();
                ops.add(ContentProviderOperation
                            .newUpdate(ContactsContract.Data.CONTENT_URI)
                            .withSelection(
                                    ContactsContract.Data.CONTACT_ID
                                            + "=? AND "
                                            + ContactsContract.Data.MIMETYPE
                                            + "=?",
                                    new String[] {
                                            contactId,
                                            ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE })
                            .withValue(
                                    ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
                                    newName).build());
    
                result = _context.getContentResolver().applyBatch(
                        ContactsContract.AUTHORITY, ops);
            }
        } finally {
            cursor.close();
        }
    

    希望对您有所帮助!

    【讨论】:

    • 它可能有效 :) 你能帮我验证几件事吗:(1) 你使用contactUri - 那是ContactsContract.Data.CONTENT_URI 吗? (2) contactUri.getLastPathSegment() 是来自 ContactsContract.Contacts._ID 的 id 吗? (3) 看来这种技术只会更新一个原始联系人;不应该有一种方法来更新聚合到联系人表中的所有原始联系人中的名称吗?
    • (1) android.provider.ContactsContract.Contacts.CONTENT_URI 是我正在使用的 (2) 这是正确的。 (3) 我想有办法做到这一点,但你为什么要这样做?如果您想一次批量更改多个,我想您会将每个更改作为单独的操作...
    • 因此,如果您从 Data.CONTENT_URI 开始,则您已经拥有正确的更新 ID。就我而言,我从联系人表开始,因此更新需要与该表相关。告诉我,如果你知道的话,RawContacts.CONTACT_ID 是 Contacts._ID 的 FK 吗?我想我现在也看到了其他关键的 shema 关系:Data.RAW_CONTACT_ID 是 RawContacts._ID 的 FK,DATA.CONTACT_ID 是 Contacts._ID 的 FK - 对吧?我希望这是在文档中...
    • 这就是我的理解 - RawContacts.CONTACT_ID 是父级, RawContacts._ID 是它的 ID。我不太确定 Data.CONTACT_ID 但命名表明它是。整个联系人系统让我深有体会 - 从来没有找到一个体面、简洁的解释,因此我尝试在我的网站上详细说明!
    • 是的,同意(就是头痛的部分)。感谢您坚持这一点 - 这真的很有帮助!
    【解决方案2】:

    上面的答案通常是正确的。但是,当我插入时

    ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME 然后尝试做 newUpdate

    ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME

    使用上述代码 - 它使联系人显示在联系人应用程序中,其名称混合了新旧数据。我发现插入和更新 ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME 例如可以按我的预期工作。在我的 Android 4x 上的联系人应用程序中编辑联系人时,我看不到家人并单独给出,请看我 DISPLAY_NAME 是由 Android 制作的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多