[英]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.