c# - Xamarin.Forms:如何下载图像,将其保存在本地并在屏幕上显示?

标签 c# xamarin xamarin.forms xamarin.essentials

我在 Android 上的 native 应用程序中打开 JPG 文件时遇到问题。 我正在使用最新版本的 Xamarin Essentials,有一些功能称为 Launcher。 这是我的代码

await Launcher.TryOpenAsync("file:///" + localPath);

我的本​​地路径是存储在 Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); 中的文件。

每当我尝试打开该文件时,我都会收到错误消息:

file:////data/user/0/mypackagename/files/.local/share/Screenshot.jpg exposed beyond app through Intent.getData()

我在 stackoverflow 上找到了几个解决方案,但我不想使用 Intent,因为我的应用程序被设计为跨平台的(如果可能的话,我想避免使用 native 平台编码)。

Launcher 在 iOS 上也会抛出错误:

canOpenURL: failed for URL: ** -- file:///" - error: "This app is not allowed to query for scheme file

我在这里做错了什么?

最佳答案

第一步:下载图片

我们可以使用HttpClient来下载图片。

HttpClient.GetByteArrayAsync 将检索图像数据并将其保存在内存中。

在下面的 DownloadImage 中,我们将检索图像作为 byte[]

static class ImageService
{
    static readonly HttpClient _client = new HttpClient();

    public static Task<byte[]> DownloadImage(string imageUrl)
    {
        if (!imageUrl.Trim().StartsWith("https", StringComparison.OrdinalIgnoreCase))
            throw new Exception("iOS and Android Require Https");

        return _client.GetByteArrayAsync(imageUrl);
    }
}

第 2 步将图像保存到磁盘

现在我们已经下载了图像,我们将把它保存到磁盘。

Xamarin.Essentials.Preferences 允许我们使用键值对将项目保存到磁盘。由于 byte[] 只是指向内存的指针,我们必须先将 byte[] 转换为 base64 字符串,然后才能将其保存到磁盘。

static class ImageService
{
    static readonly HttpClient _client = new HttpClient();

    public static Task<byte[]> DownloadImage(string imageUrl)
    {
        if (!imageUrl.Trim().StartsWith("https", StringComparison.OrdinalIgnoreCase))
            throw new Exception("iOS and Android Require Https");

        return _client.GetByteArrayAsync(imageUrl);
    }

    public static void SaveToDisk(string imageFileName, byte[] imageAsBase64String)
    {
        Xamarin.Essentials.Preferences.Set(imageFileName, Convert.ToBase64String(imageAsBase64String));
    }
}

第 3 步检索要显示的图像

现在我们已经下载了图像并将其保存到磁盘,我们需要能够从磁盘检索图像以将其显示在屏幕上。

下面的

GetFromDisk 从磁盘检索图像并将其转换为 Xamarin.Forms.ImageSource

static class ImageService
{
    static readonly HttpClient _client = new HttpClient();

    public static Task<byte[]> DownloadImage(string imageUrl)
    {
        if (!imageUrl.Trim().StartsWith("https", StringComparison.OrdinalIgnoreCase))
            throw new Exception("iOS and Android Require Https");

        return _client.GetByteArrayAsync(imageUrl);
    }

    public static void SaveToDisk(string imageFileName, byte[] imageAsBase64String)
    {
        Xamarin.Essentials.Preferences.Set(imageFileName, Convert.ToBase64String(imageAsBase64String));
    }

    public static Xamarin.Forms.ImageSource GetFromDisk(string imageFileName)
    {
        var imageAsBase64String = Xamarin.Essentials.Preferences.Get(imageFileName, string.Empty);

        return ImageSource.FromStream(() => new MemoryStream(Convert.FromBase64String(imageAsBase64String)));
    }
}

示例:在 Xamarin.Forms.ContentPage 中使用 ImageService

class App : Application
{
    public App() => MainPage = new MyPage();
}

class MyPage : ContentPage
{
    readonly Image _downloadedImage = new Image();

    public MyPage()
    {
        Content = _downloadedImage;
    }

    protected override  async void OnAppearing()
    {
        const string xamrainImageUrl = "https://cdn.dribbble.com/users/3701/screenshots/5557667/xamarin-studio-1_2x_4x.png"
        const string xamarinImageName = "XamarinLogo.png";

        var downloadedImage = await ImageService.DownloadImage(xamrainImageUrl);

        ImageService.SaveToDisk(xamarinImageName, downloadedImage);

        _downloadedImage.Source = ImageService.GetFromDisk(xamarinImageName);
    }
}

enter image description here

关于c# - Xamarin.Forms:如何下载图像,将其保存在本地并在屏幕上显示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59632849/

相关文章:

c# - catch block 没有在另一个线程中捕获异常

c# - 如何处理 ibm.data.db2.iseries 异常

ios - 使用 Xamarin iOS 进行客户端证书身份验证

azure - 无法将 Microsoft.Azure.Mobile.Server.Authentication 安装到 Xamarin Forms 中

c# - 格式化小数 xamarin

c# - 在 Unity 中构建旋转电梯

c# - 用于图像扩展的 ASPNET Core img src 通配符

android - 无法从 Android Windows 模拟器访问本地主机 (Visual Studio 2015/Xamarin)

android - MvxListView 未绑定(bind)到 MvxItemTemplate

c# - 如何使用 MVVM 模式在 Xamarin Forms 中为 ZXingScannerView 添加自定义叠加层?