代码之家  ›  专栏  ›  技术社区  ›  Jason Coyne

如何在Android上读取MAUI/Xamarin中部署的文件

  •  0
  • Jason Coyne  · 技术社区  · 4 年前

    我有一个小的MAUI应用程序正在测试中。我正在尝试读取部署中的一个文件。我有下面的代码,它在MAUI应用程序的Windows部署中运行良好,但在Android中崩溃。什么是正确的跨平台方式?

            // TODO get from service or xml
            var path = AppDomain.CurrentDomain.BaseDirectory;
            //var path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
            var fullpath = Path.Combine(path, "Services\\questions.json");
            var json = File.ReadAllText(fullpath);
    
    1 回复  |  直到 4 年前
        1
  •  5
  •   ToolmakerSteve    4 年前

    MAUI有一种新的方式来访问应用程序中包含的文件: MauiAsset .

    在博客中描述 Announcing .NET MAUI Preview 4, Raw Assets :

    .NET MAUI现在可以很容易地将其他资产添加到项目中并直接引用它们,同时保留平台本机性能。例如,如果要在WebView中显示静态HTML文件,可以将该文件添加到项目中,并在特性中将其注释为MauiAsset。

    <MauiAsset Include="Resources\Raw\index.html" />
    

    提示:您还可以使用通配符启用目录中的所有文件:

    ... Include="Resources\Raw\*" ...
    

    然后您可以按文件名在应用程序中使用它。

    <WebView Source="index.html" />
    

    更新

    然而,该功能 MauiAsset 显然仍需改进:

    open issue - MauiAsset is very hard to use .

    在这里,我们了解到:

    设置 BuildAction 在每个文件的属性中 MauiAsset .

    也就是说,目前不建议使用“通配符”方法。在解决方案资源管理器/您的项目/文件中设置每个文件的构建操作。

    在Windows上访问需要解决方法:

    #if WINDOWS
        var stream = await Microsoft.Maui.Essentials.FileSystem.OpenAppPackageFileAsync("Assets/" + filePath);
    #else
        var stream = await Microsoft.Maui.Essentials.FileSystem.OpenAppPackageFileAsync(filePath);
    #endif
    

    注:这将在某个时候被简化;关注这个问题,看看进展。


    更新

    当前MAUI模板缺少一些特定于平台的标志。现在,添加您自己的标志来识别代码何时在Windows上运行:

    enter image description here


    中的完整示例 ToolmakerSteve - repo MauiSOAnswers 看见 MauiAssetPage .

    MauiAssetPage.xaml :

    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="MauiTests.MauiAssetPage">
        <ContentPage.Content>
            <!-- By the time Maui is released, this is all you will need. -->
            <!-- The Init code-behind won't be needed. -->
            <WebView x:Name="MyWebView" Source="TestWeb.html" />
        </ContentPage.Content>
    </ContentPage>
    

    MauiAssetPage.xaml.cs :

    using Microsoft.Maui.Controls;
    using System.Threading.Tasks;
    
    namespace MauiTests
    {
        public partial class MauiAssetPage : ContentPage
        {
            public MauiAssetPage()
            {
                InitializeComponent();
    
                Device.BeginInvokeOnMainThread(async () =>
                {
                    await InitAsync();
                });
            }
    
            private async Task InitAsync()
            {
                string filePath = "TestWeb.html";
    #if WINDOWS
                var stream = await Microsoft.Maui.Essentials.FileSystem.OpenAppPackageFileAsync("Assets/" + filePath);
    #else
                var stream = await Microsoft.Maui.Essentials.FileSystem.OpenAppPackageFileAsync(filePath);
    #endif
    
                if (stream != null)
                {
                    string s = (new System.IO.StreamReader(stream)).ReadToEnd();
                    this.MyWebView.Source = new HtmlWebViewSource { Html = s };
                }
            }
        }
    }
    

    TestWeb.html :

    (whatever html you want)
    

    在里面 Solution Explorer 添加 TestWeb.html 到您的项目。在其 Properties 选择 Build Action = MauiAsset .

        2
  •  0
  •   Sydney    3 年前

    几个月来,我一直在努力寻找解决方案。我最终在线托管了该文件,然后创建了一个在运行时下载该文件的方法

    
    public  async Task DownloadFile(string fileName)
    {  
              if (File.Exists(FileSystem.Current.AppDataDirectory + $"/{fileName}"))
                {
                    return;
                }
    
                else
                {
                    try
                    {
                        
                        NetworkAccess networkAccess = Connectivity.Current.NetworkAccess;
    
                        if (networkAccess == NetworkAccess.Internet)
                        {
                            
                            await Task.Run(() =>
                            {
                                var uri = new Uri($"https://myhostedfile.com/{fileName}");
                                WebClient webClient = new WebClient();
                                webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCallback2);//checking if download is complete
                                webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(MaintainProgress);//event handler to check download progress
                                webClient.DownloadFileAsync(uri, FileSystem.Current.AppDataDirectory + $"/{fileName}");
                                
                            });
    
                        }
    
                        else
                            await Shell.Current.DisplayAlert("No Internet", "Failed to get some files from the internet, confirm if your internet is" +
                              "working", "OK");
    
    
    
                    }
                    catch (Exception)
                    {
    
                        await Shell.Current.DisplayAlert("Error", "Failed to get some files from the internet, confirm if your internet is" +
                            "working", "OK");
                    }
                }          
            }
    

    然后,您可以使用以下方式访问您的文件URL:

    string filePath = FileSystem.Current.AppDataDirectory + $"/myfile.pdf;