¿Cómo transferir archivos entre aplicaciones de Android que se ejecutan en el mismo dispositivo?

Estoy escribiendo una aplicación de Android que interactúa con un servicio RESTful. Este servicio web esencialmente enfrenta un sistema de archivos, y proporciona metadatos, así CRUD acceso a los archivos. Mi aplicación recupera los metadatos y lo expone a aplicaciones de terceros a través de un ContentProvider .

Tengo que añadir la capacidad de las aplicaciones de terceros, que se ejecutan en el mismo dispositivo que mi aplicación, a CRUD los archivos reales haciendo solicitudes a / desde mi aplicación (no directamente con el servidor). Esto significa que necesitan enviar o recibir el contenido de los archivos (que normalmente son XML o imágenes) a través de mi aplicación.

He pensado en dos enfoques para implementar esto:

Opción 1 – Uso de ContentProvider.openFile

Esto parece una opción obvia para dar a las aplicaciones de terceros la capacidad de leer archivos de mi ContentProvider . Creo que empieza a ser complicado cuando esas aplicaciones necesitan crear o actualizar archivos a través de mi 'ContentProvider'. Necesitaré una devolución de llamada cuando hayan terminado para saber cuándo enviar el archivo nuevo / modificado de nuevo al servidor. Creo que podría utilizar un FileObserver para ese propósito sin embargo.

Opción 2 – Uso de un Messenger a través de un servicio

Con este enfoque, puedo enviar los archivos entre mi aplicación y las aplicaciones cliente a través del Messenger . Los archivos tendrían que pasar a través de un Bundle , por lo que no estoy seguro de cuál es el mejor formato para transmitirlos ( File , FileDescriptor , matriz de bytes, algo más ??). No tengo una buena manija en si o no esto causaría problemas si los archivos consiguen ser grandes.

Opción 3: un enfoque híbrido

  1. Utilice la (s) carpeta (s) en el almacenamiento externo como un buzón
  2. Comunique las peticiones de CRUD, y el contenido de la caja de la gota, a través de un Messenger / Service
  3. Utilice ContentProvider para almacenar el estado de las solicitudes
  4. La aplicación de terceros recibe actualizaciones de estado a través de un ContentObserver

Resumen

Creo que usar ContentProvider sería la solución ideal, pero parece que la API no es totalmente compatible con mi caso de uso. Me preocupa que intentar seguir ese camino podría resultar en una implementación kludgy. Si voy con un servicio de Messenger y Service , no estoy seguro de la forma más sólida de transferir los archivos a través de un Bundle .

El enfoque híbrido parece bastante robusto, pero el más complejo de implementar. Los archivos en realidad no se están pasando, por lo que el rendimiento debe ser bueno. Sin embargo, me temo que esto es over-architecting la solución.

¿Cuál es el mejor enfoque para transferir archivos entre aplicaciones que se ejecutan en el mismo dispositivo Android? Por supuesto, estoy abierto a otras opciones que no he esbozado en mi pregunta.

Proveedor de contenido es definitivamente el camino a seguir. Si usted considera que Google utiliza este enfoque para casi todo, entonces se convierte en appaentr que este es el método de diseño previsto.

No estoy exaltando las virtudes de ellos, pero en la tierra de los ciegos, el proveedor de contenido de un solo ojo es el rey.

Actualizar

Hay un ejemplo de cómo hacerlo en el libro de CommonsWare, consulte el enlace proporcionado.

Fuente del proveedor de contenido / archivos

Utilice el marco de sincronización para los proveedores de contenido. Simplemente mantenga una lista de peticiones y programe la sincronización para descargar el archivo. También puede hacer esto en cosquillas de red, etc. Puede utilizar intents de difusión o contentobserver para notificar a los clientes que el archivo se descarga.

En esencia esto es probablemente similar a su tercera opción, pero lo más importante es que utiliza las herramientas suministradas por Android en lugar de rodar su propio.

Ad Endum

El mejor lugar para comenzar es la muestra de Android SDK en: android-sdk \ samples \ android-8 \ SampleSyncAdapter, pero se advierte que hay una carga de cosas relacionadas con los contactos que enmascara los bits jugosos. Me tomó un tiempo para averiguar que podía eliminar casi todo excepto el syncadapter

http://developer.android.com/reference/android/os/ParcelFileDescriptor.html puede enviarse entre procesos. Creo que hay una sutilidad en la que estos están explícitamente en la lista negra de ser permitido a ser puesto en intenciones. Pueden ser enviados a través de AIDL sin embargo. Además, NO utilice la tarjeta sd para esto. Esto es sólo pedir problemas. Una tarjeta SD es legible en el mundo, por lo que cualquiera puede verlo. Además, no siempre tiene acceso a escribir en la tarjeta SD (se quita o se pone en UMS).

Usar la tarjeta SD es definitivamente la forma recomendada de compartir archivos en Android.

Sin embargo, me gustaría ir con una solución híbrida modificada que hace uso de startActivityForResult() y onActivityResult() (docs aquí ) en el lado del cliente para comunicar solicitudes CRUD (y obtener el Uri a los archivos de la tarjeta SD si es necesario ) Si no le importa crear una actividad simulada como un front-end a su servicio. Los clientes, una vez terminados con los archivos, pueden llamar a startActivityForResult() nuevo para alertar a la aplicación de los cambios.

Por supuesto esto se puede hacer con startService() / bindService() sin embargo no proporciona una manera fácil para que los clientes obtengan un resultado del estado especialmente si usted necesita IPC.

Aunque los proveedores de contenido / resolvers se sienten como la forma correcta de ir sobre las cosas, creo que es más para las solicitudes de dirección única específica para proporcionar / consumir contenido.

  • Implementar seguridad a nivel de firma en los servicios de Android con más de una firma permitida
  • Cómo obtener datos de un servicio sin consolidar en Android
  • ¿Por qué es posible escribir una matriz booleana en un paquete pero no en un booleano?
  • Cómo realizar la comprobación nula IPC manual
  • Transferir InputStream a otro servicio (a través de límites de proceso) con ParcelFileDescriptor.createPipe () falla con "EBADF (número de archivo incorrecto)"
  • Android IPC, servicio no obtener instanciado
  • Cada actividad en Android es un proceso o una aplicación es un proceso
  • ¿Cuáles son los mecanismos de IPC disponibles en el sistema operativo Android?
  • Android IPC y diferencias de ContentProvider
  • Lanzar una excepción personalizada de un servicio a una actividad
  • ¿Qué ocurre cuando la actividad se bloquea?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.