从内容提供者那里获取联系人,没有重复或无效的联系人,并保存到 Realm
Posted
技术标签:
【中文标题】从内容提供者那里获取联系人,没有重复或无效的联系人,并保存到 Realm【英文标题】:Obtaining contacts from content provider without duplicates or invalid contacts, and save to Realm 【发布时间】:2017-01-15 05:47:42 【问题描述】:我有这段代码(感谢@EpicPandaForce 提供),但我在删除时遇到了问题。当我添加新联系人时,它就像一个魅力,而当我删除联系人(或该联系人中的号码,如果有两个联系人)时,它会保留在 Realm 中。我怎样才能让它正常工作?
realm.executeTransaction(new Realm.Transaction()
@Override
public void execute(Realm realm)
Contact realmContact = new Contact();
String filter = "" + ContactsContract.Contacts.HAS_PHONE_NUMBER + " > 0 and "
+ ContactsContract.CommonDataKinds.Phone.TYPE +"="
+ ContactsContract.CommonDataKinds.Phone.TYPE_MAIN;
Cursor phones = getActivity()
.getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, filter, null, null);
while (phones.moveToNext())
String id = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID));
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
realmContact.setId(id);
realmContact.setName(name);
realmContact.setNumber(phoneNumber);
realmContact.setIsBeingSaved(true);
realm.insertOrUpdate(realmContact);
/** merge mechanism */
realm.where(Contact.class)
.equalTo("isBeingSaved", false)
.findAll()
.deleteAllFromRealm(); // delete all non-saved data
for(Contact contact : realm.where(Contact.class).findAll())
realmContact.setIsBeingSaved(false); // reset all save state
联系人.class
public class Contact extends RealmObject
@PrimaryKey
private String id;
@Index
private String name;
@Index
private String number;
@Index
private boolean isBeingSaved;
public String getId()
return id;
public void setId(String id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getNumber()
return number;
public void setNumber(String number)
this.number = number;
public boolean getIsBeingSaved()
return isBeingSaved;
public void setIsBeingSaved(boolean beingSaved)
isBeingSaved = beingSaved;
编辑 - 工作代码:
Contact realmContact = new Contact();
Uri uri = Contacts.CONTENT_URI;
String selection = "((" + CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " NOTNULL) AND ("
+ Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY + " != '' ))";
Cursor phones = getActivity()
.getContentResolver()
.query(uri, null, selection, null, null);
String phoneNumber = "";
while (phones.moveToNext())
String id = phones.getString(phones.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
String name = phones.getString(phones.getColumnIndex(Contacts.DISPLAY_NAME_PRIMARY));
String lastTimeContacted = phones.getString(phones.getColumnIndex(Contacts.LAST_TIME_CONTACTED));
if(Integer.parseInt(phones.getString(phones.getColumnIndex(Contacts.HAS_PHONE_NUMBER))) > 0)
Cursor pCur = getActivity().getContentResolver().query(
CommonDataKinds.Phone.CONTENT_URI,
null,
CommonDataKinds.Phone.LOOKUP_KEY +" = ?",
new String[]id, null);
while (pCur.moveToNext())
phoneNumber += "/" + pCur.getString(pCur.getColumnIndex(CommonDataKinds.Phone.NUMBER));
realmContact.setNumber(phoneNumber);
phoneNumber = "";
pCur.close();
else
realmContact.setNumber("1234");
realmContact.setId(id);
realmContact.setName(lastTimeContacted);
realmContact.setIsBeingSaved(true);
realm.insertOrUpdate(realmContact);
Log.i("asd-size", realm.where(Contact.class).findAll().size() + "");
/** merge mechanism */
realm.where(Contact.class)
.equalTo("isBeingSaved", false)
.findAll()
.deleteAllFromRealm(); // delete all non-saved data
for(Contact contact : realm.where(Contact.class).findAll())
contact.setIsBeingSaved(false); // reset all save state
【问题讨论】:
@EpicPandaForce 刚刚发现DELETED
列已记录,但未实施:D 来源:***.com/questions/30609515/… 似乎有解决方法,但通常情况下还是相反:)
...伙计,联系人过于复杂了-_-
如果这个没有任何反应,我会在它可用时悬赏它
与此同时,我发现LOOKUP_KEY
比_ID
更推荐,因为后者在聚合发生时会发生变化:***.com/questions/5151885/…
@EpicPandaForce 我找到了答案,我希望你不会因此而生我的气......
【参考方案1】:
好吧,找了好久发现有错别字:
/** merge mechanism */
realm.where(Contact.class)
.equalTo("isBeingSaved", false)
.findAll()
.deleteAllFromRealm(); // delete all non-saved data
for(Contact contact : realm.where(Contact.class).findAll())
realmContact.setIsBeingSaved(false); <- here it is
它是realmContact
,实际上它应该是contact
,所以它指的是for
循环迭代的联系人。
所以,基本上,它将Contact realmContact = new Contact();
设置为false
。所以正确的版本是:
/** merge mechanism */
realm.where(Contact.class)
.equalTo("isBeingSaved", false)
.findAll()
.deleteAllFromRealm(); // delete all non-saved data
for(Contact contact : realm.where(Contact.class).findAll())
contact.setIsBeingSaved(false);
【讨论】:
哈哈哈哦好吧!同时,您从内容提供商那里获得的新联系查询是什么?毕竟他们说_ID
不是很稳定
我用实际代码更新了问题 :) 我现在使用 LOOKUP_KEY
更有希望 - 而不是 3245
你得到的东西看起来更像哈希码。另外,我更新了selection
。仍然有 WhatsApp 重复号码,但我虽然 Maybe someone will use that channel instead of phone?
所以我保持原样,但现在所有号码都在一个联系人下:)以上是关于从内容提供者那里获取联系人,没有重复或无效的联系人,并保存到 Realm的主要内容,如果未能解决你的问题,请参考以下文章