【问题标题】:How to create a file with Xamarin.Forms on Android?如何在 Android 上使用 Xamarin.Forms 创建文件?
【发布时间】: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


【解决方案1】:

解决方案:

string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;            

如果您想添加请求运行时权限,请关注此Request Runtime Permissions

【讨论】:

  • 我试过你的代码,但没有运气,除非我得到的异常指出我的错误在哪里。请参阅我更新的问题帖子。
  • 你添加了内部存储权限吗? {System.UnauthorizedAccessException:对路径“/test.txt”的访问被拒绝。你确定吗?
  • 我尝试使用读写外部存储权限,但据我所知,没有内部存储权限吗?
  • 对于外部存储权限,请尝试关注此视频link尝试在string folder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);这一行下一个断点,看看路径是否有这个/
  • 尝试将 string folder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); 更改为 string folder =Android.OS.Environment.ExternalStorageDirectory.AbsolutePath 并检查文件是否在本地存储中创建,如果没有创建,则问题是权限
猜你喜欢
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 2013-12-17
  • 2011-04-01
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多