ContentProvide, uno de los cuatro componentes principales de Android

Introducción

Proveedor de contenido, uno de los cuatro componentes principales de Android, su función principal es realizar el intercambio de datos (entre aplicaciones) entre varias aplicaciones.

Aquí está involucrado el problema de la comunicación del proceso. Naturalmente, el archivador se usa en Android, pero debido a que la cantidad de datos proporcionados por el proveedor de contenido es generalmente relativamente grande, no se puede transmitir directamente.

Entonces, lo que se usa aquí es un método llamado memoria compartida anónima para la transferencia de datos, y solo se necesita transferir un descriptor de archivo en diferentes procesos.

Tenga una comprensión más intuitiva del proveedor de contenido a través de la siguiente figura:

f5c3a936d036a6b0ef53d5ec7bc7441b.png

ContentProvider proporciona un mecanismo para compartir datos entre aplicaciones.

  1. El almacenamiento y la recuperación de datos proporciona una interfaz unificada.

  2. Encapsule los datos sin preocuparse por los detalles del almacenamiento de datos.

  3. Android proporciona un ContentProvider predeterminado para algunos datos comunes (incluidos audio, video, imágenes y contactos, etc.).

Entonces, ¿cómo se da cuenta ContentProvider de compartir datos?

Identificador uniforme de recursos (URI)

El URI representa los datos que se van a operar y se puede utilizar para identificar cada ContentProvider, de modo que pueda encontrar el ContentProvider deseado a través del URI especificado y obtener o modificar datos de él.

El formato de una URI en Android es el siguiente:

URL =<schema>://<authority>/<path>/<id>

Por ejemplo: contenido://com.jeanboy.provider/User/1

  • tema (esquema)

El prefijo URI de ContentProvider indica un URI de contenido de Android, lo que indica que los datos están controlados por ContentProvider. Esta parte es fija y no se puede cambiar.

  • Información de autorización (autoridad)

La parte de autorización del URI es un identificador único que se utiliza para ubicar el ContentProvider. El formato suele ser el nombre completo de la clase ContentProvider personalizada, que se requiere para el registro. Tales como: com.jeanboy.provider.TestProvider.

  • nombre de la tabla (ruta)

El fragmento de ruta, generalmente el nombre de la tabla, apunta a un nombre de tabla en la base de datos.

  • registro (identificación)

Apunta a un registro específico, como un registro en una tabla (devuelve todos los registros si no se especifica).

tipo de datos MIME

MIME es para especificar un archivo con una extensión para abrir con una aplicación, al igual que usa un navegador para ver un archivo PDF, y el navegador elegirá la aplicación apropiada para abrir.

La forma en que funciona en Android es similar a HTTP, ContentProvider devolverá el tipo MIME según el URI y ContentProvider devolverá una cadena que contiene dos partes.

Composición MIME = tipo + subtipo.

texto/aplicación html/pdf

...

ContentProvider devuelve el tipo MIME según URI

ContentProvider.geType(uri) ;

Android sigue una convención similar para definir tipos MIME, y hay dos formas de tipos MIME de Android para cada tipo de contenido: registros múltiples (colecciones) y registros únicos.

  • Múltiples registros:vnd.android.cursor.dir/<custom>

  • Registro único:vnd.android.cursor.item/<custom>

vnd indica que estos tipos y subtipos tienen un formato no estándar específico del proveedor. El tipo en Android se ha corregido y no se puede cambiar. Solo se puede distinguir si es una colección o un solo registro específico. El contenido después del subtipo vnd. se puede completar de acuerdo con el formato.

Al usar Intent, MIME se usará para abrir la actividad que cumpla con las condiciones según el Tipo MIME.

<actividad android:name=".TestActivity">
  <intent-filter>
    <categoría android:name="android.intent.category.DEFAULT" />
    <datos android:mimeType="vnd.android.cursor.dir/jeanboy.first" />
  </intent-filter>
</actividad>

Crear un proveedor de contenido

A continuación, aprenda a crear un ContentProvider personalizado a través de una demostración simple. La fuente de datos puede elegir SQLite, la más utilizada es esta, por supuesto, también puede elegir otra, como SharedPreferences.

Primero, cree una clase TestContentProvider, herede ContentProvider e implemente el método.

