使用存储访问框架将文件存储在 Google 驱动器上
Store file with the storage access framework on Google Drive
我想使用 Android 存储访问框架存储文件。我的测试代码应该存储一个大小为 1000000 的文件 "hallo1"。但是只会创建文件大小为 0 的文件 "hallo1"。我没有收到错误消息。本地磁盘和 sd 卡上的保存工作正常 google 驱动器不工作。
代码:
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 返回。
有人知道问题出在哪里吗?
Store file with the storage access framework on Google Drive
请参考:
其他有用的links:
更新:
With internal storage it works and in my opinion it should also work with google drive.
不使用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);
});
}
更详细的信息参考上面的link我post:.
此外,您可以使用 Xamarin.Google.Drive.Api.Android nuget package to implement this feature easily, simple demo from the 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();
更新 2:
To get the filename I found but not the folder name.
您需要先从 URI
中获取 Cursor
,然后您可以检查列名等。
对于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 直接写入失败了吗?
我想使用 Android 存储访问框架存储文件。我的测试代码应该存储一个大小为 1000000 的文件 "hallo1"。但是只会创建文件大小为 0 的文件 "hallo1"。我没有收到错误消息。本地磁盘和 sd 卡上的保存工作正常 google 驱动器不工作。 代码:
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 返回。
有人知道问题出在哪里吗?
Store file with the storage access framework on Google Drive
请参考:
其他有用的links:
更新:
With internal storage it works and in my opinion it should also work with google drive.
不使用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);
});
}
更详细的信息参考上面的link我post:
此外,您可以使用 Xamarin.Google.Drive.Api.Android nuget package to implement this feature easily, simple demo from the 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();
更新 2:
To get the filename I found but not the folder name.
您需要先从 URI
中获取 Cursor
,然后您可以检查列名等。
对于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 直接写入失败了吗?