手动添加行到光标

我有一个电话号码数组,我想从联系人数据库中获取相应的联系人姓名。

在电话号码数组中,我也有一些号码在联系人数据库之前没有保存。 例如;

  • 3333333 – > Tim
  • 5555555 – >吉姆
  • 1111111 – >未知

我有包含上面显示的电话号码,即phoneArr的数组

int size=phoneArr.size(); if(size>0){ Cursor[] cursors=new Cursor[size]; for(int i=0;i<size;i++){ Uri contactUri1 = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneArr.get(i))); cursors[i] = getContentResolver().query(contactUri1, PEOPLE_PROJECTION, null, null, " _id asc limit 1"); } Cursor phones=new MergeCursor(cursors); 

在上面的场景中,phones.getCount()返回2。 当电话号码没有出现在联系人列表中时,光标变成空的,当我合并它们时,它根本没有任何贡献。 我想要的是有一个光标如下

光标电话 – > {Tim,Jim,1111111}

我想我可以做到这一点手动添加,如下所示:

 Uri contactUri1 = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneArr.get(i))); cursors[i] = getContentResolver().query(contactUri1, PEOPLE_PROJECTION, null, null, " _id asc limit 1"); if(cursors[i].getCount()==0) // add the phone number manually to the cursor 

我怎样才能做到这一点?

这是PEOPLE_PROJECTION

 private static final String[] PEOPLE_PROJECTION = new String[] { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup.NUMBER }; 

Solutions Collecting From Web of "手动添加行到光标"

在游标中添加行的最简单方法是使用MatrixCursor和MergeCursor 。 这两个类是从SDK和这里解决这种问题。

基本上你所做的是:

  1. 将要添加的行放入MatrixCusror
  2. 使用MergeCursor合并cursormatrixCursor MergeCursor

就像是:

 // Create a MatrixCursor filled with the rows you want to add. MatrixCursor matrixCursor = new MatrixCursor(new String[] { colName1, colName2 }); matrixCursor.addRow(new Object[] { value1, value2 }); // Merge your existing cursor with the matrixCursor you created. MergeCursor mergeCursor = new MergeCursor(new Cursor[] { matrixCursor, cursor }); // Use your the mergeCursor as you would use your cursor. 

我使用一个解决scheme来完成我所有不同的需求,而且比实现Cursor更简单。
这是一个例子,我必须添加额外的“播放列表”行到光标,从媒体库中检索。 我在原始游标的第一个索引处添加行:

 public class CursorWithExtraPlaylists extends CursorWrapper { public static final int ID_COLUMN_INDEX = 0; public static final int NAME_COLUMN_INDEX = 1; private int mPos = -1; private Context mContext; private Playlist[] extras; public CursorWithExtraPlaylists(Cursor cursor, Context context, Playlist[] extras) { super(cursor); mContext = context; this.extras = extras; } @Override public int getCount() { return super.getCount() + extras.length; } @Override public int getPosition() { return mPos; } @Override public boolean moveToFirst() { return moveToPosition(0); } @Override public boolean moveToLast() { return moveToPosition(getCount() - extras.length); } @Override public boolean move(int offset) { return moveToPosition(mPos + offset); } @Override public boolean moveToPosition(int position) { // Make sure position isn't past the end of the cursor final int count = getCount(); if (position >= count) { mPos = count; return false; } // Make sure position isn't before the beginning of the cursor if (position < 0) { mPos = -1; return false; } // Check for no-op moves, and skip the rest of the work for them if (position == mPos) { return true; } mPos = position; if (mPos > 0) { // ok, that concerns super cursor return super.moveToPosition(mPos - 1); } return true; } @Override public boolean moveToNext() { return moveToPosition(mPos + 1); } @Override public boolean moveToPrevious() { return moveToPosition(mPos - 1); } private boolean isPointingOnExtras() { if (-1 == mPos || getCount() == mPos) { throw new CursorIndexOutOfBoundsException(mPos, getCount()); } if (mPos <= extras.length - 1) { // this is a request on an extra value return true; } return false; } private Object getExtraValue(int columnIndex) { switch (columnIndex) { case ID_COLUMN_INDEX: return extras[mPos].getId(); case NAME_COLUMN_INDEX: return extras[mPos].getName(mContext); } return null; } @Override public int getInt(int columnIndex) { if (isPointingOnExtras()) return (Integer) getExtraValue(columnIndex); int res = super.getInt(columnIndex); return res; } @Override public String getString(int columnIndex) { if (isPointingOnExtras()) return getExtraValue(columnIndex).toString(); return super.getString(columnIndex); } public static class Playlist { private int mId; private int mNameResId; public Playlist(int mId, int nameResId) { this.mId = mId; this.mNameResId = nameResId; } public int getId() { return mId; } public String getName(Context mContext) { return mContext.getResources().getString(mNameResId); } } } 

原始游标有2列(int,String),所以我用一个额外的行对象数组来构造它。

我知道这是一个旧的post,但真正的痛苦是行不能手动添加到光标。 我提出了一个粗略的解决scheme。 这可能有一些帮助。

Cursor实际上是一个interface ,你可以创build一个自定义classimplements Cursor接口。

 class ManualCursor implements Cursor{ // .... private Vector<String[]> rows; public void addRow(String[] values){ rows.add(values); } // Implement the necessary methods, getString(int), etc. //.... } 

最后在你的代码中

 if (cursors[i].getCount() == 0){ cursors[i] = new ManualCursor(); cursors[i].addRow(rowValues); } 

这应该做到这一点。 但是请注意,要实现这个function,在实现Cursor界面时必须要明智。

不幸的是,据我所知,没有办法可以手动向游标添加数据。 你需要以不同的方式处理这个问题。

我能想到的唯一方法就是可以做到这一点

  • 用你需要的数据字段做一个结构。
  • 创build一个Arraylist并用游标中的数据填充结构中的对象,并将其添加到列表中。
  • 现在手动添加您缺less的号码信息并将其添加到列表中。
  • 将此列表传递给您的适配器,以防将urler传递给适配器。 当然,你将不得不改变你的cursoradapter实现到一个arrayadapter