无法从URL Xamarin表单下载图像

时间:2020-01-27 08:03:21

标签: c# xamarin xamarin.forms download xamarin.android

我正在开发一个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");
}

2 个答案:

答案 0 :(得分:0)

原因

您的函数“触发并忘记”下载内容,然后直接向您显示“下载完成”弹出窗口。原因是您正在以同步方式(<DownloadDataAsync)调用异步函数...这就是为什么它仍然会在画廊中显示但仍然弹出的原因

解决方案

您应该首先阅读以下内容:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/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模式来重构另一种方法,但这是给你一个很好的起点。

编辑:

关于您编辑的新方法,请尝试使用DownloadDataTaskAsyncCopyToAsync方法以及异步/等待模式:

 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以相同的方式调用它。

祝您编程愉快!

答案 1 :(得分:0)

该图像已正确下载,我可以在文件浏览器中看到它。

保存图片后,通过刷新图库解决了我的问题,因此方法是:

mod_arr
相关问题