手动将行添加到Cursor中

时间:2012-03-29 01:20:14

标签: android cursor row manual

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

在电话号码数组中,我还有一些以前未保存到联系人数据库的号码。例如;

  • 3333333 - >添
  • 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。当电话号码没有出现在联系人列表中时,光标变空,并且当我合并它们时,它根本没有任何贡献。我想要的是有一个光标如下

光标手机 - &gt; {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
};

4 个答案:

答案 0 :(得分:50)

在游标中添加行的最简单方法是使用MatrixCursorMergeCursor。 这两个类来自SDK,这里解决了这类问题。

基本上你做的是:

  1. 将要添加的行放在MatrixCusror
  2. 使用cursor
  3. 合并您的matrixCursorMergeCursor

    类似的东西:

    // 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.
    

答案 1 :(得分:3)

我使用的解决方案可以满足我所有不同的需求,而且比实现Cursor更简单 这是一个示例,我必须向从Mediastore检索到的Cursor添加额外的“播放列表”行。我在原始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),所以我用额外的行对象数组构造它。

答案 2 :(得分:2)

我知道这是一篇旧帖子,但是无法手动将行添加到Cursor中真的很痛苦。我想出了一个粗糙的解决方案。它可能会有所帮助。

Cursor实际上是interface,您可以创建class implements 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);
}

最后在你的代码中

Cursor

应该这样做。但是要注意,为了实现这一点,你必须在实现{{1}}接口时明智。

答案 3 :(得分:1)

不幸的是,据我所知,你无法手动将数据添加到游标中。你需要以不同的方式处理这个问题。

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

  • 使用您需要的数据字段构建一个结构。
  • 制作一个Arraylist并使用游标中的数据填充结构的对象,并将它们添加到列表中。
  • 现在手动添加您缺少的号码信息并将其添加到列表中。
  • 将此列表传递给您的适配器,以防您现在将游标传递给适配器。当然,您必须将cursoradapter实施更改为arrayadapter