clase pública TestContentProvider extiende ContentProvider {
  @Anular
  booleano público onCreate() {
    // TODO hacer algo de inicialización
    falso retorno;
  }
  @Anular
  Consulta de cursor público (Uri uri, proyección de cadena [], selección de cadena,
                      String[] argumentos de selección, String sortOrder) {
    // consulta TODO
    devolver nulo;
  }
  @Anular
  cadena pública getType(Uri uri) {
    // TODO Tipo MIME
    devolver nulo;
  }
  @Anular
  inserción pública de Uri (Uri uri, valores de ContentValues) {
    // TODO insertar
    devolver nulo;
  }
  @Anular
  public int delete(Uri uri, Selección de cadena, Cadena[] argumentos de selección) {
    // TODO borrar
    devolver 0;
  }
  @Anular
  actualización pública int (Uri uri, valores de ContentValues, selección de cadenas,
                    String[] argumentos de selección) {
    // Actualización por hacer
    devolver 0;
  }
}

Luego, debe registrarse AndroidManifest.xmlcon .

<proveedor
    Android: nombre = ".ui.proveedor.TestProvider"
    android:autoridades="com.jeanboy.proveedor de pruebas" />

Usar proveedor de contenido

En aplicaciones de terceros, ¿cómo usamos URI para realizar operaciones en datos compartidos? Se hace usando la clase ContentResolver.

El método para obtener una instancia de ContentResolver es:

Resolución de ContentResolver = getContentResolver();

ContentResolver tiene las siguientes operaciones de base de datos: consulta, inserción, actualización, eliminación.

Consulta de cursor final pública (Uri uri, proyección de cadena [], selección de cadena,
                           String[] argumentos de selección, String sortOrder)
inserción de Uri final pública (url de Uri, valores de ContentValues)
actualización int final pública (Uri uri, valores de ContentValues, cadena donde,
                         String[] argumentos de selección)
eliminación int final pública (Uri url, String where, String[] selectionArgs)

Un ejemplo completo es el siguiente:

clase pública ContentProviderActivity extiende BaseActivity {
  Uri privado uriUsuario =
    Uri.parse("contenido://com.jeanboy.testprovider/user");
  @Anular
  Vacío protegido onCreate (Paquete de estado de instancia guardado) {
    super.onCreate(estadoDeInstanciaGuardado);
    setContentView(R.layout.actividad_contenido_proveedor);
  }
  public void toInsert(Ver vista) {
    Valores de ContentValues ​​= nuevos ContentValues();
    valores.put("id", 3);
    valores.put("nombre", "张三");
    Resolución de ContentResolver = getContentResolver();
    resolver.insert(uriUser, valores);
  }
  public void toUpdate(Ver vista) {
    Valores de ContentValues ​​= nuevos ContentValues();
    valores.put("id", 3);
    valores.put("nombre", "张三三");
    Resolución de ContentResolver = getContentResolver();
    resolver.update(uriUser, valores, "id = ?", new String[]{"3"});
  }
  public void toSelect(Ver vista) {
    Resolución de ContentResolver = getContentResolver();
    Cursor cursor = resolver.query(uriUser, new String[]{"id", "name"},
                                   nulo, nulo, nulo);
    while (cursor.moveToNext()) {
      Log.e(TAG, "=========== consulta :" + cursor.getInt(0) + "=="
            + cursor.getString(1));
    }
    cursor.cerrar();
  }
  public void toDelete(Ver vista) {
    Resolución de ContentResolver = getContentResolver();
    resolver.delete(uriUser, "id = ?", new String[]{"3"});
  }
}

Permisos de proveedor de contenido

Hay tres parámetros adicionales permiso, readPermission y writePermission en la etiqueta del proveedor en AndroidManifest.xml.

Primero mira el siguiente código:

<proveedor
        Android: nombre = ".ui.proveedor.TestProvider"
        android:autoridades="com.jeanboy.proveedor de prueba"
        Android: exportado = "verdadero"
        android:readPermission="com.jeanboy.provider.permission.read"
        android:writePermission="com.jeanboy.provider.permission.write"
        android:permiso="com.jeanboy.proveedor.permiso"/>

Hay varios parámetros en este código a los que hay que prestar especial atención:

  • exportado

