Android
Proveedor de contenido
Buscar..
Observaciones
Los proveedores de contenido gestionan el acceso a un conjunto estructurado de datos. Encapsulan los datos y proporcionan mecanismos para definir la seguridad de los datos. Los proveedores de contenido son la interfaz estándar que conecta los datos en un proceso con el código que se ejecuta en otro proceso.
Cuando desea acceder a los datos en un proveedor de contenido, utiliza el objeto ContentResolver
en el Context
su aplicación para comunicarse con el proveedor como cliente. El objeto ContentResolver
comunica con el objeto proveedor, una instancia de una clase que implementa ContentProvider
. El objeto proveedor recibe solicitudes de datos de los clientes, realiza la acción solicitada y devuelve los resultados.
No necesita desarrollar su propio proveedor si no tiene la intención de compartir sus datos con otras aplicaciones. Sin embargo, necesita su propio proveedor para proporcionar sugerencias de búsqueda personalizadas en su propia aplicación. También necesita su propio proveedor si desea copiar y pegar datos o archivos complejos de su aplicación a otras aplicaciones.
El propio Android incluye proveedores de contenido que administran datos como audio, video, imágenes e información de contacto personal. Puede ver algunos de ellos en la documentación de referencia del paquete android.provider
. Con algunas restricciones, estos proveedores son accesibles a cualquier aplicación de Android.
Implementando una clase de proveedor de contenido básico
1) Crear una clase de contrato
Una clase de contrato define constantes que ayudan a las aplicaciones a trabajar con los URI de contenido, nombres de columna, acciones de intención y otras características de un proveedor de contenido. Las clases de contrato no se incluyen automáticamente con un proveedor; El desarrollador del proveedor tiene que definirlos y luego ponerlos a disposición de otros desarrolladores.
Un proveedor generalmente tiene una sola autoridad, que sirve como su nombre interno de Android. Para evitar conflictos con otros proveedores, use una autoridad de contenido única. Debido a que esta recomendación también es válida para los nombres de paquetes de Android, puede definir la autoridad de su proveedor como una extensión del nombre del paquete que contiene el proveedor. Por ejemplo, si el nombre de su paquete de Android es com.example.appname
, debe otorgar a su proveedor la autoridad com.example.appname.provider
.
public class MyContract {
public static final String CONTENT_AUTHORITY = "com.example.myApp";
public static final String PATH_DATATABLE = "dataTable";
public static final String TABLE_NAME = "dataTable";
}
Un URI de contenido es un URI que identifica datos en un proveedor. Los URI de contenido incluyen el nombre simbólico de todo el proveedor (su autoridad) y un nombre que apunta a una tabla o archivo (una ruta). La parte de identificación opcional apunta a una fila individual en una tabla. Cada método de acceso a datos de ContentProvider tiene un URI de contenido como argumento; esto le permite determinar la tabla, fila o archivo a acceder. Definir estos en la clase de contrato.
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_DATATABLE).build();
// define all columns of table and common functions required
2) Crear la clase de ayuda
Una clase auxiliar administra la creación de bases de datos y la administración de versiones.
public class DatabaseHelper extends SQLiteOpenHelper {
// Increment the version when there is a change in the structure of database
public static final int DATABASE_VERSION = 1;
// The name of the database in the filesystem, you can choose this to be anything
public static final String DATABASE_NAME = "weather.db";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// Called when the database is created for the first time. This is where the
// creation of tables and the initial population of the tables should happen.
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Called when the database needs to be upgraded. The implementation
// should use this method to drop tables, add tables, or do anything else it
// needs to upgrade to the new schema version.
}
}
3) Crear una clase que amplíe la clase ContentProvider
public class MyProvider extends ContentProvider {
public DatabaseHelper dbHelper;
public static final UriMatcher matcher = buildUriMatcher();
public static final int DATA_TABLE = 100;
public static final int DATA_TABLE_DATE = 101;
Un UriMatcher asigna una autoridad y una ruta a un valor entero. El método match()
devuelve un valor entero único para un URI (puede ser cualquier número arbitrario, siempre que sea único). Una declaración de cambio elige entre consultar toda la tabla y consultar un solo registro. Nuestro UriMatcher devuelve 100 si el URI es el URI de contenido de la tabla y 101 si el URI apunta a una fila específica dentro de esa tabla. Puede usar el #
comodín para hacer coincidir con cualquier número y *
para hacer coincidir con cualquier cadena.
public static UriMatcher buildUriMatcher() {
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(CONTENT_AUTHORITY, MyContract.PATH_DATATABLE, DATA_TABLE);
uriMatcher.addURI(CONTENT_AUTHORITY, MyContract.PATH_DATATABLE + "/#", DATA_TABLE_DATE);
return uriMatcher;
}
IMPORTANTE: el orden de las llamadas addURI()
importante! El UriMatcher se verá en orden secuencial desde el primer agregado hasta el último. Como los comodines como #
y *
son codiciosos, deberá asegurarse de haber ordenado sus URI correctamente. Por ejemplo:
uriMatcher.addURI(CONTENT_AUTHORITY, "/example", 1);
uriMatcher.addURI(CONTENT_AUTHORITY, "/*", 2);
es el orden correcto, ya que el comparador buscará /example
primero antes de recurrir a la coincidencia /*
. Si se invirtieron estas llamadas de método y llamó a uriMatcher.match("/example")
, ¡UriMatcher dejará de buscar coincidencias una vez que encuentre la ruta /*
y devolverá el resultado incorrecto!
A continuación, tendrá que anular estas funciones:
onCreate () : Inicialice su proveedor. El sistema Android llama a este método inmediatamente después de crear su proveedor. Observe que su proveedor no se crea hasta que un objeto ContentResolver intente acceder a él.
@Override
public boolean onCreate() {
dbhelper = new DatabaseHelper(getContext());
return true;
}
getType () : devuelve el tipo MIME correspondiente a un URI de contenido
@Override
public String getType(Uri uri) {
final int match = matcher.match(uri);
switch (match) {
case DATA_TABLE:
return ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + MyContract.CONTENT_AUTHORITY + "/" + MyContract.PATH_DATATABLE;
case DATA_TABLE_DATE:
return ContentResolver.ANY_CURSOR_ITEM_TYPE + "/" + MyContract.CONTENT_AUTHORITY + "/" + MyContract.PATH_DATATABLE;
default:
throw new UnsupportedOperationException("Unknown Uri: " + uri);
}
}
consulta () : recupera datos de tu proveedor. Use los argumentos para seleccionar la tabla a consultar, las filas y columnas para regresar, y el orden de clasificación del resultado. Devuelve los datos como un objeto Cursor.
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor retCursor = dbHelper.getReadableDatabase().query(
MyContract.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}
Inserte una nueva fila en su proveedor. Use los argumentos para seleccionar la tabla de destino y para obtener los valores de columna para usar. Devuelve un URI de contenido para la fila recién insertada.
@Override
public Uri insert(Uri uri, ContentValues values)
{
final SQLiteDatabase db = dbHelper.getWritableDatabase();
long id = db.insert(MyContract.TABLE_NAME, null, values);
return ContentUris.withAppendedId(MyContract.CONTENT_URI, ID);
}
delete () : borra filas de tu proveedor. Usa los argumentos para seleccionar la tabla y las filas para eliminar. Devuelve el número de filas borradas.
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int rowsDeleted = db.delete(MyContract.TABLE_NAME, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
update () : actualice las filas existentes en su proveedor. Utilice los argumentos para seleccionar la tabla y las filas para actualizar y obtener los nuevos valores de columna. Devuelve el número de filas actualizadas.
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int rowsUpdated = db.update(MyContract.TABLE_NAME, values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
4) Actualizar archivo de manifiesto
<provider
android:authorities="com.example.myApp"
android:name=".DatabaseProvider"/>