Xamarin.Forms: 如何下载图片,保存到本地并显示在屏幕上?
Xamarin.Forms: How to download an Image, save it locally and display it on screen?
我在 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()
我在 Whosebug 上找到了几个解决方案,但我不想使用 Intent,因为我的应用程序被设计为跨平台的(如果可能的话,我想避免使用本机平台编码)。
启动器在 iOS 上也抛出错误:
canOpenURL: failed for URL: ** -- file:///" - error: "This app is not allowed to query for scheme file
我做错了什么?
第 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);
}
}
我在 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()
我在 Whosebug 上找到了几个解决方案,但我不想使用 Intent,因为我的应用程序被设计为跨平台的(如果可能的话,我想避免使用本机平台编码)。
启动器在 iOS 上也抛出错误:
canOpenURL: failed for URL: ** -- file:///" - error: "This app is not allowed to query for scheme file
我做错了什么?
第 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);
}
}