繁体   English   中英

无法从 URL Xamarin Form 下载图像

[英]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");
    }
}

但它不起作用,没有发现错误,我收到警报,警告我下载已完成。 我还允许internetwrite_external_storageread_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 模式重构另一种方法,但我想这为您提供了一个很好的起点。

编辑:

关于您编辑的新方法,请尝试使用DownloadDataTaskAsyncCopyToAsync方法以及 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM