问题
I'm trying to get an IDriveResource in the Google Drive Apps Folder using a query, but I'm having trouble with type casting. Here's the code I got so far:
using (IDriveFolder appFolder = DriveClass.DriveApi.GetAppFolder(googleApiClient))
using (QueryClass query = new QueryClass.Builder().AddFilter(Filters.Eq(SearchableField.Title, MY_FILE_NAME)).Build())
using (var queryResult = await appFolder.QueryChildrenAsync(googleApiClient, query))
using (var driveItem = queryResult.MetadataBuffer)
{
using (var driveFile = await driveItem.DriveId.AsDriveFile().OpenAsync(googleApiClient, DriveFile.ModeWriteOnly, null))
using (var outputStream = driveFile.DriveContents.OutputStream)
using (var writer = new OutputStreamWriter(outputStream))
using (var changeSet = new MetadataChangeSet.Builder()
.SetLastViewedByMeDate(new Java.Util.Date())
.Build())
{
writer.Write(MY_TEXT);
writer.Close();
driveFile.DriveContents.Commit(googleApiClient, changeSet);
}
}
But the compiler doesn't recognize DriveId property in driveItem. I need to type cast driveItem, but the compiler won't accept any option. If it accepts on the driveItem declaration (like MetadataBuffer), it won't have the DriveId property. If I try IDriveFile or IDriveResource it won't accept the cast in the variable declaration.
I'm actually having the same problem when trying to pass driveItem to a method like:
private async Task<bool> saveDriveItem(???? driveItemToSave)
{
...
}
I can't use this kind of method because I can't find the right ???? type to use.
Any ideas?
Thanks.
回答1:
MetadataBuffer is a collection of Metadata entries and you are trying to use it as a singular MetaData object.
When you use a Drive query, you could get back multiple files/folders as Drive allows you to have multiple files with the same name even within the same folder.
Review all the results from your query:
using (IDriveFolder appFolder = DriveClass.DriveApi.GetAppFolder(googleApiClient))
using (QueryClass query = new QueryClass.Builder().AddFilter(Filters.Eq(SearchableField.Title, MY_FILE_NAME)).Build())
using (var queryResult = await appFolder.QueryChildrenAsync(googleApiClient, query))
{
foreach (var driveItem in queryResult.MetadataBuffer)
{
Log.Debug("SO", driveItem.Title);
}
}
Since you are using AppFolder and only your app can write to it, assumably you only have one file with that unique file name unless your code is not checking for a pre-existing file and just writes a new one with the same name (which would be allowed).
Check for only one result in the MetadataBuffer, else log an error message:
using (IDriveFolder appFolder = DriveClass.DriveApi.GetAppFolder(googleApiClient))
using (QueryClass query = new QueryClass.Builder().AddFilter(Filters.Eq(SearchableField.Title, MY_FILE_NAME)).Build())
using (var queryResult = await appFolder.QueryChildrenAsync(googleApiClient, query))
{
if (queryResult.MetadataBuffer.Count == 1)
{
var driveItem = queryResult.MetadataBuffer.Get(0) as Metadata;
using (var driveFile = await driveItem.DriveId.AsDriveFile().OpenAsync(googleApiClient, DriveFile.ModeWriteOnly, null))
{
// do something with your drivefile...
}
}
else
{
Log.Error("SO", $"The query for {MY_FILE_NAME} returned {queryResult.MetadataBuffer.Count} results?!?!?");
// Your app is writing multiple files with the same name...
}
}
来源:https://stackoverflow.com/questions/45725225/how-to-query-an-idriveresource-in-google-drive-for-xamarin-android-using-the-dri