Как создать файл с Xamarin.Forms на Android? - PullRequest
0 голосов
/ 12 октября 2018

Я хотел бы создать публичный файл на моем телефоне Android, который я могу найти без рут-доступа.Где-то, где пользователь может найти и прочитать его.

Мой текущий код не выдает ошибку в списке ошибок 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, таких как File, Справочник и т. Д. (https://youtu.be/Xrh6ZJcxtZ8 (4:14)).

На видео ТАКЖЕ показано, что они были доступны только в проектах, связанных с платформой (https://youtu.be/Xrh6ZJcxtZ8 (4:35)).

Итак, я создал интерфейс в библиотеке PCL и добавил класс, который реализует интерфейс, в моей папке ресурсов для конкретных проектов на платформе Android.Я вставил код, который у меня уже был (см. Выше 1: блок кода).Я вызвал интерфейс на своей странице при обработке события клика.Код работает нормально, и я получаю предупреждение об успехе, но я не могу найти файл на своем устройстве.

2:

Подобные вопросы не помоглипроблема для меня:

Как использовать внутреннее хранилище Android в Xamarin? Как создать файл в 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

enter image description here enter image description here

Если я использую Path.Combine без предложенного Riciprini /

enter image description here

Что решило мою проблему

Я пошел против совета Riciprinis, поэтому отказался от / и последовал совету Riciprinis, чтобы изменить строку папки.

Этот код добился цели или, возможно, закончил работу (посмотрите на разговор между мной и Rciprini вкомментарии к его ответу для большего количества вещей, которые я сделал):

Код ниже помещен в функцию CreateFile из моего класса FileSaver, где находится исходная папка и путь.

string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;            
string path = System.IO.Path.Combine(folder, "test.txt");    

1 Ответ

0 голосов
/ 12 октября 2018

Решение:

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

Если вы хотите добавить разрешения времени выполнения запроса, следуйте этому Запросить разрешения времени выполнения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...