studio que programacion movetofirst example android cursor row manual

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 un arrayadapter .

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:

  1. Ponga las filas que desea agregar en un MatrixCusror
  2. matrixCursor su cursor y su matrixCursor usando un MergeCursor

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.