Este atributo se utiliza para indicar si el servicio se puede invocar o interactuar con otros componentes de la aplicación del programa; el valor es (verdadero | falso).

Si se establece en verdadero, se puede invocar o interactuar con él; de lo contrario, no; cuando se establece en falso, solo los componentes de la misma aplicación o las aplicaciones con el mismo ID de usuario pueden iniciar o vincular el servicio.

  • permiso de lectura

La autoridad necesaria para usar la función de consulta del Proveedor de contenido, es decir, la autoridad para usar query()las funciones .

  • permiso de escritura

La autoridad necesaria para usar la función de modificación de ContentProvider, es decir, la autoridad para usar las funciones insert(), update()y delete()de ContentProvider.

  • permiso

El nombre del permiso necesario para que el cliente lea y escriba datos en el Proveedor de contenido.

Esta propiedad proporciona un atajo para establecer permisos de lectura y escritura a la vez. Sin embargo, los atributos readPermission y writePermission tienen prioridad sobre esta configuración.

Si también se establece la propiedad readPermission, controlará la lectura del proveedor de contenido. Si se establece el atributo writePermission, también controlará la modificación de los datos del proveedor de contenido.

Es decir, si solo se establece el permiso permiso, entonces la aplicación con este permiso puede leer y escribir el ContentProvider aquí; si tanto el permiso como el permiso de lectura están configurados, entonces solo la aplicación con permiso de lectura puede leer, y solo la aplicación con permiso permiso permiso puede escribir! Es decir, no puede leer solo con el permiso, porque la prioridad del permiso de lectura es mayor que la del permiso; si se configuran al mismo tiempo el permiso de lectura, el permiso de escritura y el permiso, el permiso no será válido.

permiso de uso

Después de declarar el permiso anterior, debe registrarlo en el directorio al mismo nivel que la etiqueta de la aplicación.

<manifiesto...>
		<permiso
				android:nombre="com.jeanboy.proveedor.permiso.leer"
				android:label="pomisión del proveedor"
				android:protectionLevel="normal" />
  <aplicación...>
    ...
  </aplicación>
</manifiesto>

De esta forma, nuestro permiso quedará registrado en el sistema y se utilizará en aplicaciones de terceros <uses-permission>para usar permisos.

<usos-permiso android:name="com.jeanboy.provider.permission.read"/>

ContentObserver

La función principal de ContentObserver es monitorear los cambios de la base de datos en el URI especificado.

Primero, cree un ContentObserver.

clase pública DataObserver extiende ContentObserver {
  public DataObserver(Manejador manejador) {
    súper (distribuidor);
  }

  @Anular
  public void onChange(boolean selfChange) {
    super.onChange(selfChange);
    // TODO escucha los cambios de datos
  }
}

Registre un ContentObserver.

clase pública ContentProviderActivity extiende BaseActivity {

  Uri privado uriUsuario =
    Uri.parse("contenido://com.jeanboy.miproveedor/usuario");

  observador de datos privado observador de datos;

  @Anular
  cadena protegida getTAG() {
    devolver ContentProviderActivity.class.getSimpleName();
  }

  @Anular
  Vacío protegido onCreate (Paquete de estado de instancia guardado) {
    super.onCreate(estadoDeInstanciaGuardado);
    setContentView(R.layout.actividad_contenido_proveedor);
		// crear el observador de datos
    dataObserver = nuevo DataObserver(nuevo Manejador());
    // registrar el observador de datos
    getContentResolver().registerContentObserver(uriUser, verdadero,
                                                 observador de datos);
  }

  @Anular
  vacío protegido onDestroy () {
    super.onDestroy();
    // anular el registro
    getContentResolver().unregisterContentObserver(dataObserver);
  }
}

Finalmente, observe el uso de la función de escucha registerContentObserver()registrada :

public final void registerContentObserver(Uri uri,
		booleano notificar a Descendientes, observador de ContentObserver)
  • uri

El URI a observar.

  • notificar a los descendientes

Si es falso, significa coincidencia exacta, es decir, solo coincide con este URI; si es verdadero, significa que puede coincidir con su URI derivado al mismo tiempo.

おすすめ

転載: blog.csdn.net/fry3309/article/details/125281146