通过从 RawContacts 过滤 account_type 列来显示联系人
Posted
技术标签:
【中文标题】通过从 RawContacts 过滤 account_type 列来显示联系人【英文标题】:showing contacts by filtering account_type column from RawContacts 【发布时间】:2018-02-20 18:45:33 【问题描述】:我在 RecyclerView
和以下代码检索联系人上显示联系人
Uri Contact_URI=ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
return new CursorLoader(getActivity(),Contact_URI,null,null,null,Build.VERSION.SDK_INT
>= Build.VERSION_CODES.HONEYCOMB ?
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY :
ContactsContract.Contacts.DISPLAY_NAME+ "ASC");
但有些联系人会被多次显示,所以我决定在account_type
列上过滤联系人。下面的代码过滤器基于account_type
if(list.getString(list.getColumnIndex("account_type")).equals("Local Phone Account") || list.getString(list.getColumnIndex("account_type")).equals("SIM Account") )
textView.setText(list.getString(list.getColumnIndex(Build.VERSION.SDK_INT
>= Build.VERSION_CODES.HONEYCOMB ?
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY :
ContactsContract.Contacts.DISPLAY_NAME)));
number.setText(list.getString(list.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
number.setText(list.getString(list.getColumnIndex("account_type")));
问题是 sim 卡和电话联系人的 account_type
值因设备而异。在Samsung GT-l9082
中,为 sim "Sim Account" 和 Phone "Local Phone Account" 提供了值,但是当我在 Galaxy J5
上对其进行测试时,它针对account_type
显示了针对 sim 和电话联系人的不同值。我只想显示 Sim 和电话联系方式
【问题讨论】:
【参考方案1】:这不是要走的路。
CommonDataKinds.Phone.CONTENT_URI
是联系人数据库中所有手机的表格,而不是联系人。
因此,即使您只过滤到一个帐户,如果某个联系人包含多于一部手机,它也会在您的列表中出现两次。
如果您只想为每个联系人显示一行,但仍需要在主列表中显示电话,则不能使用 CursorLoader
范例(这实际上很糟糕,我也不会使用它) .
改为对Phones.CONTENT_URI
表中的所有项目运行一个简单查询,并创建一个从CONTACT_ID
到NUMBER
s 列表的HashMap
,然后在地图中的每个项目显示一行,然后您还可以访问该联系人的电话列表以进行显示。
Map<String, List<String>> contacts = new HashMap<String, List<String>>();
String[] projection = Phone.CONTACT_ID, Phone.DISPLAY_NAME, Phone.NUMBER ;
Cursor cur = cr.query(Phone.CONTENT_URI, projection, null, null, null);
while (cur != null && cur.moveToNext())
long id = cur.getLong(0);
String name = cur.getString(1);
String data = cur.getString(2); // the actual info, e.g. +1-212-555-1234
Log.d(TAG, "got " + id + ", " + name + ", " + data);
// add info to existing list if this contact-id was already found, or create a new list in case it's new
String key = id + " - " + name;
List<String> infos;
if (contacts.containsKey(key))
infos = contacts.get(key);
else
infos = new ArrayList<String>();
contacts.put(key, infos);
infos.add(data);
// now you can iterate over the 'contacts' map to display all contacts
【讨论】:
感谢您的回答。我还认为它可以过滤联系人,但CursorLoader
返回一个 Cursor
和 CursorLoader.query()
在非 UI 线程上运行。所以这没关系。虽然,我同意使用 HashMaps。我接受它作为答案
您可以自己运行查询并在非UI线程上构建HashMap(使用Thread),然后将HashMap传递给适配器以在屏幕上显示数据
我只获取了直接查询ContactsContract.Data
的电话号码并过滤Data.MIMTYPE=Phone.CONTENT_ITEM_TYPE
。它只给我联系人的电话号码,无论是属于 SIM 卡、电话还是任何电子邮件帐户
您在ContactsContract.Data
上提到的查询与在ContactsContract.CommonDataKinds.Phone
上简单查询相同,Phone
表会为您添加 mimetype 选择。
是的,我知道,但现在问题是,如果我在投影Phone.CONTACT_ID, Phone.LOOKUP_KEY,Phone.DISPLAY_NAME_PRIMARY,Phone.NUMBER
中包含这些列,它只会给我保存在联系人中的电话号码,但如果在该投影中包含像 Phone.Data_Version
这样的附加列,它会显示重复项Whatsapp
也有 mimetype 电话。我认为它应该在没有 Phone.Data_Version
列的情况下显示重复项,因为 whatsapp 联系人还使用电话 mimetype 保存号码以上是关于通过从 RawContacts 过滤 account_type 列来显示联系人的主要内容,如果未能解决你的问题,请参考以下文章
通过从多个列中删除匹配的电子邮件域来过滤 Pandas 数据框
如何通过从 input type='file' 中选择来设置多个视频文件的预览