【发布时间】:2019-03-17 15:33:59
【问题描述】:
我想在我的安卓手机上创建一个公共文件,我可以在没有 root 访问权限的情况下找到它。用户可以在某个地方找到并阅读它。
我当前的代码在 Visual Studio 错误列表中没有给出错误。只有 36 个关于无法读取带有调试符号的 mono.android.dll 之类的文件以及关于在我的 FileSaver 类中不使用声明的异常的警告。目前,我认为这没有关系。我没有例外。我的代码成功进入了创建警报的文件。
如果有人能把我推向正确的方向或知道我正在犯的错误,我会全力以赴。
我的代码:
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();
}
}
FileSaver 类
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 平台特定项目资产文件夹中添加了一个实现该接口的类。我输入了我已经拥有的代码(参见上面的 1:代码块)。我在点击事件处理程序的页面中调用了该接口。代码运行良好,我收到成功警报,但在我的设备上找不到该文件。
2:
这样的问题并没有解决我的问题:
How to use Internal Storage of Android in Xamarin? How to create a file in Android?
3:
我检查了是否需要权限。内部存储不需要权限。
4:
我尝试了来自网站的其他代码或应该创建文件的 StackOverflow 问题。例如,Application.Context.FilesDir.Path 没有帮助。我无法让它工作。为了这篇文章的篇幅,我将它们排除在外。
试过 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 建议的断点
如果我在没有 Riciprini 建议的情况下使用 Path.Combine /
什么解决了我的问题
我反对 Riciprini 的建议,所以我放弃了 / 并按照 Riciprini 的建议更改文件夹字符串。
这段代码起到了作用,或者可能完成了工作(查看我和 Rciprini 在他的答案的 cmets 之间的对话,了解我所做的更多事情):
下面的代码是从我的FileSaver类中的CreateFile函数中放置的原始文件夹和路径在哪里。
string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
string path = System.IO.Path.Combine(folder, "test.txt");
【问题讨论】:
-
你确定你没有遇到异常吗?您的 try/catch 块似乎忽略了抛出的任何异常
-
它如何忽略任何异常?请帮助我理解它。
-
它返回 false,但您不会以任何方式记录异常,因此您不知道实际的潜在错误是什么。了解引发了哪些特定异常将有助于您进行调试
-
我知道如果 try 块失败,CreateFile 会返回 false,但它不会失败,所以 CreateFile 返回 true。
-
如果它返回 true 并且现在抛出异常,那么它可能正在创建您的文件。你确定不是吗?如果你做一个 File.Exists() 那里有文件吗?
标签: c# android xamarin.forms system.io.file