Inicio Android Google Drive en Android (3)

Google Drive en Android (3)

por sgoliver
drive-3

[mensaje-curso]

En los artículos anteriores de la serie sobre el uso de los servicios de Google Drive en Android hemos aprendido a crear y eliminar ficheros y carpetas, y a consultar y modificar el contenido y los metadatos de los ficheros. En este tercer artículo veremos cómo listar o consultar el contenido de una carpeta y cómo realizar búsquedas sobre una carpeta determinada o sobre la unidad completa. Adicionalmente, al final del artículo presentaré la  llamada Carpeta de Aplicación (o App Folder), una carpeta privada y no visible donde almacenar datos específicos de nuestra aplicación Android.

Vayamos por orden. Empezaremos por la opción de listar o consultar el contenido de una carpeta de Google Drive. Entre las operaciones proporcionadas por la API de Drive tenemos el método listChildren() con el que podemos obtener un listado de todos los archivos y carpetas (en realidad de sus metadatos) almacenados dentro de una carpeta. Lo utilizaremos como viene siendo habitual en artículos anteriores, llamaremos a listChildren() sobre una carpeta base, asignaremos un callback, e implementaremos su método onResult() para gestionar el resultado de la operación. Este resultado nos llegará en forma de objeto MetadataBufferResult, que encapsula el listado real al que podemos acceder a través de getMetadataBuffer(). Obtenido el listado podemos iterar sobre él para obtener los metadatos de cada uno de los elementos que contiene. En mi caso de ejemplo iré escribiendo el título de cada uno de ellos al log de Android:

private void listFolder(DriveId folderDriveId) {

    DriveFolder folder = folderDriveId.asDriveFolder();

    folder.listChildren(apiClient).setResultCallback(
        new ResultCallback<DriveApi.MetadataBufferResult>() {
            @Override
            public void onResult(DriveApi.MetadataBufferResult metadataBufferResult) {
                if (metadataBufferResult.getStatus().isSuccess()) {
                    for(Metadata m: metadataBufferResult.getMetadataBuffer())
                        Log.i(LOGTAG, "Fichero: " + m.getTitle() + " [" + m.getDriveId().encodeToString() + "]");
                }
                else {
                    Log.e(LOGTAG, "Error al listar carpeta");
                }
            }
        });
}

Si ejecutamos la aplicación y este método veríamos en el log el listado de ficheros y carpetas contenidos en la carpeta base sobre la que hayamos ejecutado, a partir de su DriveId, el método listChildren(). En mi caso había preparado una carpeta de prueba con tres ficheros:

  • prueba1.txt
  • prueba2.html
  • prueba3.css

Y como era de esperar, en el log veremos estos tres ficheros junto a su DriveId asociado:

demo-list-folder

La siguiente operación que describiremos será la búsqueda de elementos dentro de una carpeta determinada de Google Drive. Al igual que podemos listar el contenido completo de una carpeta, la API de Google Drive también nos ofrece la posibilidad de realizar una búsqueda dentro de una carpeta para recuperar sólo aquellos elementos que cumplan unas determinadas condiciones.

El criterio de búsqueda lo definiremos creando un objeto Query, el cual construiremos a partir de uno o varios filtros, objetos Filter, que representarán cada una de las condiciones que debe cumplir un elemento para formar parte de los resultados de la búsqueda. Cada filtro estará conformado por una operación y unos parámetros. Entre las condiciones podemos encontrar las más habituales:

  • Igual: Filter.eq()
  • Mayor/Menor que: Filter.greaterThan() y Filter.lessThan()
  • Mayor/Menor o igual que: Filter.graterThanEquals() y lessThanEquals()
  • Contiene: Filter.contains()
  • Contenido en el conjunto: Filter.in()

Y por supuesto operadores condicionales para combinar condiciones:

  • Y: Filter.and()
  • O: Filter.or()
  • No: Filter.not()

El primer parámetro de casi todas estas operaciones será un metadato y el segundo el valor con el que comparar dicho metadato. Así, por ejemplo, si queremos buscar los ficheros cuyo nombre sea «prueba2.html» podríamos construir la siguiente query:

