如何在 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