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