android - que - Agregando filas en Cursor manualmente
public cursor android (4)
Tengo una serie de números de teléfono y quiero obtener los nombres de contacto correspondientes de la base de datos de contactos.
En la serie de números de teléfono, también tengo algunos números que no se guardaron antes en la base de datos de contactos. Por ejemplo;
- 3333333 -> tim
- 5555555 -> Jim
- 1111111 -> desconocido
Tengo la matriz que contiene los números de teléfono que se muestran arriba, a saber, 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 () devuelve 2 en el escenario anterior. Cuando el número de teléfono no aparece en la lista de contactos, el cursor se queda vacío y, de alguna manera, cuando los fusiono no contribuye en absoluto. Lo que quiero es tener un cursor de la siguiente manera
Teléfonos con cursor -> {Tim, Jim, 1111111}
Creo que puedo hacer esto agregando la fila manualmente de la siguiente manera:
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
¿Cómo puedo conseguir esto?
Aquí está la PERSONAS_PROYECCIÓN
private static final String[] PEOPLE_PROJECTION = new String[] {
ContactsContract.PhoneLookup._ID,
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup.NUMBER
};
Desafortunadamente, hasta donde sé, no hay forma de que pueda agregar datos manualmente al cursor. Necesitas manejar esto de una manera diferente.
La única forma en que puedo pensar en cómo puedes hacer esto es
- Haz una estructura con los campos de datos que necesitas.
- Haga un Arraylist y llene los objetos de su estructura con los datos de los cursores y agréguelos a la lista.
- Ahora agregue manualmente la información de su número faltante y agréguela a la lista.
- Pase esta lista a su adaptador, en caso de que esté pasando el cursor a un adaptador ahora. Por supuesto, tendría que cambiar la implementación de su
cursoradapter
a unarrayadapter
.
La forma más fácil de agregar filas en un cursor es usar un MatrixCursor y un MergeCursor . Esas dos clases son del SDK y están aquí para resolver ese tipo de problemas.
Básicamente lo que haces es:
- Ponga las filas que desea agregar en un
MatrixCusror
-
matrixCursor
sucursor
y sumatrixCursor
usando unMergeCursor
Algo como:
// 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.
Sé que esta es una publicación antigua, pero es un dolor real que las filas no se puedan agregar manualmente a un Cursor. He venido con una solución cruda. Podría ser de alguna ayuda.
Cursor
es en realidad una interface
y puede crear una class
personalizada que implements
la interfaz del Cursor
.
class ManualCursor implements Cursor{
// ....
private Vector<String[]> rows;
public void addRow(String[] values){
rows.add(values);
}
// Implement the necessary methods, getString(int), etc.
//....
}
Y finalmente en tu código.
if (cursors[i].getCount() == 0){
cursors[i] = new ManualCursor();
cursors[i].addRow(rowValues);
}
Deberias hacer eso. Pero ten en cuenta que, para que esto funcione, debes ser sensato al implementar la interfaz del Cursor
.
Utilizo una solución que hace el truco para todas mis necesidades diferentes y que es más simple que implementar Cursor.
Aquí hay un ejemplo donde tengo que agregar filas adicionales de "lista de reproducción" a un Cursor, recuperado del Mediastore. Agrego filas en los primeros índices del Cursor original:
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);
}
}
}
El cursor original tiene 2 columnas (int, String), así que lo construyo con una matriz de objetos de filas adicionales.