Query query = 
    new Query.Builder()
        .addFilter(Filters.eq(SearchableField.TITLE, "prueba2.html"))
        .build();

Construida la query, ya tan sólo nos quedará llamar al método queryChildren() sobre una carpeta, pasándole como parámetro el objeto Query construido. Igual que siempre asignaremos un callback y gestionaremos los resultados en el evento onResult(). Al igual que ocurría al listar el contenido completo de una carpeta, el resultado de la consulta lo obtendremos en forma de objeto MetadataBufferResult, por lo que no insistiremos en cómo acceder a los resultados. Veamos cómo quedaría el código completo de un método de búsqueda sobre una carpeta:

private void searchFolder(DriveId folderDriveId) {

    DriveFolder folder = folderDriveId.asDriveFolder();

    Query query = new Query.Builder()
        .addFilter(Filters.eq(SearchableField.TITLE, "prueba2.html"))
        .build();

    folder.queryChildren(apiClient, query)
        .setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
            @Override
            public void onResult(DriveApi.MetadataBufferResult mdBufferResult) {
                if (mdBufferResult.getStatus().isSuccess()) {
                    if(mdBufferResult.getMetadataBuffer().getCount() > 0)
                        Log.i(LOGTAG, "Ficheros encontrados!");
                    else
                        Log.i(LOGTAG, "No se han encontrado ficheros!");

                    for(Metadata m: mdBufferResult.getMetadataBuffer())
                        Log.i(LOGTAG, "Fichero: " + m.getTitle() + " [" + m.getDriveId().encodeToString() + "]");
                }
                else {
                    Log.e(LOGTAG, "Error al buscar en carpeta");
                }
            }
        });
}

Igual de sencillo será buscar ficheros y carpetas en la unidad completa de Google Drive. La única diferencia será el método al que llamaremos para ello, que en esta ocasión será query() y lo llamaremos directamente sobre DriveApi en vez de sobre una carpeta determinada.

Para el nuevo ejemplo, construiré una query que localice todos aquellos ficheros cuyo nombre contenga el texto «prueba» y su MIME Type sea «text/css».

private void searchDrive() {

    Query query = new Query.Builder()
        .addFilter(Filters.and(
            Filters.eq(SearchableField.MIME_TYPE, "text/css"),
            Filters.contains(SearchableField.TITLE, "prueba")))
        .build();

    Drive.DriveApi.query(apiClient, query)
        .setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
            @Override
            public void onResult(DriveApi.MetadataBufferResult mdBufferResult) {
                if (mdBufferResult.getStatus().isSuccess()) {
                    if(mdBufferResult.getMetadataBuffer().getCount() > 0)
                        Log.i(LOGTAG, "Ficheros encontrados!");
                    else
                        Log.i(LOGTAG, "No se han encontrado ficheros!");

                    for(Metadata m: mdBufferResult.getMetadataBuffer())
                        Log.i(LOGTAG, "Fichero: " + m.getTitle() + " [" + m.getDriveId().encodeToString() + "]");
                }
                else {
                    Log.e(LOGTAG, "Error al buscar en carpeta");
                }
            }
        });
}

Con esto habríamos terminado con las operaciones más importantes que nos ofrece la API de Google Drive para Android. Pero como comentamos al principio de este artículo vamos a dedicar un par de minutos a hablar sobre la Carpeta de Aplicación o App Folder.

Hasta el momento, siempre hemos estado creando y gestionando ficheros o carpetas almacenados en la carpeta raíz de Drive o en alguna subcarpeta de ésta. Sin embargo, existe otra alternativa a la hora de guardar datos específicos de nuestra aplicación Android, como por ejemplo ficheros de configuración, ficheros temporales, u otros ficheros que pertenezcan al usuario de la aplicación pero que no nos convenga que puedan ser manipulados si no es por la propia aplicación. Esta alternativa se llama App Folder, o carpeta de aplicación, y no es más que una carpeta especial de Google Drive que tan sólo es accesible por la aplicación Android, es decir, su contenido no es visible accediendo a Google Drive ni puede ser utilizado por otras aplicaciones. Nota: aunque el contenido de esta carpeta no sea visible, el tamaño de los elementos almacenados en ella sí que cuentan de cara a la cuota de almacenamiento del usuario.

