【问题标题】:Xamarin.Forms: How to download an Image, save it locally and display it on screen?Xamarin.Forms:如何下载图像,将其保存在本地并在屏幕上显示?
【发布时间】:2020-01-07 16:57:54
【问题描述】:

我在 Android 上的本机应用程序中打开 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,因为我的应用程序被设计为跨平台的(如果可能的话,我想避免使用原生平台编码)。

Launcher 在 iOS 上也抛出错误:

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

我在这里做错了什么?

【问题讨论】:

  • 你的目标是什么?是不是要在屏幕上显示保存为嵌入资源的Image,stackoverflow.com/a/50031151/5953643
  • 我需要从服务器下载文件并以某种方式呈现。我认为这将是最简单的解决方案。
  • 知道了!我们将使用 Xamarin.Essentials.Preferences 从磁盘保存/检索文件。 Xamarin.Essentials.Launcher 用于打开其他应用,例如设置或 Twitter。
  • @BrandonMinnick 如果您找到了解决方案,您能否添加一个描述您所做工作的答案?这可以在未来帮助开发人员
  • @PaulKertscher 当然!我在 11 小时前回答了这个问题,如下:stackoverflow.com/a/59634820/5953643

标签: c# xamarin xamarin.forms xamarin.essentials


【解决方案1】:

第 1 步:下载图片

我们可以使用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);
    }
}

【讨论】:

  • 我想在本机应用程序中打开此图像。这可能吗?我已经实施了与您类似的解决方案,但我对此并不满意。
  • 您能否详细说明一下您所说的原生应用程序是什么意思?你在使用 Xamarin.Forms 吗?
  • 是的,我正在使用 Xamarin 表单。我想下载 jpg 文件(已完成),然后在 Android/iOS 上的默认应用程序中打开该 jpg(用这张照片打开照片浏览器)
  • 哦-好的。这是一个完全不同的问题和一个完全不同的过程。让我们这样做:使用该特定解释打开一个新问题,然后在下面使用链接发表评论,我们将在那里回答。我不想删除这个问题和这个答案,因为两者都已经有了一堆观点和赞成票,这意味着这个讨论对其他开发者有帮助。
  • 好的,这里有新问题:stackoverflow.com/questions/59642350/…
猜你喜欢
  • 2020-12-27
  • 2021-07-04
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
  • 2010-11-03
  • 2017-05-11
相关资源
最近更新 更多