im using the Google Drive API to save(use as backup) a database there, its working nice, but just if i use the ROOT
the Api Call:
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
......build();
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, metadataChangeSet, result.getDriveContents())
.setResultCallback(fileCallback);
CallBack to Save the file:
final public ResultCallback < DriveFolder.DriveFileResult > fileCallback = new
ResultCallback < DriveFolder.DriveFileResult > () {
#Override
public void onResult(DriveFolder.DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
return;
}
Log.i(TAG, "Successfull !");
}
};
i know that i must get the Folder, but if i do this, i need to do a CallBack to call another callback and then save?
isnt any way to directly do .createNewFile inside the FOLDER? without doing another Query for folder, check if the folder exist than create the folder, than use the DriveID, than create the file?
Remember, that in the GooDrive universe, the tree structure (folder, subfolder, ...) is a mirage. The Drive is a flat system of objects (files, folders) where one of the metadata fields is a 'set of parent IDs', that actually forms the notion of parentobject - childobject structure. Actually the classic tree (one parent many children) is not even enforced, so a child object can 'appear' in more that one parent.
This fact explains that you CAN NOT create an OS type of path in one shot. The objects (parents) must be created before their IDs can be plugged into child objects' metadata.
So the only way to do it, is to do what you say:
if folder exists
return it's ID
else
return ID of newly created one
create a child object with parent's ID
... and here is an example how I create a structure of type:
/ MYROOT / 2015 / 2015-12
(where MYROOT, 2015 , 2015-12 are subfloders the Drive root)
new Thread(new Runnable() {
#Override
public void run() {
DriveId Id = getFolder( getFolder( getFolder(
Drive.DriveApi.getRootFolder(mGAC).getDriveId(), "MYROOT"),
"2015",
"2015-12"
);
}
}).start();
GoogleApiClient mGAC;
DriveId getFolder(DriveId parentId, String titl) {
DriveId dId = null;
if (parentId != null && titl != null) try {
ArrayList<Filter> fltrs = new ArrayList<>();
fltrs.add(Filters.in(SearchableField.PARENTS, parentId));
fltrs.add(Filters.eq(SearchableField.TITLE, titl));
fltrs.add(Filters.eq(SearchableField.MIME_TYPE, "application/vnd.google-apps.folder"));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
MetadataBuffer mdb = null;
DriveApi.MetadataBufferResult rslt = Drive.DriveApi.query(mGAC, qry).await();
if (rslt.getStatus().isSuccess()) try {
mdb = rslt.getMetadataBuffer();
if (mdb.getCount() > 0)
dId = mdb.get(0).getDriveId();
} catch (Exception ignore) {}
finally { if (mdb != null) mdb.close(); }
if (dId == null) {
MetadataChangeSet meta = new Builder().setTitle(titl).setMimeType(UT.MIME_FLDR).build();
DriveFolderResult r1 = parentId.asDriveFolder().createFolder(mGAC, meta).await();
DriveFolder dFld = (r1 != null) && r1.getStatus().isSuccess() ? r1.getDriveFolder() : null;
if (dFld != null) {
MetadataResult r2 = dFld.getMetadata(mGAC).await();
if ((r2 != null) && r2.getStatus().isSuccess()) {
dId = r2.getMetadata().getDriveId();
}
}
}
} catch (Exception e) { e.printStackTrace(); }
return dId;
}
In the 'mdb.get(0).getDriveId()' area, you can see how hacky it gets when you try to impose a classic tree structure on the Drive. The search here can return multiple objects with the same name, so I use the first one. There should be some kind of error reporting here.
As you can see it is possible to replace callbacks with the 'await()' method, flattening the code into a classic DOS style spaghetti code as long as you place the whole sequence off-UI thread (asynctask, thread, ....)
Still, more elegant (IMO) option to accomplish this is to use recursive call from the result callback.
fromPath(Drive.DriveApi.getRootFolder(mGAC).getDriveId(), "MYROOT/2015/2015-12/file.jpg");
....
void fromPath(final DriveId parentId, final String path) {
if (parentId != null && path != null) {
final int idx = path.indexOf('/');
if (idx < 0) {
// reached last path item - probably file name
// CREATE FILE WITH patentID AND QUIT
return; //--- DONE -------------------->>>
}
final String titl = path.substring(0, idx);
ArrayList<Filter> fltrs = new ArrayList<>();
fltrs.add(Filters.in(SearchableField.PARENTS, parentId));
fltrs.add(Filters.eq(SearchableField.TITLE, titl));
fltrs.add(Filters.eq(SearchableField.MIME_TYPE, UT.MIME_FLDR));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
Drive.DriveApi.query(mGAC, qry).setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
#Override
public void onResult(DriveApi.MetadataBufferResult rslt) {
MetadataBuffer mdb = null;
if (rslt != null && rslt.getStatus().isSuccess()) {
try {
mdb = rslt.getMetadataBuffer();
for (Metadata md : mdb) {
if (md.isTrashed()) continue;
fromPath(md.getDriveId(), path.substring(idx + 1));
return; //+++ first found, NEXT +++++++>>>
}
} finally { if (mdb != null) mdb.close(); }
}
MetadataChangeSet meta = new Builder().setTitle(titl).setMimeType(UT.MIME_FLDR).build();
parentId.asDriveFolder().createFolder(mGAC, meta)
.setResultCallback(new ResultCallback<DriveFolderResult>() {
#Override
public void onResult(DriveFolderResult rslt) {
DriveFolder dFld = rslt != null && rslt.getStatus().isSuccess() ? rslt.getDriveFolder() : null;
if (dFld != null) {
dFld.getMetadata(mGAC).setResultCallback(new ResultCallback<MetadataResult>() {
#Override
public void onResult(MetadataResult rslt) {
if (rslt != null && rslt.getStatus().isSuccess()) {
fromPath(rslt.getMetadata().getDriveId(), path.substring(idx + 1));
return; //+++ created, NEXT +++++++>>>
}
}
});
}
}
});
}
});
}
}
A WORD OF CAUTION:
As I called this sequence repeatedly, using the last DriveId (like 2015-12) as a parent of a JPEG image file, I have experienced weird behavior, like suddenly getting a 'null' result from 'Drive.DriveApi.getRootFolder(mGAC).getDriveId()'. It shouldn't happen and I assume it is a bug in GDAA. I contribute this to the fact that the DriveId used inside GDAA is 'invalid' until the folder gets committed and the ResourceId is resolved in underlying REST Api. Unfortunately, there is no completion event available for folder creation, so I resolved this by calling this sequence only once in onConnected() and caching the '2015-12's DriveId for later use as a parent of the image JPEG files.
Actually you can see it here (createTree() method) with text file on the tail, but the moment I switched the TEXT to JPEG, all hell broke lose.
Good Luck
Related
I'm currently studying ways to sync data between an Android device to Google Drive and stumbled upon the sample code at https://github.com/googledrive/android-quickeditor , but I'm encountering an issue when opening an existing file and then tapping on 'Save Changes'. Basically the problematic code is here:
#Override
protected com.google.android.gms.common.api.Status doInBackground(DriveId... params) {
R await;
DriveFile file = params[0].asDriveFile();
PendingResult<DriveContentsResult> openDriveContentsResult = file.open(mClient, DriveFile.MODE_WRITE_ONLY, null);
if (!openDriveContentsResult.await().getStatus().isSuccess()) {
return openDriveContentsResult.await().getStatus();
}
Changes changes = edit(openDriveContentsResult.await().getDriveContents());
PendingResult<MetadataResult> metadataResult = null;
PendingResult<com.google.android.gms.common.api.Status> closeContentsResult = null;
if (changes.getMetadataChangeSet() != null) {
metadataResult = file.updateMetadata(mClient, changes.getMetadataChangeSet());
if (!metadataResult.await().getStatus().isSuccess()) {
return metadataResult.await().getStatus();
}
}
if (changes.getDriveContents() != null) {
closeContentsResult = changes.getDriveContents().commit(mClient, null);
closeContentsResult.await();
}
return closeContentsResult.await().getStatus();
}
The exact line throwing the error is:
Changes changes = edit(openDriveContentsResult.await().getDriveContents());
The Error is java.lang.IllegalStateException: Result has already been consumed. I referred to the PendingResult class reference and it clearly states that "After the result has been retrieved using await() or delivered to the result callback, it is an error to attempt to retrieve the result again." Fair enough I guess.
The problem is, how am I supposed to fix this properly? I have commented out
if (!metadataResult.await().getStatus().isSuccess()) {...}
for now to avoid calling await() twice (for sake of debugging), BUT (as expected) then results into the same error at
return closeContentsResult.await().getStatus();
So...how can I fix this? Pretty please?
Solved. For anyone that's getting frustrated over this:
#Override
protected com.google.android.gms.common.api.Status doInBackground(DriveId... params)
{
R await;
DriveFile file;
Changes changes;
PendingResult<DriveContentsResult> openDriveContentsResult;
DriveContentsResult driveContentsResult;
PendingResult<MetadataResult> updateMetadataResult;
MetadataResult metaDataResult;
PendingResult<com.google.android.gms.common.api.Status> commitResults;
com.google.android.gms.common.api.Status closeContentResults = null;
file = params[0].asDriveFile();
openDriveContentsResult = file.open(mClient, DriveFile.MODE_WRITE_ONLY, null);
driveContentsResult = openDriveContentsResult.await();
if (!driveContentsResult.getStatus().isSuccess())
{
return driveContentsResult.getStatus();
}
changes = edit(driveContentsResult.getDriveContents());
updateMetadataResult = null;
commitResults = null;
if (changes.getMetadataChangeSet() != null)
{
updateMetadataResult = file.updateMetadata(mClient, changes.getMetadataChangeSet());
metaDataResult = updateMetadataResult.await();
if (!metaDataResult.getStatus().isSuccess())
{
return metaDataResult.getStatus();
}
}
if (changes.getDriveContents() != null)
{
commitResults = changes.getDriveContents().commit(mClient, null);
closeContentResults = commitResults.await();
}
if (null == commitResults)
{
return commitResults.await().getStatus();
}
else
{
return closeContentResults.getStatus();
}
}
I am trying to access all files and folders from google drive to a arraya list. But I can get only one file from Drive. What to do get all files and folders from google drive. I am using the following code..
Thanks
Arun
public void onConnected(Bundle connectionHint) {
// Log.i(TAG, "API client connected.");
Toast.makeText(getActivity(), "Successfully logged in", Toast.LENGTH_LONG).show();
DriveFolder s = Drive.DriveApi.getRootFolder(mGoogleApiClient);
String s1 = (Drive.DriveApi.getRootFolder(mGoogleApiClient)).getDriveId().toString();
DriveId sFolderId2 = DriveId.decodeFromString(s1);
DriveId sFolderId = (Drive.DriveApi.getRootFolder(mGoogleApiClient)).getDriveId();
DriveFolder folder = Drive.DriveApi.getFolder(mGoogleApiClient, sFolderId);
folder.listChildren(mGoogleApiClient).setResultCallback(rootFolderCallback);
// findAll(folder);
}
public ResultCallback<DriveApi.MetadataBufferResult> rootFolderCallback = new
ResultCallback<DriveApi.MetadataBufferResult>() {
#Override
public void onResult(DriveApi.MetadataBufferResult result) {
if (!result.getStatus().isSuccess()) {
return;
}
resultarray = new ArrayList<String>();
int hh = result.getMetadataBuffer().getCount();
for (int i = 0; i < result.getMetadataBuffer().getCount(); i++) {
resultarray.add(result.getMetadataBuffer().get(i).getTitle());
}
Toast.makeText(getActivity(), "Successfully listed files.", Toast.LENGTH_LONG).show();
}
};
UPDATE (Aug 25, 2015, 10:39 MST)
Based on your comment below, you have 2 options:
1/ Stay with the GDAA, use one of the INTENTS:
- Pick a file with opener activity
- Pick a folder with opener activity
See, GDAA does not let your app see anything it did not create (SCOPE_FILE only), but it still allows user to browse everything. If the user selects a file, it will become visible to you app. I don't know your app's intentions, so I can't say if this approach is usable.
2/ Switch to the REST with the DRIVE scope and your app will see everything (user has to approve up front). The basic CRUD implementation can be found here but make sure you change the scope in the init() method to 'DriveScopes.DRIVE'.
In case your app needs to iterate down the folder tree, collecting files in the process, both 'testTree()' and 'deleteTree()' methods in the MainActivity() do exactly that.
You may also stay with the GDAA and add REST functionality to it by adding
com.google.api.services.drive.Drive mGOOSvc = new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(),
GoogleAccountCredential.usingOAuth2(appContext, Collections.singletonList(DriveScopes.DRIVE))
.setSelectedAccountName(email)
but you will sooner or later run into problems caused by GDAA caching / latency.
ORIGINAL ANSWER
Try this approach:
private static GoogleApiClient mGAC;
/****************************************************************************
* find file/folder in GOODrive
* #param prnId parent ID (optional), null searches full drive, "root" searches Drive root
* #param titl file/folder name (optional)
* #param mime file/folder mime type (optional)
* #return arraylist of found objects
*/
static void search(String prnId, String titl, String mime) {
if (mGAC != null && mGAC.isConnected()) {
// add query conditions, build query
ArrayList<Filter> fltrs = new ArrayList<>();
if (prnId != null){
fltrs.add(Filters.in(SearchableField.PARENTS,
prnId.equalsIgnoreCase("root") ?
Drive.DriveApi.getRootFolder(mGAC).getDriveId() : DriveId.decodeFromString(prnId)));
}
if (titl != null) fltrs.add(Filters.eq(SearchableField.TITLE, titl));
if (mime != null) fltrs.add(Filters.eq(SearchableField.MIME_TYPE, mime));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
// fire the query
Drive.DriveApi.query(mGAC, qry).setResultCallback(new ResultCallback<MetadataBufferResult>() {
#Override
public void onResult(MetadataBufferResult rslt) {
if (rslt != null && rslt.getStatus().isSuccess()) {
MetadataBuffer mdb = null;
try {
mdb = rslt.getMetadataBuffer();
if (mdb != null ) for (Metadata md : mdb) {
if (md == null || !md.isDataValid()) continue;
String title = md.getTitle();
DriveId driveId = md.getDriveId();
//.......
}
} finally { if (mdb != null) mdb.close(); }
}
}
});
}
}
Call it first with NULLs
search(null,null,null)
To list all the files in your Google Drive. You will see all the files your Android App created. But only those - FILE scope does not see anything else.
If you need to scan the directory tree, you may look closer at this GDAA demo, in MainActivity, there is are 'testTree()' / 'deleteTree() methods that recursively scan the directory tree structure.
Also, you may look at the answer here, it deals with a similar issue (especially the comments exchange under the answer).
Good Luck
Please note that you can use GDAA to retrieve the files and folder that you have either uploaded from the Android Device or downloaded via the drive app. This is to have more security (as quoted by Google).
In he code you need to ensure that you are trying all possible combinations for the files that may be present in your Google Drive account. For example, check if you are tracking the parent of a file or a folder. If this condition is not met your app wont be able to retrieve those specific files.
/** Get the list of parents Id in ascending order. */
private List<String> collectParents(String folderId, Map<String, String> folderIdToParentId){
String parentId = folderIdToParentId.get(folderId);
if (logger.isTraceEnabled()){
logger.trace("Direct parent of {} is {}", folderId, parentId);
}
List<String> ancestors = new ArrayList<String>();
ancestors.add(parentId);
if (folderIdToParentId.containsKey(parentId)){
ancestors.addAll(collectParents(parentId, folderIdToParentId));
return ancestors;
}
return ancestors;
}
See the full code here.
I am using Google Play Services SDK.
And tried the Demos from developer site.
Is there a way to get(download) all the files from a specific folder?
Any pointer will be of great help. The whole sample code doesn't seem to be complete.
Here is the 'await' version of a method that does something similar (must be run on non-ui thread).
// list / search all non-trashed files in a folder (globally if 'fldr' is null)
GoogleApiClient _gac;
public void findAll(String title, String mime, DriveFolder fldr) {
ArrayList<Filter> fltrs = new ArrayList<Filter>();
fltrs.add(Filters.eq(SearchableField.TRASHED, false));
if (title != null)
fltrs.add(Filters.eq(SearchableField.TITLE, title));
if (mime != null)
fltrs.add(Filters.eq(SearchableField.MIME_TYPE, mime));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
MetadataBufferResult rslt = (fldr == null) ? Drive.DriveApi.query(_gac, qry).await() :
fldr.queryChildren(_gac, qry).await();
if (rslt.getStatus().isSuccess()) {
MetadataBuffer mdb = null;
try {
mdb = rslt.getMetadataBuffer();
if (mdb == null) return null;
for (Metadata md : mdb) {
if ((md == null) || (!md.isDataValid()) || md.isTrashed()) continue;
// md gives you the file info
}
} finally { if (mdb != null) mdb.close(); }
}
}
There is a bunch of code on the same theme on Github here, but I haven't touched it for awhile now (i.e. no warranties).
I want to integrate Google drive with my app I have registered my app in Google Developers Console. I got a sample from https://github.com/googledrive/android-demos .By this i am able to create a file,folder in Google drive's root folder but the problem is I couldn't create a file or folder inside an existing folder. In such case i got a toast "Cannot find DriveId. Are you authorized to view this file?" ie I cannot get the driveID
public class CreateFolderInFolderActivity extends BaseDemoActivity {
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
Drive.DriveApi.fetchDriveId(getGoogleApiClient(), EXISTING_FOLDER_ID)
.setResultCallback(idCallback);
}
final ResultCallback<DriveIdResult> idCallback = new ResultCallback<DriveIdResult>() {
#Override
public void onResult(DriveIdResult result) {
if (!result.getStatus().isSuccess()) {
showMessage(result.getStatus().toString());
showMessage("Cannot find DriveId. Are you authorized to view this file?");
return;
}
DriveFolder folder = Drive.DriveApi
.getFolder(getGoogleApiClient(), result.getDriveId());
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("MyNewFolder").build();
folder.createFolder(getGoogleApiClient(), changeSet)
.setResultCallback(createFolderCallback);
}
};
final ResultCallback<DriveFolderResult> createFolderCallback = new
ResultCallback<DriveFolderResult>() {
#Override
public void onResult(DriveFolderResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Problem while trying to create a folder");
return;
}
showMessage("Folder successfully created");
}
};
}
I cannot find any proper documentation for this.
Plz help me where i am going wrong or Whether I Have to include any other permissions
You can take a peek here: in the 'createTree()' method, there is a creation of folder within a folder.
There are 3 different drive ID entities in the new Google Drive Android API (GDAA)
the object of type DriveID - the one you get from methods and use in your code
a string you get from encodeToString() and pass to decodeFromString() - used to save within the app (caching for instance)
a string you get from getResourceId() and pass to fetchDriveId() - the one you see in the html address of a file.
Both 2 and 3 identifiers are strings, so they may be confused. Identifier 2 is faster when retrieving Drive ID (via decodeFromString()). Identifier 3 is slower to retrieve (via fetchDriveId()), but usefull if you need to take your ID elsewhere (Apps Script, for instance).
Please see also: SO 21800257
What is EXISTING_FOLDER_ID? If you are trying to just run the sample straight out without having made any changes, this won't work.
You need to change EXISTING_FOLDER_ID to the resource id of a folder that your app has access to. This could be a folder that your app created in the root.
first create folder using creatreeTree()
then run a search query to get id of create public static ArrayList<ContentValues> search(String prnId, String titl, String mime) {
ArrayList<ContentValues> gfs = new ArrayList<>();
if (mGOOSvc != null && mConnected) try {
// add query conditions, build query
String qryClause = "'me' in owners and ";
if (prnId != null) qryClause += "'" + prnId + "' in parents and ";
if (titl != null) qryClause += "title = '" + titl + "' and ";
if (mime != null) qryClause += "mimeType = '" + mime + "' and ";
qryClause = qryClause.substring(0, qryClause.length() - " and ".length());
Drive.Files.List qry = mGOOSvc.files().list().setQ(qryClause)
.setFields("items(id,mimeType,labels/trashed,title),nextPageToken");
String npTok = null;
if (qry != null) do {
FileList gLst = qry.execute();
if (gLst != null) {
for (File gFl : gLst.getItems()) {
if (gFl.getLabels().getTrashed()) continue;
gfs.add( UT.newCVs(gFl.getTitle(), gFl.getId(), gFl.getMimeType()));
} //else UT.lg("failed " + gFl.getTitle());
npTok = gLst.getNextPageToken();
qry.setPageToken(npTok);
}
} while (npTok != null && npTok.length() > 0); //UT.lg("found " + vlss.size());
} catch (Exception e) { UT.le(e); }
return gfs;
}
when you get folder id use this code to create folder in folder ` public static ParentReference insertFileIntoFolder(Drive service, String folderId,
String folderName) throws IOException {
// Log.e("founddd",id);
File fileMetadata = new File();
fileMetadata.setParents(Collections.singletonList(new ParentReference().setId(folderId == null ? "root" : folderId)));
fileMetadata.setTitle(folderName);
fileMetadata.setMimeType("application/vnd.google-apps.folder");
File file = mGOOSvc.files().insert(fileMetadata).execute();
System.out.println("Folder ID: " + file.getId());
strChildFolder = file.getId();
return null;
}`
I'm trying to figure out how to check if a folder exists in Google Drive using the new Google Drive Android API
I've tried the following, thinking that it would either crash or return null if the folder is not found, but it doesn't do that (just as long as it is a valid DriveId, even though the folder has been deleted).
DriveFolder folder = Drive.DriveApi.getFolder(getGoogleApiClient(), driveId));
If i try to create a file the folder I get from the above code, it does not crash either?
I'm clearly having a little hard time understanding how this new API works all to together, especially with the very limited tutorials and SO questions out there, and I'm really stuck on this one, so any input will be much appreciated.
Just to clarify my problem: I'm creating a file in a specified Google Drive folder, but if the folder does not exist (has been deleted by user), I want to create it first.
After a lot of research this is the code I ended up with. It works properly, but has an issue: When a folder is trashed in Google Drive it takes some time (hours) before the metadata I can fetch from my app is updated, meaning that this code can first detect if the folder has been trashed a couple of hours later the trashing event actually happened - further information and discussions can be found here.
public class checkFolderActivity extends BaseDemoActivity {
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
DriveId folderId = DriveId.decodeFromString(folderId);
DriveFolder folder = Drive.DriveApi.getFolder(mGoogleApiClient, folderId);
folder.getMetadata(mGoogleApiClient).setResultCallback(metadataRetrievedCallback);
}
final private ResultCallback<DriveResource.MetadataResult> metadataRetrievedCallback = new
ResultCallback<DriveResource.MetadataResult>() {
#Override
public void onResult(DriveResource.MetadataResult result) {
if (!result.getStatus().isSuccess()) {
Log.v(TAG, "Problem while trying to fetch metadata.");
return;
}
Metadata metadata = result.getMetadata();
if(metadata.isTrashed()){
Log.v(TAG, "Folder is trashed");
}else{
Log.v(TAG, "Folder is not trashed");
}
}
};
}
If you're creating a folder based on it's existence status, the 'createTree()' method here does just that.
The following 2 code snippets list files/folders based on arguments passed ( inside a folder, globally, based on MIME type ...). The line with md.getTitle() is the one that you can use to interrogate files/folders.
GoogleApiClient _gac;
void findAll(String title, String mime, DriveFolder fldr) {
ArrayList<Filter> fltrs = new ArrayList<Filter>();
fltrs.add(Filters.eq(SearchableField.TRASHED, false));
if (title != null) fltrs.add(Filters.eq(SearchableField.TITLE, title));
if (mime != null) fltrs.add(Filters.eq(SearchableField.MIME_TYPE, mime));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
MetadataBufferResult rslt = (fldr == null) ? Drive.DriveApi.query(_gac, qry).await() :
fldr.queryChildren(_gac, qry).await();
if (rslt.getStatus().isSuccess()) {
MetadataBuffer mdb = null;
try {
mdb = rslt.getMetadataBuffer();
if (mdb == null) return null;
for (Metadata md : mdb) {
if ((md == null) || md.isTrashed()) continue;
--->>>> md.getTitle()
}
} finally { if (mdb != null) mdb.close(); }
}
}
void listAll(DriveFolder fldr) {
MetadataBufferResult rslt = fldr.listChildren(_gac).await();
if (rslt.getStatus().isSuccess()) {
MetadataBuffer mdb = null;
try {
mdb = rslt.getMetadataBuffer();
if (mdb == null) return null;
for (Metadata md : mdb) {
if ((md == null) || md.isTrashed()) continue;
--->>>> md.getTitle()
}
} finally { if (mdb != null) mdb.close(); }
}
}
The key is probably checking the "isTrashed()" status. Since 'remove' file on the web only moves it to TRASH. Also, deleting in general (on the website, since there is no 'DELETE' in the API) is a bit flaky. I was testing it for a while, and it may take hours, before the "isTrashed()" status is updated. And manually emptying the trash in Google Drive is also unreliable. See this issue on Github.
There is a bit more talk here, but probably unrelated to your problem.
So today the answer is out of date API.
So I have posted example of how to check the folder if exists with the new update of documentation:
fun checkFolder(name: String):Boolean {
check(googleDriveService != null) { "You have to init Google Drive Service first!" }
return search(name, FOLDER_MIME_TYPE)
}
private fun search(name: String, mimeType:String): Boolean {
var pageToken: String? = null
do {
val result: FileList =
googleDriveService!!
.files()
.list()
.setQ("mimeType='$FOLDER_MIME_TYPE'")
.setSpaces("drive")
.setFields("nextPageToken, files(id, name)")
.setPageToken(pageToken)
.execute()
for (file in result.files) {
Log.d(TAG_UPLOAD_FILE , "Found file: %s (%s)\n ${file.name}, ${file.id} ")
if (name == file.name) return true
}
pageToken = result.nextPageToken
} while (pageToken != null)
return false
}
private const val FOLDER_MIME_TYPE= "application/vnd.google-apps.folder"
You can try to get the metadata for the folder. If the folder doesn't exist, this will fail.