【问题标题】:Get a contact's groups?获取联系人的群组?
【发布时间】:2017-06-13 20:10:46
【问题描述】:

我正在尝试将联系人与组进行多对多映射。

例如,如果我有:

  • 用户 1,属于组 701、702、704
  • 用户 2,不属于任何组
  • 用户 3,属于组 702

我希望得到如下所示的关系:

userID | groupID
1      | 701
1      | 702
1      | 704
3      | 702

我试过这个:

Cursor cursor = contentResolver.query(ContactsContract.Data.CONTENT_URI, null, new String[] {
    ContactsContract.CommonDataKinds.GroupMembership.CONTACT_ID,
    ContactsContract.CommonDataKinds.GroupMembership.GROUP_SOURCE_ID
}, null, null, null);

但这并不完全奏效。 GROUP_SOURCE_ID 列返回不是任何组 ID 的奇怪数字。有时它甚至返回 0 或负数。

我可以通过遍历每个组并查找该组中的所有联系人来构建此映射,但这需要大量查询,而且我正在努力保持快速(显然,只有这几个查询相当慢!)。

谁能告诉我如何在一个查询中获得此联系人到群组的映射?

谢谢!

【问题讨论】:

    标签: android


    【解决方案1】:
        Cursor dataCursor = getContentResolver().query(
                ContactsContract.Data.CONTENT_URI,
                new String[]{
                        ContactsContract.Data.CONTACT_ID,
                        ContactsContract.Data.DATA1
                },
                ContactsContract.Data.MIMETYPE + "=?",
                new String[]{ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE}, null
        );
    

    通过使用此dataCursor,您将获得联系人数据库中所有联系人的contact_idgroup_id

        Cursor groupCursor = getContentResolver().query(
                ContactsContract.Groups.CONTENT_URI,
                new String[]{
                        ContactsContract.Groups._ID,
                        ContactsContract.Groups.TITLE
                }, null, null, null
        );
    

    通过使用此groupCursor,您将获得联系人数据库中所有组的group_idgroup_title

    因此,如果您想获取与contact_id 关联的所有组,首先使用合适的选择语句获取dataCursor。使用dataCursor,您可以获得与contact_id 关联的所有group_id。现在使用groupCursor,您可以获得与该特定联系人关联的所有组的信息。

    【讨论】:

    • 效果很好!太感谢了!那么你怎么知道我需要 DATA1?是否有任何文档可以告诉我解决方案?因为找了半天,也没找到……
    • @Verdagon 通过检查联系人数据库
    • 这是新手应该能够做到的事情吗?如果没有,你能告诉我怎么做,我可以写一篇关于它的文章吗?
    • 只需从/data/data/com.android.providers.contacts/database获取数据库,然后使用sqliteman或其他软件打开即可。现在您将能够看到其中的数据。查看数据,您可以说出您需要哪一列。
    【解决方案2】:

    完整的答案是: 首先获取组游标(与上面的答案相同)

    Cursor groups_cursor= getContentResolver().query(
            ContactsContract.Groups.CONTENT_URI,
            new String[]{
                    ContactsContract.Groups._ID,
                    ContactsContract.Groups.TITLE
            }, null, null, null
    );
    

    使用以下代码将所有 group_id 和 group_title 存储在组 HashMap 中:

     if(groups_cursor!=null){
            while(groups_cursor.moveToNext()){
                String group_title = groups_cursor.getString(1);
                String id = groups_cursor.getString(0);
                groups.put(id, group_title);
            }
        }
    

    然后使用上述答案的 data_cursor,获取 contacts_ids 和他们的 group_ids。

    Cursor dataCursor = getContentResolver().query(
            ContactsContract.Data.CONTENT_URI,
            new String[]{
                    ContactsContract.Data.CONTACT_ID,
                    ContactsContract.Data.DATA1
            },
            ContactsContract.Data.MIMETYPE + "=?",
            new String[]{ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE}, null
    );
    

    现在使用 dataCursor 和组 HashMap。

        if(dataCursor!=null){
                while(dataCursor.moveToNext()){
                    String id  = dataCursor.getString(0);
                    String group_id= dataCursor.getString(1);
                    String groupTitle = groups.get(group_id);
                    Log.d(TAG, "groupTitle : " + groupTitle + " contact_id: " + id );
               }
      }
    

    【讨论】:

      【解决方案3】:
       public static HashMap<String, String> getContactsForGroup(String groupID, Activity activity){
          Cursor dataCursor = activity.getContentResolver().query(
                  ContactsContract.Data.CONTENT_URI,
                  new String[]{                                                       // PROJECTION
                          ContactsContract.Data.CONTACT_ID,
                          ContactsContract.Data.DISPLAY_NAME,         // contact name
                          ContactsContract.Data.DATA1                 // group
                  },
                  ContactsContract.Data.MIMETYPE + " = ? " + "AND " +                 // SELECTION
                  ContactsContract.Data.DATA1 +    " = ? ",           // set groupID
                  new String[]{                                                       // SELECTION_ARGS
                          ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE,
                          groupID
                  },
                  null
          );
      
          dataCursor.moveToFirst();
          HashMap<String, String> map = new HashMap<>();
          while (dataCursor.moveToNext()) //
          {
              String s0 = dataCursor.getString(0);                //contact_id
              String s1 = dataCursor.getString(1);                //contact_name
              String s2 = dataCursor.getString(2);                //group_id
              Log.d("tag", "contact_id: " + s0 + "  contact: " + s1 + "   groupID: "+ s2);
              map.put(s0, s1);
          }
          return map;
      }
      

      【讨论】:

      • 一些建议...将您的 while 循环更改为 do while 循环。由于现在编写代码,它将始终跳过表的第一行,因为 cursor.moveToFirst() 将指针放在索引 0 处,但 while (cursor.moveToNext()) 会将其推进到索引 1。您应该 close() 光标(即尝试最后阻止)。最后dataCursor.moveToFirst()理论上可以抛出NPE,所以添加一个空检查。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多