martes, 10 de enero de 2017

Google Drive en Android (2)

En el artículo anterior de esta serie sobre los servicios de Google Drive en Android ya vimos cómo configurar un nuevo proyecto en la consola de desarrolladores añadiendo la API de Drive para Android, y cómo realizar en nuestra aplicación las operaciones básicas de creación y eliminación de ficheros y carpetas.
En este segundo artículo vamos a seguir profundizando en las funcionalidades que proporciona este servicio, y empezaremos por cómo consultar y modificar los metadatos de un fichero o carpeta ya existente.
La consulta de los metadatos de un fichero o carpeta seguirá una vez más el mismo esquema que las operaciones que ya conocemos. En primer lugar llamaremos al método getMetadata() sobre el objeto DriveFile o DriveFolder que queramos consultar. Asignaremos un callback (ResultCallback) e implementaremos su método onResult() para ser notificado cuando finalice la operación. Si el resultado es correcto (getStatus().isSuccess())  podremos obtener los metadatos mediante el método getMetadata() del objeto MetadataResult recibido como parámetro, y a partir de éste cualquier dato concreto que necesitemos, por ejemplo su nombre (con getTitle()) o su fecha de última actualización (con getModifiedDate()). Podéis consultar el listado completo de métodos disponibles para recuperar cada metadato en la documentación de la clase MetadataResult.
Veamos cómo quedaría un método que recupere los metadatos de un fichero a partir de su DriveId:
Modificar los metadatos de un fichero/carpeta es tan sencillo como consultarlos. Crearemos en primer lugar un objeto MetadataChangeSet con los cambios que queramos realizar en los metadatos, igual que hacíamos para crear un fichero nuevo. Una vez definidos los metadatos que queremos actualizar, llamaremos al método updateMetadata() pasándole como parámetros el conjunto de metadatos creados, asignaremos el callback habitual y revisaremos dentro del método onResult() que la operación ha finalizado correctamente.
Un método que actualizará por ejemplo el título de un fichero a partir de su DriveId quedaría de la siguiente forma:
Al igual que podemos consultar y modificar los metadatos también podremos, por supuesto, consultar y modificar el contenido de un fichero ya existente.
Tanto para leer como para escribir un fichero de Google Drive tendremos primero que abrirlo, indicando el modo de apertura correspondiente (apertura para leer o para escribir). Tras la apertura del fichero podremos acceder a su contenido (recordemos, objeto DriveContents), a partir del cual obtendremos su stream en entrada o salida asociado, sobre el que podremos utilizar la API estándar de Java para la lectura/escritura de ficheros.
Detallemos en primer lugar el proceso de lectura de un fichero. Comenzaremos llamando al método open() sobre el fichero (DriveFile). Como parámetro del método open() pasaremos el modo de acceso de lectura (DriveFile.MODE_READ_ONLY). Asignaremos el callback correspondiente y en el método onResult(), tras comprobar que la operación de apertura se ha realizado correctamente, llamaremos a getDriveContents() sobre el resultado recibido para obtener una referencia al contenido del fichero. Tras esto construiremos un objeto BufferedReader (api estandar java.io) a partir del stream de entrada asociado al contenido, que obtenemos llamando a getInputStream(). En mi caso de ejemplo accederé a ficheros de texto, por lo que podemos leer el contenido linea a linea utilizando el método readLine(). Por último, llamamos al método discard() del objeto DriveContents para cerrar todos los recursos abiertos.
Se muestra a continuación el código completo de un método de lectura de ficheros de texto almacenados en Drive a partir de su DriveId:
La escritura sobre un fichero ya existente es prácticamente análoga. Comenzamos nuevamente abriendo el fichero llamando al método open()pasándole esta vez el modo de acceso de escritura DriveFile.MODE_WRITE_ONLY. En el onResult() del callback asignado obtenemos una referencia al contenido del fichero mediante getDriveContents() y creamos un objeto BufferedWriter a partir de su stream de salida asociado, que obtenemos mediante getOutputStream(). Escribimos el texto deseado al fichero (insisto, en mi caso de ejemplo es texto, pero podría ser cualquier contenido), y por último llamamos al método commit() sobre el objeto DriveContents para confirmar los cambios realizados. Sobre el método commit() también podemos asignar un nuevo callback para verificar que se realiza correctamente. También indicar que opcionalmente, junto con el cambio de contenido del fichero, también podremos actualizar los metadatos del mismo definiendo previamente un objeto MetadadataChangeSet y pasándoselo como parametro al método commit(). Veamos un ejemplo completo que actualiza el contenido de un fichero almacenado en Google Drive a partir de su DriveId:
Por último vamos comentar una alternativa a la hora de abrir ficheros de Drive. Al igual que ocurre para crear ficheros, la API de Google Drive para Android también nos ofrece una actividad predefinida para poder seleccionar un fichero de la cuenta de Google Drive del usuario logueado. Esta actividad permitirá al usuario seleccionar un fichero de su cuenta y nos devolverá como resultado, entre otras cosas, su DriveId asociado. Con este DriveIdpodremos leer o escribir el contenido del fichero con cualquiera de los dos métodos implementados anteriormente. Veamos cómo hacerlo.
De forma análoga a la actividad de creación de ficheros, lo primero que haremos será el IntentSender con el que lanzaremos la actividad. Utilizaremos para ello el método newOpenFileActivityBuilder() de la API de Drive. Tenemos la posibilidad de filtrar los ficheros que se mostrarán al usuario por su tipo de contenido (MIME Type) mediante el método setMimeType() del builder, que recibi un array con los tipos visualizables. Así, si por ejemplo queremos que sólo se puedan seleccionar fichero de texto plano podemos llamar a setMimeType(new String[] { “text/plain” }). También podemos personalizar el título de la actividad mostrada mediante setActivityTitle() o la carpeta inicial mediante setActivityStartFolder().
Construido el IntentSender lanzamos la actividad llamando a startIntentSenderForResult() pasándole como parámetro una constante arbitraria identificativa de la operación, en mi caso llamada REQ_OPEN_FILE. El resultado de esta acción lo recibiremos en el método onActivityResult() de la actividad principal y lo identificaremos por su constante identificativa. Dentro de dicho método podremos obtener el DriveId del fichero seleccionado accediento al extra del intent recibido como parámetro con el identificador OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID. Una vez obtenido el DriveId del fichero podremos por ejemplo leer su contenido llamando a nuestro método auxiliar readFile() que ya describimos anteriormente:
Si ejecutamos la aplicación de ejemplo y lanzamos el método anterior podremos ver cómo la aplicación nos muestra la actividad siguiente de selección de ficheros:
open-file-activity
Y con esto terminaríamos con el apartado de operaciones de lectura y escritura de metadatos y contenido de ficheros almacenados en Drive desde Android.

No hay comentarios:

Publicar un comentario