0

This is the code that I'm using to upload a file in a set of nested folders.
While most of the times it works, for some set of nested folders the result of the callback is negative.
Also, using another device with another google account, the same set of nested folders may upload correctly. The error message that is returned by the callback of the folder is "Invalid parent folder Google Drive API".

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bundle extras = getIntent().getExtras();
    if (extras != null) {
        this.photoName = extras.getString(CommonUtilities.PHOTO_FILE_NAME);
        this.foldersNames = extras.getStringArray(CommonUtilities.PHOTO_FOLDERS_NAMES);
        this.photoPath = extras.getString(CommonUtilities.PHOTO_PATH);
    }

    //Put the folders in an array list
    ArrayList<String> foldersArrayList = new ArrayList<>();
    for(String folder: foldersNames){
        foldersArrayList.add(folder);
    }
    final Iterator<String> iterator = foldersArrayList.iterator();

    // Perform I/O off the UI thread.
    new Thread() {
        @Override
        public void run() {
            // write content to DriveContents

            try {
                Drive.DrivePreferencesApi.getFileUploadPreferences(getGoogleApiClient()).setResultCallback(new ResultCallback<DrivePreferencesApi.FileUploadPreferencesResult>() {
                    @Override
                    public void onResult(@NonNull DrivePreferencesApi.FileUploadPreferencesResult fileUploadPreferencesResult) {
                        //Set the network preference
                        fileUploadPreferencesResult.getFileUploadPreferences().setNetworkTypePreference(FileUploadPreferences.NETWORK_TYPE_WIFI_ONLY);

                        //Get the root folder
                        driveFolder = Drive.DriveApi.getRootFolder(getGoogleApiClient());

                        //Iterate through the folders and create them if they don't exist
                        createFolders(iterator);
                    }
                });

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }.start();

}


private void createFolders(final Iterator<String> iteratorFolder){
    final String folder = iteratorFolder.next();
        //Search if condominium exists
        Query query = new Query.Builder()
                .addFilter(Filters.contains(SearchableField.TITLE, folder))
                .build();
        Drive.DriveApi.query(getGoogleApiClient(), query)
                .setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
                    @Override
                    public void onResult(DriveApi.MetadataBufferResult result) {
                        // Iterate over the matching Metadata instances in mdResultSet
                        // The iterator has elements if the query has succeed to find at least one result
                        final Iterator<Metadata> iterator = result.getMetadataBuffer().iterator();
                        if (!iterator.hasNext()) {
                            MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                                    .setTitle(folder).build();
                            driveFolder.createFolder(
                                    getGoogleApiClient(), changeSet).setResultCallback(new ResultCallback<DriveFolder.DriveFolderResult>() {
                                @Override
                                public void onResult(@NonNull DriveFolder.DriveFolderResult driveFolderResult) {
                                    if (!driveFolderResult.getStatus().isSuccess()) {
                                        showMessage("Error while trying to create the folder");
                                        showMessage(driveFolderResult.getStatus().getStatusMessage());
                                        return;
                                    }
                                    driveFolder = driveFolderResult.getDriveFolder();
                                    showMessage("Created a folder: " + driveFolderResult.getDriveFolder().getDriveId());

                                    if(iteratorFolder.hasNext()) {
                                        createFolders(iteratorFolder);
                                    } else{
                                        createFile(photoName);
                                    }
                                }
                            });
                        }
                        while (iterator.hasNext()) {
                            final Metadata metadata = iterator.next();
                            driveFolder = Drive.DriveApi.getFolder(getGoogleApiClient(), metadata.getDriveId());
                            //Check if the folder exists, if it doesn't, create it
                            if(iteratorFolder.hasNext()) {
                                createFolders(iteratorFolder);
                            } else{
                                createFile(photoName);
                            }

                    }
                }
    });
}

private void createFile(final String photoName){
    Drive.DriveApi
            .newDriveContents(getGoogleApiClient())
            .setResultCallback(new ResultCallback<DriveApi.DriveContentsResult>() {
                @Override
                public void onResult(@NonNull DriveApi.DriveContentsResult driveContentsResult) {
                    try {
                        //Create new photo file
                        final DriveContents driveContents = driveContentsResult.getDriveContents();

                        File file = new File(photoPath);

                        FileInputStream f = new FileInputStream(file);
                        InputStream inputStream = f;
                        OutputStream outputStream = driveContents.getOutputStream();
                        IOUtils.copy(inputStream, outputStream);

                        MetadataChangeSet changeSet2 = new MetadataChangeSet.Builder()
                                .setTitle(photoName + ".jpeg")
                                .setMimeType("image/jpeg").build();

                        // Create a file in the root folder
                        driveFolder
                                .createFile(getGoogleApiClient(), changeSet2, driveContents)
                                .setResultCallback(new ResultCallback<DriveFolder.DriveFileResult>() {
                                    @Override
                                    public void onResult(@NonNull DriveFolder.DriveFileResult driveFileResult) {
                                        if (!driveFileResult.getStatus().isSuccess()) {
                                            showMessage("Error while trying to create new file contents");
                                        }
                                        finish();
                                    }

                                });
                    } catch(Exception e){
                        e.printStackTrace();
                    }
                }
            });
}
Marco Menardi
  • 481
  • 6
  • 20
  • As a minimum you'll need to post the full http response including error status and message – pinoyyid Mar 07 '17 at 14:18
  • You could try using REST API as a workaround for GDAA as stated in this related SO [post](http://stackoverflow.com/a/37736306/5995040) and there was an [issue](https://code.google.com/a/google.com/p/apps-api-issues/issues/detail?id=4483) reported regarding this. Also try using `ResourceID` and not depending on the Drive ID base on this [reported issue in GitHub](https://github.com/googledrive/android-demos/issues/35) and SO [post](http://stackoverflow.com/questions/31261276/invalid-parent-folder-error-in-drive-api-android). Hope this helps – Mr.Rebot Mar 08 '17 at 10:21
  • Did you allow the Drive.SCOPE_APPFOLDER in the signin options ? – Arnaud Nov 15 '17 at 14:40

0 Answers0