Android abra y guarde archivos en / de Google Drive SDK

He pasado las últimas seis horas revisando documentos de Google y todavía no sé cómo comenzar con esto. Todo lo que quiero hacer es hacerlo para que mi aplicación Android existente pueda leer archivos de Google Drive, subir nuevos archivos a Google Drive y editar archivos existentes en Google Drive.

He leído que Drive SDK v2 se enfoca únicamente en facilitar el uso de los desarrolladores de Android (y el móvil en general), y sin embargo, parece que no hay prácticamente nada en su documentación al respecto.

Idealmente, quisiera que alguien me señale una documentación decente, un ejemplo o un tutorial sobre cómo hacerlo (tenga en cuenta que estoy usando Android. Tienen muchas cosas sobre cómo usar Drive con Google App Engine; ya lo he visto y no tengo idea de cómo pasar de eso a una aplicación de Android).

Necesito saber qué bibliotecas necesito descargar y agregar a mi proyecto, qué necesito agregar a mi manifiesto, y cómo finalmente puedo obtener una lista de archivos de Google Drive, descargar uno y luego subir una versión modificada.

Idealmente, me gustaría manejar las cuentas automáticamente, de la forma en que lo hace la aplicación oficial de Google Drive.

Editar: Claudio Cherubino dice que Google Play Services ya está disponible y que hará que este proceso sea mucho más fácil. Sin embargo, no hay un código de muestra disponible (sin embargo, él dice que llegará pronto … dijeron que Google Play Services “llegaría pronto” hace 4 meses, por lo que hay muchas posibilidades de que esta respuesta continúe siendo el único ejemplo completamente funcional de acceso Google Drive desde su aplicación Android en 2013.)

Editar 2X: Parece que estuve fuera por alrededor de un mes cuando dije que Google no tendría un ejemplo de trabajo hasta el próximo año. La guía oficial de Google está aquí:

https://developers.google.com/drive/quickstart-android

Aún no he probado sus métodos, por lo que es posible que mis soluciones de septiembre de 2012 (abajo) sigan siendo las mejores:

Google Play Services NO ES NECESARIO para esto. Es un dolor en el trasero, y pasé más de 50 horas (editar: más de 100 horas) averiguándolo todo, pero hay muchas cosas que te ayudarán a saber:

LAS BIBLIOTECAS

Para los servicios en línea de Google en general, necesitará estas bibliotecas en su proyecto: ( Instrucciones y Enlace de descarga )

  • google-api-client-1.11.0-beta.jar
  • google-api-client-android-1.11.0-beta.jar
  • google-http-client-1.11.0-beta.jar
  • google-http-client-android-1.11.0-beta.jar
  • google-http-client-jackson-1.11.0-beta.jar
  • google-oauth-client-1.11.0-beta.jar
  • guava-11.0.1.jar
  • jackson-core-asl-1.9.9.jar
  • jsr305-1.3.9.jar

Para Google Drive en particular, también necesitará esto:

  • google-api-services-drive-v2-rev9-1.8.0-beta.jar ( Enlace de descarga )

CONFIGURAR LA CONSOLA

Luego, ve a Google Console . Haz un nuevo proyecto. En Servicios, deberás activar dos cosas: DRIVE API y DRIVE SDK . Están separados, uno no enciende automáticamente el otro y ¡ DEBE ENCENDERLO! (Calcular esto desperdicia al menos 20 horas de mi tiempo a solas).

Aún en la consola, vaya a Acceso a la API. Crea un cliente, conviértelo en una aplicación de Android. Dale tu ID de paquete. No creo que las huellas dactilares sean realmente importantes, ya que estoy bastante seguro de que utilicé la correcta, pero de todas maneras trato de hacerlo bien (Google proporciona instrucciones para ello).

Generará una ID de cliente . Vas a necesitar eso. Aferrate a ello.

Editar: me han dicho que me equivoco y que solo necesita activar Drive API, Drive SDK no necesita encenderse en absoluto, y que solo necesita usar la clave de API simple, no establecida algo para Android Estoy investigando eso ahora y probablemente edite esta respuesta en unos minutos si lo resuelvo …

EL CÓDIGO ANDROID – Configurar y cargar

