我想存储一个包含Android存储访问框架的文件。我的测试代码应该存储一个文件" hallo1"大小为1000000.但只有一个文件" hallo1"将创建filesize 0。我没有收到任何错误消息。本地光盘和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。
有人知道问题在哪里?
答案 0 :(得分:1)
使用Google云端硬盘上的存储访问框架存储文件
请参阅:Google Drive API implementation Xamarin Android
其他有用的链接:
使用内部存储,它可以工作,在我看来,它也适用于谷歌驱动器。
您无法在不使用Google云端硬盘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();
获取我找到的文件名但不是文件夹名称。
您需要先从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);
}
答案 1 :(得分:1)
我找到了解决方案:
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直接写入失败了?