What I am trying to do is simply not possible using the Google Drive Android API. I guess this is because the DriveResource
does not get a resourceId
until it has been uploaded.
See this SO answer which discusses how you aren't able to access any file or folder that isn't created by your app. I tested this and it's true - when I run a Query
for a folder that I created manually in my root folder I cannot find it, but when I create a folder with the same name from my app, I get 1 query result.
Also see this SO thread which says you need to use another Google Drive API (they suggested the REST API) to be able to specify a folder programmatically (without using a popup where the user selects a folder). Unfortunately that won't work for me because I am building an offline app - precisely the reason I chose to work with Google Drive.
I ended up making a compromise and working with the root folder - luckily for me my project is to be used with very specific Google accounts so I am able to do this. My code looks something like this:
private void createFile() {
// [START create_file]
final Task<DriveFolder> rootFolderTask = getDriveResourceClient().getRootFolder();
final Task<DriveContents> createContentsTask = getDriveResourceClient().createContents();
Tasks.whenAll(rootFolderTask, createContentsTask)
.continueWithTask(task -> {
DriveFolder parent = rootFolderTask.getResult();
DriveContents contents = createContentsTask.getResult();
OutputStream outputStream = contents.getOutputStream();
try (Writer writer = new OutputStreamWriter(outputStream)) {
writer.write("Hello World!");
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("HelloWorld.txt")
.setMimeType("text/plain")
.setStarred(true)
.build();
return getDriveResourceClient().createFile(parent, changeSet, contents);
})
.addOnSuccessListener(this,
driveFile -> {
showMessage(getString(R.string.file_created,
driveFile.getDriveId().encodeToString()));
finish();
})
.addOnFailureListener(this, e -> {
Log.e(TAG, "Unable to create file", e);
showMessage(getString(R.string.file_create_error));
finish();
});
// [END create_file]
}
If you can't compromise and use the root folder, I would suggest that you create a folder from within your app into the root folder and then save the string representation of the DriveId which you can use the next time you run the code. I haven't yet tested if the folder could be used by another instance of the app running on a different device, but I would hope so (fingers crossed).
Another option is displaying a popup so the user can select the folder manually. See this demo example.