tutorial studio para google documentos desarrolladores android google-drive-sdk google-drive-android-api

studio - Android Drive API Error de carpeta principal no válida



google drive para desarrolladores (2)

Utilicé Android Drive Api para cargar mis archivos en Drive. Creé una carpeta ("NewFolder") en la raíz de Google Drive y creé una carpeta interna ("InnerFolder") en mi "NewFolder" desde la aplicación de Android usando el siguiente código. Luego escribo mis archivos en este "InnerFolder" desde mi aplicación de Android.

Mi aplicación crea el "InnerFolder" en la primera instalación en mi dispositivo solamente. Luego, desinstale y vuelva a instalar la aplicación. No volverá a crear la carpeta (identificador de unidad de la carpeta creada almacenada (como DriveId: yrjundeen12cnfe) en el archivo local).

Mi código funciona bien en la primera instalación. Pero si desinstalo y vuelvo a instalar la aplicación muchas veces y trato de subirlo a Google Drive, recibí un error como "carpeta principal no válida" en el método de devolución de llamada de createFile.

Código de creación de la primera carpeta:

private void createGalleryFolder() { DriveFolder folder = Drive.DriveApi.getRootFolder(googleApiClient); MetadataChangeSet changeSet = new MetadataChangeSet.Builder() .setTitle(AppConstants.DEFAULT_GALLERY_NAME).build(); folder.createFolder(googleApiClient, changeSet).setResultCallback( createRootFolderCallback); } final ResultCallback<DriveFolderResult> createRootFolderCallback = new ResultCallback<DriveFolderResult>() { @Override public void onResult(DriveFolderResult result) { if (!result.getStatus().isSuccess()) { showError(); return; } // Root folder created Successfully DriveId mFolderDriveId = result.getDriveFolder().getDriveId(); AppUtilities.saveOnLocalFile(mFolderDriveId, AppConstants.ROOT_FOLDER_ID_FILE); if (!deviceID.equalsIgnoreCase("")) { DriveFolder folder = Drive.DriveApi.getFolder(googleApiClient, result.getDriveFolder().getDriveId()); MetadataChangeSet changeSet = new MetadataChangeSet.Builder() .setTitle(deviceID).build(); folder.createFolder(googleApiClient, changeSet) .setResultCallback(createInnerFolderCallback); } else { showError(); } } }; final ResultCallback<DriveFolderResult> createInnerFolderCallback = new ResultCallback<DriveFolderResult>() { @Override public void onResult(DriveFolderResult result) { if (!result.getStatus().isSuccess()) { showError(); return; } // IMEI folder created successfully inside the Root folder DriveId mFolderDriveId = result.getDriveFolder().getDriveId(); AppUtilities.saveOnLocalFile(mFolderDriveId, AppConstants.INNER_FOLDER_ID_FILE); // Success } };

Código de carga de archivos:

private void saveFileToDrive(final Bitmap bitmapToSave,final File imageFile,final String imageName) { Drive.DriveApi.newDriveContents(googleApiClient).setResultCallback(driveContentsCallback); } final private ResultCallback<DriveContentsResult> driveContentsCallback = new ResultCallback<DriveContentsResult>() { @Override public void onResult(DriveContentsResult result) { if(!result.getStatus().isSuccess()){ Log.i("Test1", "Failed to create new contents"); return; } Log.i("Test1", "New contents created"); //Write image data to OutputStream OutputStream outputStream = result.getDriveContents().getOutputStream(); ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream(); bitmapToSave.compress(Bitmap.CompressFormat.JPEG, 100, bitmapStream); try { outputStream.write(bitmapStream.toByteArray()); DriveFolder folder = Drive.DriveApi.getFolder(googleApiClient, DriveId.decodeFromString(getFolderDriveID())); MetadataChangeSet changeSet = new MetadataChangeSet.Builder() .setTitle(imageName) .setMimeType("image/jpeg") .setStarred(false).build(); folder.createFile(googleApiClient, changeSet, result.getDriveContents()).setResultCallback(fileCallback); } catch (IOException e) { Log.i("Test1","Unable to write file contents"); } } }; final private ResultCallback<DriveFileResult> fileCallback = new ResultCallback<DriveFileResult>() { @Override public void onResult(DriveFileResult result) { if (!result.getStatus().isSuccess()) { Log.i("Test1","Error while trying to create the file "+result.getStatus().getStatusMessage()); return; } Log.i("Test1","Created a file: " + result.getDriveFile().getDriveId()); result.getDriveFile().getMetadata(googleApiClient).setResultCallback(fileUploadedResultCallback); } }; final private ResultCallback<MetadataResult> fileUploadedResultCallback = new ResultCallback<MetadataResult>() { @Override public void onResult(MetadataResult result) { if(!result.getStatus().isSuccess()){ Log.i("Test1", "Failed to upload"); return; } Log.i("Test1", "File uploaded"); } };

Error en ResultCallback:

D/dalvikvm( 584): threadid=50: interp stack at 0x549a5000 D/dalvikvm( 584): threadid=50: calling run() I/Test1 ( 813): Image added --------- beginning of /dev/log/system D/ActivityThread( 584): SVC-CREATE_SERVICE handled : 0 / CreateServiceData{token=android.os.BinderProxy@415dbf40 className=com.google.android.gms.drive.api.DriveAsyncService packageName=com.google.android.gms intent=null} D/ActivityThread( 584): SVC-Calling onStartCommand: com.google.android.gms.drive.api.DriveAsyncService@415b6480, flags=2, startId=1 D/ActivityThread( 584): SVC-SERVICE_ARGS handled : 0 / ServiceArgsData{token=android.os.BinderProxy@415dbf40 startId=1 args=Intent { act=com.google.android.gms.drive.EXECUTE pkg=com.google.android.gms }} W/DataServiceConnectionImpl( 584): Could not find entry, and no valid resource id: DriveId:CAESABgGIMq7nNDgUg== E/DriveAsyncService( 584): Invalid parent folder. E/DriveAsyncService( 584): OperationException[Status{statusCode=Invalid parent folder., resolution=null}] E/DriveAsyncService( 584): at com.google.android.gms.drive.api.e.e(SourceFile:619) E/DriveAsyncService( 584): at com.google.android.gms.drive.api.e.a(SourceFile:458) E/DriveAsyncService( 584): at com.google.android.gms.drive.api.a.n.a(SourceFile:82) E/DriveAsyncService( 584): at com.google.android.gms.drive.api.a.b.a(SourceFile:27) E/DriveAsyncService( 584): at com.google.android.gms.common.service.c.onHandleIntent(SourceFile:60) E/DriveAsyncService( 584): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) E/DriveAsyncService( 584): at android.os.Handler.dispatchMessage(Handler.java:99) E/DriveAsyncService( 584): at android.os.Looper.loop(Looper.java:154) E/DriveAsyncService( 584): at android.os.HandlerThread.run(HandlerThread.java:65) I/Test1 ( 813): Error while trying to create the file Invalid parent folder.


No confíe en DriveId de GDAA para almacenar en caché o posiblemente direccionar objetos de Drive (archivo / carpeta) más allá de la aplicación y el alcance del dispositivo. Esta ID proviene de la instancia de Servicios de Google Play en su dispositivo (por lo que no es válida en otro dispositivo que utilice la misma aplicación, incluso si el archivo / carpeta aún está visible en el alcance de ARCHIVO). Recuerdo vagamente "perderlo" incluso al borrar el caché de Google Play Services (GooPS) o incluso al volver a instalar GooPS. Pero esto podría haber sido arreglado. Mi último encuentro con GDAA fue hace unos meses.

En su lugar, hay un ''ResourceId'', que se utiliza en RESTFul API (conocido como simple ''id'') - ver SO 21800257 . Esta cadena representa de forma única el objeto Drive y puede ser portada y utilizada en cualquier lugar (incluso forma parte de la dirección HTTP en la interfaz web de Drive).
Desafortunadamente, ResourceId no está disponible de inmediato (hasta que GDAA confirma el objeto) - SO 22432431

Buena suerte


No puede acceder al archivo ni a las carpetas creadas en otras aplicaciones (incluidas las aplicaciones Drive Web y Android), a menos que el usuario autorice explícitamente a que su aplicación acceda a ellas utilizando el selector de archivos.

Si creó la carpeta con su aplicación Android, luego desinstala y vuelve a instalar su aplicación, su aplicación aún debería poder acceder a la carpeta ya que la autorización está ligada a su ID de aplicación de la Consola del Desarrollador, que no cambia entre las instalaciones.

Este comportamiento también significa que la versión web de su aplicación puede acceder a los archivos creados por la versión de Android.