Cómo conectarse a Google Drive* desde una aplicación Android*

Descarga de código fuente

En este ejemplo se muestra cómo conectarse al servicio de almacenamiento en línea Google Drive* de una persona desde una aplicación Android*. Describiré las secciones de código que se ejecutan de acuerdo con el flujo de uso de la aplicación. Está aplicación se basa en el ejemplo de Google Drive que se encuentra aquí. Antes de comenzar a armar este ejemplo, se recomienda seguir las instrucciones del enlace anterior para registrar la aplicación en Google Cloud Console.

Como la mayoría de las aplicaciones Android, esta comienza con la función onCreate de MainActivity. En esta función, se puede ver que las credenciales para conectarse a la cuenta de Google Drive están configuradas y se ha iniciado una actividad para pedir al usuario que seleccione su cuenta de Google de entre las cuentas registradas en el dispositivo o que ingrese una nueva.

mCredential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(DriveScopes.DRIVE));
        startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);


Después de esto, la función pasa a configurar los procesos de los botones y el de ListView.

Ahora que la interfaz de usuario básica está configurada, la aplicación espera la intervención del usuario por medio de los botones de carga y descarga. Si el usuario presiona el botón de descarga, el OnClickListener de ese botón inicia un Intent que permite al usuario seleccionar la aplicación para tomar archivos multimedia del espacio de almacenamiento del dispositivo.


final Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() 
{
	public void onClick(View v) 
	{
	final Intent galleryIntent = new Intent(Intent.ACTION_PICK);
	galleryIntent.setType("*/*");
	startActivityForResult(galleryIntent, RESULT_STORE_FILE);
	}
});

 

 

Dado que el Intent se inició con startActivityForResult, después de su respuesta, a la función onActivityResult de la actividad principal se la llamará con RESULT_STORE_FILE. El identificador de recurso uniforme (URI) del archivo seleccionado por el usuario se puede obtener desde data.getData().


protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) 
{
	switch (requestCode) 
	{
		…
		case RESULT_STORE_FILE:
			mFileUri = data.getData();
			// Save the file to Google Drive
        		saveFileToDrive();
			break;
	}
}

Con este URI, el archivo se puede guardar en Drive, lo cual se hace con la llamada a saveFileToDrive(). Todas las comunicaciones a la cuenta de Drive con las API de Drive se hacen en un nuevo subproceso para garantizar que no ralentice el subproceso de la interfaz de usuario principal, lo cual causaría que esta se hiciera más lenta y tardase más en responder.


private void saveFileToDrive() 
{
Thread t = new Thread(new Runnable() 
    	{
    		@Override
    		public void run() 
    		{
			…
    		}
    	});
    	t.start();
}


Dentro de la función de ejecución, se crea un nuevo URI a partir de la ruta real al contenido de los archivos multimedia. Esto se debe a que la ruta asociada con el URI devuelto del Intent Gallery es una ruta de acceso virtual que no funciona con la función de carga de la API de Google Drive. Aquí obtenemos la ruta física y creamos un nuevo URI a partir de ella para realizar cargas a Google Drive.


// Create URI from real path
String path;
path = getPathFromUri(mFileUri);
mFileUri = Uri.fromFile(new java.io.File(path));
…
	java.io.File fileContent = new java.io.File(mFileUri.getPath());

Se crean las variables FileContent y File para pasar a las API de Google Drive y cargar el contenido del archivo al Google Drive del usuario. Se crea un objeto File a partir del objeto Service creado en OnCreate y se usa su función Insert para preparar el contenido del archivo multimedia que se va a cargar. Luego se llama a execute para insertar el contenido en Google Drive en la nube.


FileContent mediaContent = new FileContent(cR.getType(mFileUri), fileContent);
// File's meta data. 
File body = new File();
body.setTitle(fileContent.getName());
body.setMimeType(cR.getType(mFileUri));
com.google.api.services.drive.Drive.Files f1 = mService.files();
com.google.api.services.drive.Drive.Files.Insert i1 = f1.insert(body, mediaContent);
File file = i1.execute();


En este punto, ha finalizado la carga y el usuario puede ver el archivo en la carpeta raíz de su cuenta de Google Drive.

A continuación, el usuario puede seleccionar el botón de descarga. Cuando lo hace, se llama a la función getDriveContents.


final Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener()
{
	public void onClick(View v) 
	{
	getDriveContents();
	}
});


getDriveContents inicia un nuevo subproceso para descargar una lista de nombres de archivos y todo el contenido de la cuenta de Google Drive.


