Agrupar por en ContentResolver en Ice Cream Sandwich
Estoy haciendo una consulta en los contactos de Android ContentProvider. Necesito una cláusula Group By. En Pan de jengibre y Honeycomb, hago algo como esto para buscar números de teléfono y correos electrónicos al mismo tiempo:
(La cláusula WHERE real es mucho más complicada, ya que incluye tipos de cheques.Esto es una simplificación, pero da el mismo resultado)
- IllegalStateException: Tablas no válidas al intentar consultar la base de datos con ContentProvider
- Android WebView no puede cargar archivos de video locales
- Android - Seleccionar máximo en contentProvider
- ¿Cómo compartir archivos desde cualquier ruta usando un FileProvider?
- Obtener número de teléfono para varios destinatarios en android
String request = Phone.NUMBER + " LIKE ? OR " + Email.DATA + " LIKE ?"; String[] params = new String["%test%", "%test%"]; Cursor cursor = getContentResolver().query( Data.CONTENT_URI, new String[] { Data._ID, Data.RAW_CONTACT_ID }, request + ") GROUP BY (" + Data.RAW_CONTACT_ID, params, "lower(" + Data.DISPLAY_NAME + ") ASC");
La inyección del ')' termina la cláusula WHERE y permite la inserción de una cláusula GROUP BY.
Sin embargo, en Ice Cream Sandwich, parece que el ContentProvider detecta esto y agrega el número correcto de paréntesis para prevenir mi inyección. Cualquier otra forma de hacerlo en una sola consulta de cursor?
Editar
Actualmente, he eliminado el GROUP BY, y agregado un MatrixCursor para limitar el impacto, pero prefiero tener un cursor real:
MatrixCursor result = new MatrixCursor(new String[] { Data._ID, Data.RAW_CONTACT_ID }); Set<Long> seen = new HashSet<Long>(); while (cursor.moveToNext()) { long raw = cursor.getLong(1); if (!seen.contains(raw)) { seen.add(raw); result.addRow(new Object[] {cursor.getLong(0), raw}); } }
- Agregar varios contactos en lote
- Android: Observación de SMS para subprocesos eliminados
- OnCreate del proveedor de contenido
- Agregar eventos al calendario nativo no funciona
- ¿Debo usar un proveedor de contenido?
- Obtener una imagen de Galería desde las carpetas sincronizadas de Picasa // Google + no funciona
- CursorLoader no se actualiza después del cambio de datos
- Android - Observer DB cambia con GreenDao ORM
Puede crear un Uri
personalizado tal que cuando su UriMatcher
en su ContentProvider
consiga, puede insertar su cláusula group by y luego ejecutar el raw sql directamente en la base de datos.
Primero de todas las excusa mi Inglés POBRE! Soy nuevo en Java / Android, comenzó con 4.2.1 y luchar con eso casi 2 días, entonces empiezo a leer algunos detalles más sobre SQLiteQueryBuilder la parte de la consulta es más o menos lo que u está buscando;)
Tiene:
public Cursor query (SQLiteDatabase db, String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder)
La "función" de consulta del proveedor de contenido sólo le proporciona:
query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder)
Aquí u puede trucos alrededor, voy a publicar mi código recorte:
@Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); /* a String is a Object, so it can be null!*/ String groupBy = null; String having = null; switch (sUriMatcher.match(uri)) { ... ... ... case EPISODES_NEXT: groupBy = "ShowID"; queryBuilder.setTables(EpisodenTable.TableName); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } Cursor c = queryBuilder.query(db, projection, selection, selectionArgs, groupBy, having, sortOrder); c.setNotificationUri(getContext().getContentResolver(), uri); return c; }
¡eso es!
Aquí el código que uso para ejecutar:
Cursor showsc = getContext().getContentResolver().query( WhatsOnTVProvider.CONTENT_EPISODES_NEXT_URI, EpisodenTable.allColums_inclCount, String.valueOf(Calendar.getInstance().getTimeInMillis() / 1000) + " < date", null, null);