update studio programacion móviles desarrollo curso contentresolver content aplicaciones android cursor wrapping android-contentprovider

android - studio - Cursor de ajuste/desenvolvimiento en ContentProvider



manual de programacion android pdf (3)

No hay necesidad de "desenvolver" el cursor. El problema es que si su proveedor de contenido proporciona resultados a un cliente que se ejecuta en otro proceso, el cursor que devolvió de la consulta () debe implementar la interfaz CrossProcessCursor. No se indica en el documento (AFAICS), pero puede verlo desde su registro.

Todo lo que necesita hacer es implementar la interfaz de CrossProcessCursor y envolverla alrededor de su cursor.

// your query statement does not seem right..BTW Cursor result = mContentResolver.query(...); // now, you return a CrossProcessCursorWrapper. return new CrossProcessCursorWrapper(result);

La implementación de los métodos de CrossProcessCursor se transporta desde AbstractCursor. Algunas modificaciones leves se hacen para que el compilador feliz:

public class CrossProcessCursorWrapper extends CursorWrapper implements CrossProcessCursor { public CrossProcessCursorWrapper(Cursor cursor) { super(cursor); } @Override public CursorWindow getWindow() { return null; } @Override public void fillWindow(int position, CursorWindow window) { if (position < 0 || position > getCount()) { return; } window.acquireReference(); try { moveToPosition(position - 1); window.clear(); window.setStartPosition(position); int columnNum = getColumnCount(); window.setNumColumns(columnNum); while (moveToNext() && window.allocRow()) { for (int i = 0; i < columnNum; i++) { String field = getString(i); if (field != null) { if (!window.putString(field, getPosition(), i)) { window.freeLastRow(); break; } } else { if (!window.putNull(getPosition(), i)) { window.freeLastRow(); break; } } } } } catch (IllegalStateException e) { // simply ignore it } finally { window.releaseReference(); } } @Override public boolean onMove(int oldPosition, int newPosition) { return true; } }

Estoy creando ContentProvider que es un proxy de otro ContentProvider (para problemas de seguridad y para dar acceso a parte de la funcionalidad de la aplicación completa).

public class GFContactsProvider extends ContactsProvider implements DatabaseConstants { private Context mContext; private ContentResolver mContentResolver; @Override public boolean onCreate() { mContext = getContext(); mContentResolver = mContext.getContentResolver(); } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor result = mContentResolver.query(ContactsContract.getContactsURI(Long.parseLong(address.get(1))), null, null, null, ContactsContract.ContactColumns.SHOW_NAME); return result; } }

Después de llamar al CP interno desde mi CP, recibí una excepción inesperada:

java.lang.UnsupportedOperationException: Only CrossProcessCursor cursors are supported across process for now

La excepción se refiere a la envoltura del Cursor por el CP y la transferencia envuelta, el CP Externo no puede envolverlo nuevamente, así que tengo un problema aquí. Cuando verifiqué la clase del cursor devuelto recibí CursorWrapperInner. ¿Hay alguna forma de desenvolver el cursor (de este CWI al cursor normal) en mi CP externo (pero no transfiriendo todos los datos a MatrixCursor en bucle? Es demasiado lento).


Parece que usas dos apk o algo así. No debe obtener esto con diferentes proveedores de contenido que se utilicen entre sí dentro de la misma aplicación. Cuando otra aplicación intenta usar su ContentProviders, sin embargo, recibe este error. La solución es permitir que su implementación de Cursor personalizada implemente la interfaz de CrossProcessCursor.


Por lo que sé, no puede desenvolver el Cursor porque la clase de envoltorio es privada (podría ser posible mediante el uso de reflexiones, pero el SecurityManager probablemente no lo permita), pero podría intentar crear su propio envoltorio que implemente el CrossProcessCursor, envuelve el cursor devuelto y es devuelto por su ContentProvider.