private void getDriveContents()
{
	Thread t = new Thread(new Runnable() 
	{
		@Override
		public void run() 
		{
			mResultList = new ArrayList(); … } }); t.start(); } 

Dentro de getDriveContents, se establece un objeto FileList y se lo usa para solicitar una lista de archivos. Para no recibir una lista con todos los objetos de la carpeta raíz y todos los objetos de la papelera, el valor Q se establece como la cadena de caracteres “trashed=false”. Después de que se han obtenido todas las páginas de datos de archivos y se las ha guardado en ArrayList de Files, se rellena ListView en la interfaz de usuario para mostrar a los usuarios qué archivos hay para descargar en su cuenta de Google Drive.


com.google.api.services.drive.Drive.Files f1 = mService.files();
com.google.api.services.drive.Drive.Files.List request = null;
				
do 
{
	try 
	{ 
		request = f1.list();
		request.setQ("trashed=false");
		com.google.api.services.drive.model.FileList fileList = request.execute();
						
		mResultList.addAll(fileList.getItems());

		request.setPageToken(fileList.getNextPageToken());
	} catch (UserRecoverableAuthIOException e) {
		startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
	} catch (IOException e) {
		e.printStackTrace();
		if (request != null)
		{
		request.setPageToken(null);
		}
	}
} while (request.getPageToken() !=null && request.getPageToken().length() > 0);
				
populateListView();

populateListView toma los nombres de los archivos de ArrayList y los guarda en una matriz simple de cadenas de caracteres. Se pueden usar con un ArrayAdapter o para rellenar ListView. Cuando ListView ya se rellenó, la aplicación espera una nueva intervención del usuario.

 

 

En este punto, el usuario puede seleccionar un nombre de archivo de ListView y se llamará a su función OnItemClickListener para que se encargue de la selección.


OnItemClickListener mMessageClickedHandler = new OnItemClickListener() 
{
	public void onItemClick(AdapterView parent, View v, int position, long id) 
	{
		downloadItemFromList(position);
	}
};

Ahora se llama a downloadItemFromList con la posición seleccionada en la lista. Se inicia un nuevo subproceso debido a que se producirá una nueva comunicación con Google Drive. Cuando la selección de ListView se asocia con el archivo correspondiente de la ArrayList de Files, ese archivo en particular tiene una dirección URL de descarga que se puede usar para establecer una petición (Request) de respuesta de HTTP. Una vez establecida, se puede llamar a execute para iniciar la descarga del contenido del archivo. El contenido del archivo se devuelve en la forma de un InputStream.


com.google.api.client.http.HttpResponse resp = 
	mService.getRequestFactory()
	.buildGetRequest(new GenericUrl(tmp.getDownloadUrl()))
	.execute();
InputStream iStream = resp.getContent();
try 
{
	final java.io.File file = new java.io.File(Environment
		.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath(), 
		tmp.getTitle());
	showToast("Downloading: " + tmp.getTitle() + " to " + Environment
	.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath());
	storeFile(file, iStream);
} finally {
	iStream.close();
}

Este InputStream se puede usar junto con un OutputStream para guardar el archivo en un directorio del espacio de almacenamiento interno o externo (tarjeta SD) del dispositivo.


private void storeFile(java.io.File file, InputStream iStream)
{
	try 
	{
		final OutputStream oStream = new FileOutputStream(file);
		try
		{
			try
			{
				final byte[] buffer = new byte[1024];
				int read;
				while ((read = iStream.read(buffer)) != -1)
				{
					oStream.write(buffer, 0, read);
				}
				oStream.flush();
			} finally {
				oStream.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
}

Once the file is written to storage, the user can select to download another file or upload a new one.

Cuando ya se ha escrito el archivo en el espacio de almacenamiento, el usuario puede seleccionar descargar otro archivo o cargar uno nuevo. La API de Drive ofrece muchas más posibilidades que se pueden usar para escribir fascinantes aplicaciones Android que interactúen con las cuentas de Google Drive del usuario. Se puede encontrar más información de las API de Google Drive en: https://developers.google.com/drive/v2/reference/.

Biografía y foto del autor

Gideon forma parte del Grupo de Software y Servicios de Intel. Trabaja con proveedores de software independientes y los ayuda a optimizar sus productos para procesadores Intel® Atom™. En el pasado, trabajó en un equipo que escribió controladores gráficos de Linux* para plataformas con Android OS.

 

Para obtener información más completa sobre las optimizaciones del compilador, consulte nuestro Aviso de optimización.
AdjuntoTamaño
Icono de paquete googledriveapp.zip105.71 KB