1

I used Android Drive Api to upload my files on Drive.I created a folder("NewFolder") on Google Drive root and created a inner folder("InnerFolder") inside my "NewFolder" from android app using following code.Then I write my files on this "InnerFolder" from my android app.

My app create the "InnerFolder" on first time installation on my device only.Then uninstall and reinstall App will not created folder again(Stored created folder Drive Id(like DriveId:yrjundeen12cnfe) in local file).

My Code works fine on first time Installation.But If I uninstall and reinstall app many times and I try to upload on Google Drive,I got error as "Invalid parent folder" on callback method of createFile.

First Time Folder Creation code:

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
    }
};

File Upload code:

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 on 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.
Ramprasad
  • 7,981
  • 20
  • 74
  • 135

2 Answers2

3

Do not rely on GDAA's DriveId for any caching or possibly addressing of Drive object (file/folder) beyond the app and device scope. This ID is coming from Google Play Services instance on your device (so it is not even valid on a different device using the same app - even if file/folder is still visible under the FILE scope). I vaguely remember 'losing' it even when clearing the Google Play Services (GooPS) cache or even re-installing GooPS. But this might have been fixed. My last encounter with GDAA was a few months ago.

Instead, there is a 'ResourceId', that is used in RESTFul API (known as plain 'id') - see SO 21800257. This string uniquely represents the Drive object and can be ported and used everywhere (it is even a part of HTTP address in Drive Web interface).
Unfortunately, ResourceId is not immediately available (until GDAA commits the the object) - SO 22432431

Good Luck

Community
  • 1
  • 1
seanpj
  • 6,735
  • 2
  • 33
  • 54
  • As like you said,I got ResourceId as null on createFolder ReultCallback. String resourceId = result.getDriveFolder().getDriveId().getResourceId(); it returns null. I tried to use Completion Events.But I am not able to commit for createFolder method. – Ramprasad Jan 27 '15 at 10:55
  • Is it possible to add ExecutionOptions to createFolder method to setNotifyOnCompletion? Because onCompletion event I get ResourceId of folder to store it locally and createFile inside the folder using the ResourceId. – Ramprasad Jan 27 '15 at 13:27
  • If you addressing me, sorry I can't answer, since I dropped GDAA some time ago for more elegant REST / GCM based solution. You are still welcome to pull quite resent https://github.com/seanpjanson/GDAADemo that has barebones SCRUD (sorry, no (D)elete, though) implementation of both GDAA and REST interface to play with it. To explain, I played with DGAA for a while hoping to get inter-device updating-notifications. It is not there, none of the on-notify, sync, ... GDAA functionality replaces immediacy of GCM. – seanpj Jan 27 '15 at 17:01
  • @seanpj is there any other options to skip this invalid parent folder issue.? – Sagar Maiyad Jul 07 '15 at 07:10
  • Don't understand what you're asking, Please raise an SO question with a complete description / code / logcat... – seanpj Jul 07 '15 at 09:22
1

You can't access file and folders created in other apps (including the Drive Web and Android apps) unless the user explicitly authorizes your app to access them using the file picker.

If you created the folder using your Android app, then uninstall and reinstall your app, your app should still be able to access the folder as authorization is tied to your Developer Console application ID which doesn't change between installs.

This behavior also means the Web version of your app can access files created by the Android version.

Daniel
  • 1,239
  • 1
  • 13
  • 24
  • I updated my question above.I got Invalid parent folder error when I uninstall and reinstall app repeatedly.Also error said,local storage has beed cleared – Ramprasad Jan 24 '15 at 09:33