如何在 Android 上创建带有 Xamarin.Forms 的文件?
How to create a file with Xamarin.Forms on Android?
我想在我的 android phone 上创建一个 public 文件,我可以在没有 root 访问权限的情况下找到它。用户可以找到并阅读它的地方。
我当前的代码没有在 Visual Studio 错误列表中给出错误。只有 36 条警告,关于无法使用调试符号读取 mono.android.dll 等文件,以及关于在我的 FileSaver class 中不使用声明的异常。目前,我认为这不相关。我没有例外。我的代码成功到达文件创建警报。
如果有人能把我推向正确的方向或知道我犯的错误,我会洗耳恭听。
我的代码:
XAML 按钮部分
<Button x:Name="CreateFile" />
XAML.CS 构造函数和点击部分
public MyPage ()
{
InitializeComponent ();
CreateFile.Clicked += OnCreateFileClicked;
}
private async void OnCreateFileClicked(object sender, EventArgs e)
{
IFileSaver FileSaver = DependencyService.Get<IFileSaver>();
if (await FileSaver.CreateFile())
{
await this.DisplayAlert("The file is created","Created file","Okay","Okay");
} else
{
await this.DisplayAlert("The file is NOT CREATED", "The file is NOT CREATED", ":(", ";-;");
}
}
界面
using System.Threading.Tasks;
namespace PvApp
{
/*
* You can't use C# friends File, Directory, Streamwriter etc. (system.io) in the PCL (public class library).
* So we do it in the platform specific libraries.
*/
public interface IFileSaver
{
Task<bool> CreateFile();
}
}
文件保护程序class
using System.Threading.Tasks;
using Xamarin.Forms;
using PvApp.Droid.Assets;
[assembly: Dependency(typeof(FileSaver))]
namespace PvApp.Droid.Assets
{
class FileSaver : IFileSaver
{
public async Task<bool> CreateFile()
{
//TRIED: .MyDocuments,
string folder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
string path = System.IO.Path.Combine(folder, "test.txt");
try
{
System.IO.File.Create(path);
return await Task.FromResult(true);
}
catch (System.Exception exception)
{
return await Task.FromResult(false);
}
}
}
}
我做过的事情
1:
我在 Xamarin 大学看到了这个视频,它向我展示了我可以使用 System.IO 命名空间中的一些老朋友,例如文件、目录等 (https://youtu.be/Xrh6ZJcxtZ8 (4:14))。
视频还向我展示了它们只能在特定于平台的项目中访问 (https://youtu.be/Xrh6ZJcxtZ8 (4:35))。
所以我在 PCL 库中创建了一个接口,并在我的 Android 平台特定项目资产文件夹中添加了一个实现该接口的 class。我输入了我已有的代码(见上文 1:代码块)。我在单击事件处理程序的页面中调用了该接口。代码运行正常,我收到成功提醒,但我在我的设备上找不到该文件。
2:
像这样的问题并没有解决我的问题:
How to create a file in Android?
3:
我检查了是否需要权限。内部存储不需要权限。
4:
我尝试了网站上的其他代码或应该创建文件的 Whosebug 问题。 Application.Context.FilesDir.Path,例如,它没有帮助。我无法让它发挥作用。为了这篇post的篇幅,我把它们放在外面了。
试过 Riciprinis 代码:
{System.UnauthorizedAccessException: Access to the path "/test.txt" is denied.
at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x001b7] in <4d6eb5dfe2ab4eee884ef920069afd5f>:0
at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize) [0x00000] in <4d6eb5dfe2ab4eee884ef920069afd5f>:0
at (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,int)
at System.IO.File.Create (System.String path, System.Int32 bufferSize) [0x00000] in <4d6eb5dfe2ab4eee884ef920069afd5f>:0
at System.IO.File.Create (System.String path) [0x00000] in <4d6eb5dfe2ab4eee884ef920069afd5f>:0
at PvApp.Droid.Assets.FileSaver+<CreateFile>d__0.MoveNext () [0x00058] in (Filepath to my FileSaver.cs and to function System.IO.File.Create(path);)
尝试了 Riciprinis 内部存储权限:
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
Riciprini 建议的断点
如果我使用 Path.Combine 而没有 Riciprini 的建议 /
什么解决了我的问题
我反对 Riciprinis 的建议,所以我放弃了 /
并按照 Riciprinis 的建议更改文件夹字符串。
这段代码成功了,或者可能完成了工作(查看我和 Rciprini 在他的回答评论中的对话,了解我所做的更多事情):
下面的代码放在我的 FileSaver class 的 CreateFile 函数中,其中原始文件夹和路径所在。
string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
string path = System.IO.Path.Combine(folder, "test.txt");
解决方案:
string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
如果你想添加请求运行时权限,按照这个Request Runtime Permissions
我想在我的 android phone 上创建一个 public 文件,我可以在没有 root 访问权限的情况下找到它。用户可以找到并阅读它的地方。
我当前的代码没有在 Visual Studio 错误列表中给出错误。只有 36 条警告,关于无法使用调试符号读取 mono.android.dll 等文件,以及关于在我的 FileSaver class 中不使用声明的异常。目前,我认为这不相关。我没有例外。我的代码成功到达文件创建警报。
如果有人能把我推向正确的方向或知道我犯的错误,我会洗耳恭听。
我的代码:
XAML 按钮部分
<Button x:Name="CreateFile" />
XAML.CS 构造函数和点击部分
public MyPage ()
{
InitializeComponent ();
CreateFile.Clicked += OnCreateFileClicked;
}
private async void OnCreateFileClicked(object sender, EventArgs e)
{
IFileSaver FileSaver = DependencyService.Get<IFileSaver>();
if (await FileSaver.CreateFile())
{
await this.DisplayAlert("The file is created","Created file","Okay","Okay");
} else
{
await this.DisplayAlert("The file is NOT CREATED", "The file is NOT CREATED", ":(", ";-;");
}
}
界面
using System.Threading.Tasks;
namespace PvApp
{
/*
* You can't use C# friends File, Directory, Streamwriter etc. (system.io) in the PCL (public class library).
* So we do it in the platform specific libraries.
*/
public interface IFileSaver
{
Task<bool> CreateFile();
}
}
文件保护程序class
using System.Threading.Tasks;
using Xamarin.Forms;
using PvApp.Droid.Assets;
[assembly: Dependency(typeof(FileSaver))]
namespace PvApp.Droid.Assets
{
class FileSaver : IFileSaver
{
public async Task<bool> CreateFile()
{
//TRIED: .MyDocuments,
string folder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
string path = System.IO.Path.Combine(folder, "test.txt");
try
{
System.IO.File.Create(path);
return await Task.FromResult(true);
}
catch (System.Exception exception)
{
return await Task.FromResult(false);
}
}
}
}
我做过的事情
1:
我在 Xamarin 大学看到了这个视频,它向我展示了我可以使用 System.IO 命名空间中的一些老朋友,例如文件、目录等 (https://youtu.be/Xrh6ZJcxtZ8 (4:14))。
视频还向我展示了它们只能在特定于平台的项目中访问 (https://youtu.be/Xrh6ZJcxtZ8 (4:35))。
所以我在 PCL 库中创建了一个接口,并在我的 Android 平台特定项目资产文件夹中添加了一个实现该接口的 class。我输入了我已有的代码(见上文 1:代码块)。我在单击事件处理程序的页面中调用了该接口。代码运行正常,我收到成功提醒,但我在我的设备上找不到该文件。
2:
像这样的问题并没有解决我的问题:
3:
我检查了是否需要权限。内部存储不需要权限。
4:
我尝试了网站上的其他代码或应该创建文件的 Whosebug 问题。 Application.Context.FilesDir.Path,例如,它没有帮助。我无法让它发挥作用。为了这篇post的篇幅,我把它们放在外面了。
试过 Riciprinis 代码:
{System.UnauthorizedAccessException: Access to the path "/test.txt" is denied.
at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x001b7] in <4d6eb5dfe2ab4eee884ef920069afd5f>:0
at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize) [0x00000] in <4d6eb5dfe2ab4eee884ef920069afd5f>:0
at (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,int)
at System.IO.File.Create (System.String path, System.Int32 bufferSize) [0x00000] in <4d6eb5dfe2ab4eee884ef920069afd5f>:0
at System.IO.File.Create (System.String path) [0x00000] in <4d6eb5dfe2ab4eee884ef920069afd5f>:0
at PvApp.Droid.Assets.FileSaver+<CreateFile>d__0.MoveNext () [0x00058] in (Filepath to my FileSaver.cs and to function System.IO.File.Create(path);)
尝试了 Riciprinis 内部存储权限:
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
Riciprini 建议的断点
如果我使用 Path.Combine 而没有 Riciprini 的建议 /
什么解决了我的问题
我反对 Riciprinis 的建议,所以我放弃了 /
并按照 Riciprinis 的建议更改文件夹字符串。
这段代码成功了,或者可能完成了工作(查看我和 Rciprini 在他的回答评论中的对话,了解我所做的更多事情):
下面的代码放在我的 FileSaver class 的 CreateFile 函数中,其中原始文件夹和路径所在。
string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
string path = System.IO.Path.Combine(folder, "test.txt");
解决方案:
string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
如果你想添加请求运行时权限,按照这个Request Runtime Permissions