使用Google云端硬盘上的存储访问框架存储文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Google云端硬盘上的存储访问框架存储文件相关的知识,希望对你有一定的参考价值。

我想存储一个带有android存储访问框架的文件。我的测试代码应该存储一个大小为1000000的文件“hallo1”。但是只会创建一个文件大小为0的文件“hallo1”。我没有收到任何错误消息。本地光盘和SD卡上的保存工作正常只有谷歌驱动器不起作用。代码:

        protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        // Get our button from the layout resource,
        // and attach an event to it
        Button button = FindViewById<Button>(Resource.Id.myButton);

        button.Click += delegate
        {
            Intent intentCreate = new Intent(Intent.ActionCreateDocument);
            intentCreate.AddCategory(Intent.CategoryOpenable);
            intentCreate.SetType("audio/*");
            intentCreate.PutExtra(Intent.ExtraTitle, "hallo" + count);
            StartActivityForResult(intentCreate, 1);

            count++;
        };
    }

    protected override  void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        var stream = this.ContentResolver.OpenOutputStream(data.Data, "w");
        var b = new byte[1000000];
        stream.Write(b, 0, b.Length);
        stream.Flush();
        stream.Close();

        base.OnActivityResult(requestCode, resultCode, data);
    }

Filepicker from the android storage access framework

Enter the filename (default "hallo1" from the code)

data.Data给出了一个内部的Android.Net.Uri。

有人知道问题在哪里?

答案

使用Google云端硬盘上的存储访问框架存储文件

请参考:Google Drive API implementation Xamarin Android

其他有用的链接:

Update:

内置存储它的工作原理,在我看来它也适用于谷歌驱动器。

如果不使用Google Drive API,则无法直接实现此功能,您应首先创建文件,然后将文件上传到Google云端硬盘,如下所示:

void IResultCallback.OnResult(Java.Lang.Object result)
{
    var contentResults = (result).JavaCast<IDriveApiDriveContentsResult>();
    if (!contentResults.Status.IsSuccess) // handle the error
        return;
    Task.Run(() =>
    {
        var writer = new OutputStreamWriter(contentResults.DriveContents.OutputStream);
        writer.Write("Stack Overflow");
        writer.Close();
        MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
            .SetTitle("New Text File")
            .SetMimeType("text/plain")
            .Build();
        DriveClass.DriveApi
            .GetRootFolder(_googleApiClient)
            .CreateFile(_googleApiClient, changeSet, contentResults.DriveContents);
    });
}

有关更多详细信息,请参阅上面发布的链接:Google Drive API implementation Xamarin Android


此外,您可以使用Xamarin.Google.Drive.Api.Android nuget包轻松实现此功能,来自document的简单演示:

CloudRail.AppKey = "{Your_License_Key}";
// Google Drive:
GoogleDrive drive = new GoogleDrive(this, "[clientIdentifier]", "", "[redirectUri]", "[state]");
drive.UseAdvancedAuthentication();
ICloudStorage cs = drive;

new System.Threading.Thread(new System.Threading.ThreadStart(() =>
{
    try
    {
        IList<CloudMetaData> filesFolders = cs.GetChildren("/");
        //IList<CloudMetaData> filesFolders = cs.GetChildrenPage("/", 1, 4);  // Path, Offet, Limit
        //cs.Upload(/image_2.jpg,stream,1024,true);   // Path and Filename, Stream (data), Size, overwrite (true/false)
    }
    catch (Exception e)
    {
        System.Console.WriteLine(e.Message);
    }
 })).Start();

Update 2:

要获取我找到的文件名,但不是文件夹名称。

您需要首先从Cursor获取URI,然后您可以检查列名称等。

对于Google云端硬盘,有一个列名称_display_name。这将为您提供文件名。

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    var uri = data.Data;
    ICursor cursor = this.ContentResolver.Query(uri, null, null, null, null);
    cursor.MoveToFirst();

    var filenameIndex = cursor.GetColumnIndex("_display_name");
    var filename = cursor.GetString(filenameIndex);
    System.Diagnostics.Debug.WriteLine("filename == " + filename);
}
另一答案

我找到了解决方案:

        protected override  void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {

        // this works fine:
        using (System.IO.Stream stream = this.ContentResolver.OpenOutputStream(data.Data, "w"))
        {
            using (var javaStream = new Java.IO.BufferedOutputStream(stream))
            {
                var b = new byte[1000000];
                javaStream.Write(b, 0, b.Length);
                javaStream.Flush();
                javaStream.Close();
            }
        }

        // the direct writing on the System.IO.Stream failed:
        //using (System.IO.Stream stream = this.ContentResolver.OpenOutputStream(data.Data, "w"))
        //{
        //    var b = new byte[1000000];
        //    stream.Write(b, 0, b.Length);
        //    stream.Flush();
        //    stream.Close();
        //}

        base.OnActivityResult(requestCode, resultCode, data);
    }

有人知道为什么这个工作和使用System.IO.Stream直接写入失败?

以上是关于使用Google云端硬盘上的存储访问框架存储文件的主要内容,如果未能解决你的问题,请参考以下文章

使用ACTION_CREATE_DOCUMENT写入的文件在Google云端硬盘上为空,但在本地存储中为空

Google云端硬盘服务帐户附加存储

列出所有Google云端硬盘(根)文件

MS Access和Google文件流

使用VBA上传到Google云端硬盘?

Google云端硬盘,在特定文件夹中自动删除超过7天的文件