我想获得的用途联系人的电子邮件ID。 对于我使用光标装载机。 有一个问题我收到重复的电子邮件ID也。 如何删除电子邮件duplicacy。 我应该使用原始查询“SELECT DISTINCT”而不是使用CursorLoader或者有一些其他的解决办法?
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.CommonDataKinds.Email.DATA};
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP +"='1' AND " + Email.DATA +" IS NOT NULL AND " + Email.DATA +" != \"\" " ;
//showing only visible contacts
String[] selectionArgs = null;
return new CursorLoader(this, ContactsContract.CommonDataKinds.Email.CONTENT_URI, projection, selection, selectionArgs, sortOrder);
}
Answer 1:
我最近就遇到了这个问题。 看来,CursorLoader不具备的“不同”的实现。 我的解决办法增加了几行到onLoadFinish方法和扩展了BaseAdapter接受一个列表参数:
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String projection[] = {
CommonDataKinds.Phone._ID,
CommonDataKinds.Phone.DISPLAY_NAME,
};
String select = "((" + CommonDataKinds.Phone.DISPLAY_NAME + " NOTNULL) and " + CommonDataKinds.Phone.HAS_PHONE_NUMBER + " > 0)";
String sort = CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
CursorLoader loader = new CursorLoader(
mContext,
CommonDataKinds.Phone.CONTENT_URI,
projection,
select,
null,
sort
);
return loader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
List<String> displayNames = new ArrayList<String>();
cursor.moveToFirst();
while(!cursor.isAfterLast()){
String name = cursor.getString(cursor.getColumnIndex(CommonDataKinds.Phone.DISPLAY_NAME));
if(!displayNames.contains(name))
displayNames.add(name);
cursor.moveToNext();
}
mAdapter.swapCursor(displayNames);
}
这里是我的BaseAdapter类:
public class AdapterAddContacts extends BaseAdapter{
private List<String> mData = new ArrayList<String>();
private Context mContext;
public AdapterAddContacts(Context context,List<String> displayNames){
mData = displayNames;
mContext = context;
}
@Override
public int getCount() {
if(mData != null)
return mData.size();
else
return 0;
}
@Override
public Object getItem(int pos) {
return mData.get(pos);
}
@Override
public long getItemId(int id) {
return id;
}
@Override
public View getView(int pos, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.entry_add_contacts,parent,false);
String data = mData.get(pos);
TextView textName = (TextView)view.findViewById(R.id.my_contacts_add_display_name);
textName.setText(data);
textName.setTag(data);
return view;
}
public void swapCursor(List<String> displayNames){
mData = displayNames;
this.notifyDataSetChanged();
}
你应该能够专门修改此为您的需求。
Answer 2:
通过@mars启发,我不需要适配器的修改的解决方案。 我们的想法是删除光标的复印件; 因为没有办法做到这一点,我们创建了一个新的游标的内部消除重复。
所有的代码是在onLoadFinished
:
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
MatrixCursor newCursor = new MatrixCursor(PROJECTION); // Same projection used in loader
if (cursor.moveToFirst()) {
String lastName = "";
do {
if (cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)).compareToIgnoreCase(lastName) != 0) {
newCursor.addRow(new Object[]{cursor.getString(0), cursor.getString(1), cursor.getString(2) ...}); // match the original cursor fields
lastName =cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
}
} while (cursor.moveToNext());
}
mContactsAdapter.swapCursor(newCursor);
}
Answer 3:
我曾经在我的项目一个小型的黑客 - SQL注入,这样的:
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(
this,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] {
"DISTINCT "+ MediaStore.Images.Media.BUCKET_ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME},
null, null, null);
}
此代码只返回包名称和画廊它们的ID。 所以,我想重写代码这样的:
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
String[] projection = new String[] {
"DISTINCT " + ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Email.DATA};
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP +"='1' AND " + Email.DATA +" IS NOT NULL AND " + Email.DATA +" != \"\" " ;
//showing only visible contacts
String[] selectionArgs = null;
return new CursorLoader(this, ContactsContract.CommonDataKinds.Email.CONTENT_URI, projection, selection, selectionArgs, sortOrder);
}
Answer 4:
你可以把setDistinct在你的内容提供商。
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
...
final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setDistinct(true);
Answer 5:
如果你担心性能,不希望在onLoadFinished()再次玩弄光标,然后有一个小黑客
我结合以下从SO两种解决方案。
选择在机器人源码不同值
与rawQuery CursorLoader
这里是我工作的解决方案:
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
String tableName;
/*
* Choose the table to query and a sort order based on the code returned
* for the incoming URI.
*/
switch (uriMatcher.match(uri)) {
case NOTIFICATION:
tableName = NOTIFICATIONS_TABLE_NAME;
break;
case NOTIFICATION_TIMESTAMP:
Cursor cursor = db.query(true, NOTIFICATIONS_TABLE_NAME, projection, selection, selectionArgs, TIMESTAMP, null, sortOrder, null);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
case DOWNLOAD:
tableName = DOWNLOADS_TABLE;
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
if (selection != null) {
selection = selection + "=?";
}
Cursor cursor = db.query(tableName, projection, selection, selectionArgs, null, null, sortOrder);
// Tell the cursor what uri to watch, so it knows when its source data
// changes
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
如果在这种情况下,表名看到的是同样是前2个案件,但我创建了一个虚拟URI来实现这一目标。 可能不是一个很好的做法,但完美的作品。
Answer 6:
我发现了一个解决方案中使用DISTINCT
在选择阵列关键字。
String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, "DISTINCT" + ContactsContract.CommonDataKinds.Email.DATA};
文章来源: Using CursorLoader to get emails causes duplication of emails