【问题标题】:Upload file into google drive folder using Xamarin.Android使用 Xamarin.Android 将文件上传到谷歌驱动器文件夹
【发布时间】:2017-12-03 13:56:48
【问题描述】:

我想使用 Xamarin.Andriod 在谷歌驱动器中的特定文件夹(不是默认位置)中创建文件

我正在使用下面的代码

 MetadataChangeSet changeSetfile = new MetadataChangeSet.Builder()
                   .SetTitle("Test.jpg")
                   .SetMimeType("image/jpeg")
                   .Build();

            DriveClass.DriveApi
                   .GetRootFolder(_googleApiClient)
                    .CreateFile(_googleApiClient, changeSetfile, contentResults.DriveContents);

【问题讨论】:

    标签: c# xamarin xamarin.android google-drive-android-api


    【解决方案1】:
    1. 实现GoogleApiClient.IConnectionCallbacks

    2. 使用DriveClass.APIDriveClass.ScopeFile 获得GoogleApiClient

    GoogleApiClient 示例:

    if (_googleApiClient == null) //  _googleApiClient is a class level variable
    {
        _googleApiClient = new GoogleApiClient.Builder(this)
          .AddApi(DriveClass.API)
          .AddScope(DriveClass.ScopeFile)
          .AddConnectionCallbacks(this)
          .AddOnConnectionFailedListener(onConnectionFailed)
          .Build();
    }
    if (!_googleApiClient.IsConnected)
        _googleApiClient.Connect();
    
    1. 连接后,查询文件夹,根据需要创建,然后向其中“写入”文件。

    文件夹和文件示例:

    var folderName = "StackOverflow";
    using (var driveId = DriveClass.DriveApi.GetRootFolder(_googleApiClient))
    using (var query = new QueryClass.Builder().AddFilter(Filters.And(Filters.Eq(SearchableField.Title, folderName), Filters.Eq(SearchableField.Trashed, false))).Build())
    using (var metaBufferResult = await driveId.QueryChildrenAsync(_googleApiClient, query))
    {
        if (metaBufferResult.Status.IsSuccess)
        {
            DriveId folderId = null;
            foreach (var metaData in metaBufferResult.MetadataBuffer)
            {
                if (metaData.IsFolder && metaData.Title == folderName)
                {
                    folderId = metaData.DriveId;
                    break;
                }
            }
    
            IDriveFolder driveFolder = null;
            switch (folderId)
            {
                case null: // if folder not found, create it and fall through to default
                    using (var folderChangeSet = new MetadataChangeSet.Builder().SetTitle(folderName).Build())
                    using (var folderResult = await driveId.CreateFolderAsync(_googleApiClient, folderChangeSet))
                    {
                        if (!folderResult.Status.IsSuccess)
                        {
                            Log.Error(TAG, folderResult.Status.StatusMessage);
                            break;
                        }
                        driveFolder = folderResult.DriveFolder;
                    }
                    goto default;
                default:
                    driveFolder = driveFolder ?? folderId.AsDriveFolder();
    
                    // create your file in the IDriveFolder obtained, 
                    using (var contentResults = await DriveClass.DriveApi.NewDriveContentsAsync(_googleApiClient))
                    {
                        if (contentResults.Status.IsSuccess)
                        {
                            using (var writer = new OutputStreamWriter(contentResults.DriveContents.OutputStream))
                            {
                                writer.Write("StackOverflow Rocks");
                                using (var changeSet = new MetadataChangeSet.Builder()
                                    .SetTitle("StackOverflow Rocks")
                                    .SetStarred(true)
                                    .SetMimeType("text/plain")
                                    .Build())
                                using (var driveFileResult = await driveFolder.CreateFileAsync(_googleApiClient, changeSet, contentResults.DriveContents))
                                {
                                    if (driveFileResult.Status.IsSuccess)
                                        Log.Debug(TAG, "File created, open https://drive.google.com to review it");
                                    else
                                        Log.Error(TAG, driveFileResult.Status.StatusMessage);
                                }
                            }
                        }
                    }
                    driveFolder.Dispose();
                    break;
            }
            folderId?.Dispose();
        }
        else
        {
            Log.Error(TAG, metaBufferResult.Status.StatusMessage);
        }
    }
    

    注意事项:

    • 在后台线程上执行此操作
    • 驱动器允许多个同名文件/文件夹 (Title)
      • 如果要替换现有文件,请查询现有文件
      • 查询现有文件夹,除非你真的有多个具有相同Title 的文件夹
    • Trash 中的文件夹和文件将被返回查询,除非被排除在外。
    • 利用Using 块和Dispose 避免泄漏

    【讨论】:

    • 如果我已经有文件夹 ID ,我可以使用这个代码 folderId = DriveId.DecodeFromString("DriveId:1Q-eJcxoTjnZ_7wcAzKvb-WqBlbFyK04h");
    • @MedhatKhalifa EncodeFromString 不会生成稳定的 ID,因此不要硬编码或存储该值,因为它可以(并且将会)更改,因此您的 DecodeFromString 将无法生成有效的驱动器 ID。总是做一个新的查询,它会得到你的 DriveId。 DriveId 实例上的ToInvariantString 将生成一个稳定的 ID,但它用于相等性检查、日志记录等。您可以在其上使用 DecodeFromString。
    • ,好的,但是我如何添加权限以使这个创建的文件夹与其他电子邮件地址共享
    • @MedhatKhalifa 此 API 不会公开访问控制列表 (ACL) 以进行共享,REST api 会这样做,因此您需要通过 OAuth2 登录用户并使用访问令牌进行调用: developers.google.com/drive/v3/web/manage-sharing
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-10
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 2019-08-04
    相关资源
    最近更新 更多