Para poder hacer uso de la App Folder lo primero que tendremos que hacer es añadir un nuevo scope (SCOPE_APPFOLDER) a la hora de crear nuestro cliente API. Así quedaría este cambio:

apiClient = new GoogleApiClient.Builder(this)
    .enableAutoManage(this, this)
    .addApi(Drive.API)
    .addScope(Drive.SCOPE_FILE)
    .addScope(Drive.SCOPE_APPFOLDER)
    .build();

Este cambio hará que al ejecutar la aplicación (solo la primera vez) se solicite automáticamente al usuario una nueva autorización para acceder al nuevo recurso añadido (la App Folder):

drive-permissions-2

Podemos utilizar la App Folder casi como cualquier otra carpeta normal, por ejemplo listado su contenido como hemos visto en este artículo o creado nuevos ficheros dentro de ella como vimos en el primer artículo de la serie. La única diferencia será la forma de obtener la carpeta base sobre la que queremos actuar, que ya no será la carpeta raíz de Drive ni ninguna subcarpeta de ésta. Para obtener una referencia a la App Folder usaremos el método getAppFolder() sobre DriveApi, de forma análoga a como llamamos a getRootFolder() para obtener la carpeta raíz. Veamos cómo quedaría un método completo para crear un nuevo fichero en la App Folder:

private void createFileAppFolder(final String filename) {

    Drive.DriveApi.newDriveContents(apiClient)
        .setResultCallback(new ResultCallback<DriveApi.DriveContentsResult>() {
            @Override
            public void onResult(DriveApi.DriveContentsResult result) {
                if (result.getStatus().isSuccess()) {

                    writeSampleText(result.getDriveContents());

                    MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                        .setTitle(filename)
                        .setMimeType("text/plain")
                        .build();

                    //Opción 3: Carpeta de Aplicación (App Folder)
                    DriveFolder folder = Drive.DriveApi.getAppFolder(apiClient);

                    folder.createFile(apiClient, changeSet, result.getDriveContents())
                        .setResultCallback(new ResultCallback<DriveFolder.DriveFileResult>() {
                            @Override
                            public void onResult(DriveFolder.DriveFileResult result) {
                                if (result.getStatus().isSuccess()) {
                                    Log.i(LOGTAG, "Fichero creado con ID = " + result.getDriveFile().getDriveId());
                                } else {
                                    Log.e(LOGTAG, "Error al crear el fichero");
                                }
                            }
                        });
                } else {
                    Log.e(LOGTAG, "Error al crear DriveContents");
                }
            }
        });
}

Como podéis ver es completamente análogo al método que ya describimos en detalle en el primer artículo de este serie.

Por último, como curiosidad, si creamos ficheros o carpetas dentro de la App Folder, aunque éstos no sean visibles desde Google Drive sí que podemos consultar cuánto espacio ocupan de nuestra cuota. Para ello, nos dirigimos en primer lugar a las opciones de configuración de Drive, en la esquina superior derecha:

configuracion-drive-1

Una vez dentro, pulsamos sobre la sección «Administrar aplicaciones» y buscamos el nombre de nuestra aplicación dentro del listado que aparecerá a la derecha. Bajo el nombre, podremos comprobar cuánto ocupan los ficheros almacenados en la carpeta App Folder de nuestra aplicación (indicado como «Datos de aplicación ocultos»):

configuracion-drive-2

Y con esto finalizamos por ahora la serie sobre la API de Google Drive para Android.

Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la página del curso en GitHub.

[mensaje-curso]

También te puede interesar

2 comentarios

Google Drive en Android [Serie] | sgoliver.net 05/10/2016 - 18:16

[…] Google Drive en Android (3) [Act. Septiembre 2016] […]

Responder
tor 29/05/2017 - 7:26

active el api drive en google
Hice los tres ejemplos de drive , pero en los tres me sale el mismo error ,
error en la conexion. ¿ que puede ser ?

Responder

Dejar un comentario

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información. Aceptar Más Información

Política de Privacidad y Cookies