Primero, obtenga un token de autenticación:

AccountManager am = AccountManager.get(activity); am.getAuthToken(am.getAccounts())[0], "oauth2:" + DriveScopes.DRIVE, new Bundle(), true, new OnTokenAcquired(), null); 

A continuación, OnTokenAcquired () debe configurarse de la siguiente manera:

 private class OnTokenAcquired implements AccountManagerCallback { @Override public void run(AccountManagerFuture result) { try { final String token = result.getResult().getString(AccountManager.KEY_AUTHTOKEN); HttpTransport httpTransport = new NetHttpTransport(); JacksonFactory jsonFactory = new JacksonFactory(); Drive.Builder b = new Drive.Builder(httpTransport, jsonFactory, null); b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() { @Override public void initialize(JSonHttpRequest request) throws IOException { DriveRequest driveRequest = (DriveRequest) request; driveRequest.setPrettyPrint(true); driveRequest.setKey(CLIENT ID YOU GOT WHEN SETTING UP THE CONSOLE BEFORE YOU STARTED CODING) driveRequest.setOauthToken(token); } }); final Drive drive = b.build(); final com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File(); body.setTitle("My Test File"); body.setDescription("A Test File"); body.setMimeType("text/plain"); final FileContent mediaContent = new FileContent("text/plain", an ordinary java.io.File you'd like to upload. Make it using a FileWriter or something, that's really outside the scope of this answer.) new Thread(new Runnable() { public void run() { try { com.google.api.services.drive.model.File file = drive.files().insert(body, mediaContent).execute(); alreadyTriedAgain = false; // Global boolean to make sure you don't repeatedly try too many times when the server is down or your code is faulty... they'll block requests until the next day if you make 10 bad requests, I found. } catch (IOException e) { if (!alreadyTriedAgain) { alreadyTriedAgain = true; AccountManager am = AccountManager.get(activity); am.invalidateAuthToken(am.getAccounts()[0].type, null); // Requires the permissions MANAGE_ACCOUNTS & USE_CREDENTIALS in the Manifest am.getAuthToken (same as before...) } else { // Give up. Crash or log an error or whatever you want. } } } }).start(); Intent launch = (Intent)result.getResult().get(AccountManager.KEY_INTENT); if (launch != null) { startActivityForResult(launch, 3025); return; // Not sure why... I wrote it here for some reason. Might not actually be necessary. } } catch (OperationCanceledException e) { // Handle it... } catch (AuthenticatorException e) { // Handle it... } catch (IOException e) { // Handle it... } } } 

EL CÓDIGO ANDROID – Descarga

 private java.io.File downloadGFileToJFolder(Drive drive, String token, File gFile, java.io.File jFolder) throws IOException { if (gFile.getDownloadUrl() != null && gFile.getDownloadUrl().length() > 0 ) { if (jFolder == null) { jFolder = Environment.getExternalStorageDirectory(); jFolder.mkdirs(); } try { HttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet(gFile.getDownloadUrl()); get.setHeader("Authorization", "Bearer " + token); HttpResponse response = client.execute(get); InputStream inputStream = response.getEntity().getContent(); jFolder.mkdirs(); java.io.File jFile = new java.io.File(jFolder.getAbsolutePath() + "/" + getGFileName(gFile)); // getGFileName() is my own method... it just grabs originalFilename if it exists or title if it doesn't. FileOutputStream fileStream = new FileOutputStream(jFile); byte buffer[] = new byte[1024]; int length; while ((length=inputStream.read(buffer))>0) { fileStream.write(buffer, 0, length); } fileStream.close(); inputStream.close(); return jFile; } catch (IOException e) { // Handle IOExceptions here... return null; } } else { // Handle the case where the file on Google Drive has no length here. return null; } } 

Una última cosa … si ese bash es enviado, necesitarás manejarlo cuando regrese con un resultado.

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 3025) { switch (resultCode) { case RESULT_OK: AccountManager am = AccountManager.get(activity); am.getAuthToken(Same as the other two times... it should work this time though, because now the user is actually logged in.) break; case RESULT_CANCELED: // This probably means the user refused to log in. Explain to them why they need to log in. break; default: // This isn't expected... maybe just log whatever code was returned. break; } } else { // Your application has other intents that it fires off besides the one for Drive's log in if it ever reaches this spot. Handle it here however you'd like. } } 

EL CÓDIGO ANDROID – Actualización

Dos notas rápidas sobre la actualización de la última fecha de modificación de un archivo en Google Drive:

  1. Debe proporcionar un DateTime completamente inicializado. Si no lo hace, obtendrá una respuesta de “Solicitud incorrecta” de Google Drive.
  2. Debe usar setModifiedDate () en el archivo de Google Drive y setSetModifiedDate (true) en la solicitud de actualización. (Nombre divertido, ¿eh? “SetSet […]”, no hay manera de que la gente pueda confundir ese …)

Aquí hay un breve código de muestra que muestra cómo hacer una actualización, incluida la actualización de la hora del archivo:

 public void updateGFileFromJFile(Drive drive, File gFile, java.io.File jFile) throws IOException { FileContent gContent = new FileContent("text/csv", jFile); gFile.setModifiedDate(new DateTime(false, jFile.lastModified(), 0)); gFile = drive.files().update(gFile.getId(), gFile, gContent).setSetModifiedDate(true).execute(); } 

EL MANIFIESTO

Necesitará los siguientes permisos: GET_ACCOUNTS, USE_CREDENTIALS, MANAGE_ACCOUNTS, INTERNET, y existe la posibilidad de que necesite WRITE_EXTERNAL_STORAGE también, dependiendo de dónde desee almacenar las copias locales de sus archivos.

SU OBJETIVO DE CONSTRUCCIÓN

Haz clic con el botón derecho en tu proyecto, ve a sus propiedades y, en Android, cambia el objective de comstackción a las API de Google, si es necesario. Si no están allí, descárguelos del administrador de descargas de Android.

Si está probando un emulador, asegúrese de que su objective sea Google API, no Android genérico.

Necesitará una cuenta de Google configurada en su dispositivo de prueba. El código tal como está escrito usará automáticamente la primera cuenta de Google que encuentre (eso es lo que [0] es). IDK si necesita haber descargado la aplicación Google Drive para que esto haya funcionado. Estaba usando API Nivel 15, no sé cuánto tiempo atrás funcionará este código.

EL RESTO

Lo anterior debería hacerte comenzar y con suerte puedes encontrar la manera de salir de allí … honestamente, esto es todo lo lejos que he llegado hasta ahora. Espero que esto ayude MUCHAS personas y les ahorre MUCHO tiempo. Estoy bastante seguro de que acabo de escribir la guía de configuración más completa para configurar una aplicación de Android para usar Google Drive. Es una pena que Google distribuya el material necesario en al menos 6 páginas diferentes que no se vinculan entre sí.

Consulte este video de Google I / O para aprender cómo integrar su aplicación de Android con Drive:

http://www.youtube.com/watch?v=xRGyzqD-vRg

Tenga en cuenta que lo que ve en el video está basado en los Servicios de Google Play , que aún no se lanzó al público en general :

https://developers.google.com/android/google-play-services/

Es 2015, ¡las cosas han cambiado!

Obtenga la ‘Drive API para Android’ con gradle:

 compile 'com.google.android.gms:play-services-drive:7.8.0' 

Hay un nuevo doco (aunque todavía es mediocre IMO):

https://developers.google.com/drive/web/quickstart/android

Y para aquellos a punto de ir a la espeleología … el mayor problema que he encontrado hasta ahora es que no hay forma de distinguir las carpetas que han sido eliminadas permanentemente de las carpetas que son normales … puedes encontrarlas, puedes crear carpetas y archivos dentro de ellos, solo escribir en el archivo DriveContents siempre fallará.

Eche un vistazo al ejemplo de DrEdit de Google, que tiene una carpeta llamada android/ . Cópialo, sigue el readme y debería funcionar (funciona para mí en un emulador de Android con KitKat).

.

PD

Perdón por revivir esto, pero la nueva API de Google Drive para Android no es compatible con el acceso total a Drive, solo con los ámbitos de autorización drive.file y drive.appdata , por lo que si necesita acceso total, debe volver al buen cliente de la API de Google. para Java (que usa el ejemplo DrEdit).