[英]Unable to download Image from URL Xamarin Form
我正在开发一个 Xamarin 应用程序,它从数据库中检索信息,拍摄/选择照片并将它们上传到远程服务器,从远程服务器显示这些图像,用户可以通过点击并按下按钮来删除它们。 最后一步是将存储在服务器中的图像下载到本地设备库。
这是我当前的按钮单击事件:
private void button_download_image_Clicked(object sender, EventArgs e)
{
Uri image_url_format = new Uri(image_url);
WebClient webClient = new WebClient();
try
{
webClient.DownloadDataAsync(image_url_format);
webClient.DownloadDataCompleted += webClient_DownloadDataCompleted;
}
catch (Exception ex)
{
DisplayAlert("Error", ex.ToString(), "OK");
}
}
在webClient_DownloadDataCompleted
方法下方:
private void webClient_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
try
{
Uri image_url_format = new Uri(image_url);
byte[] bytes_image = e.Result;
Stream image_stream = new MemoryStream(bytes_image);
string dest_folder= Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).ToString();
string file_name= Path.GetFileName(image_url_format.LocalPath);
string dest_path= Path.Combine(dest_folder, file_name);
using (var fileStream = new FileStream(dest_path, FileMode.Create, FileAccess.Write))
{
image_stream.CopyTo(fileStream);
}
DisplayAlert("Alert", "Download completed!", "OK");
}
catch (Exception ex)
{
DisplayAlert("Error", ex.ToString(), "OK");
}
}
但它不起作用,没有发现错误,我收到警报,警告我下载已完成。 我还允许internet , write_external_storage和read_external_storage 。
另一件事是,一段时间后,图像出现在“下载相册”下的图库中,这是正确的。
对这种行为有什么想法吗?
编辑
在我的新按钮下载事件下方:
private void button_download_image_Clicked(object sender, EventArgs e)
{
Uri image_url_format = new Uri(image_url);
WebClient webClient = new WebClient();
try
{
byte[] bytes_image = webClient.DownloadData(image_url_format);
Stream image_stream = new MemoryStream(bytes_image);
string dest_folder = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).ToString();
string file_name = Path.GetFileName(image_url_format.LocalPath);
string dest_path = Path.Combine(dest_folder, file_name);
using (var fileStream = new FileStream(dest_path, FileMode.Create, FileAccess.Write))
{
image_stream.CopyTo(fileStream);
}
}
catch (Exception ex)
{
DisplayAlert("Error", ex.ToString(), "OK");
}
DisplayAlert("Alert", "File scaricato con successo", "OK");
}
原因
您的功能“触发并忘记”下载,然后直接向您显示“下载完成”弹出窗口。 原因是您以同步方式( DownloadDataAsync
)调用异步函数......这就是为什么它会在一段时间后仍然出现在库中而您仍然会弹出。
解决方案
您应该首先阅读: https : //docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
然后作为起点,尝试声明您的事件处理程序 async 并在适当的地方使用 await 关键字:
private async void button_download_image_Clicked(object sender, EventArgs e)
{
Uri image_url_format = new Uri(image_url);
WebClient webClient = new WebClient();
try
{
await webClient.DownloadDataAsync(image_url_format); // This will await the download
...
}
catch (Exception ex)
{
...
}
}
当然,最好也使用 async/await 模式重构另一种方法,但我想这为您提供了一个很好的起点。
编辑:
关于您编辑的新方法,请尝试使用DownloadDataTaskAsync
和CopyToAsync
方法以及 async/await 模式:
private async void button_download_image_Clicked(object sender, EventArgs e)
{
Uri image_url_format = new Uri("url");
WebClient webClient = new WebClient();
try
{
byte[] bytes_image = await webClient.DownloadDataTaskAsync(image_url_format);
Stream image_stream = new MemoryStream(bytes_image);
string dest_folder = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).ToString();
string file_name = Path.GetFileName(image_url_format.LocalPath);
string dest_path = Path.Combine(dest_folder, file_name);
using (var fileStream = new FileStream(dest_path, FileMode.Create, FileAccess.Write))
{
await image_stream.CopyToAsync(fileStream);
}
}
catch (Exception ex)
{
await DisplayAlertAsync("Error", ex.ToString(), "OK");
}
await DisplayAlertAsync("Alert", "File scaricato con successo", "OK");
}
此外,您应该创建一个DisplayAlertAsync
方法并使用 await 以相同的方式调用它。
快乐编码!
图像已正确下载,我可以在文件资源管理器中看到它。
我通过重新刷新图库解决了我的问题,保存图像后使用此行,因此方法将是:
private void button_download_image_Clicked(object sender, EventArgs e)
{
Uri image_url_format = new Uri(image_url);
WebClient webClient = new WebClient();
try
{
byte[] bytes_image = webClient.DownloadData(image_url_format);
Stream image_stream = new MemoryStream(bytes_image);
string dest_folder = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).ToString();
string file_name = Path.GetFileName(image_url_format.LocalPath);
string dest_path = Path.Combine(dest_folder, file_name);
using (var fileStream = new FileStream(dest_path, FileMode.Create, FileAccess.Write))
{
image_stream.CopyTo(fileStream);
}
// this 3 lines fix my problem
var mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
mediaScanIntent.SetData(Android.Net.Uri.FromFile(new Java.IO.File(dest_path)));
Android.App.Application.Context.SendBroadcast(mediaScanIntent);
}
catch (Exception ex)
{
DisplayAlert("Error", ex.ToString(), "OK");
}
DisplayAlert("Alert", "File scaricato con successo", "OK");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.