【问题标题】:Image does not display in gallery after download下载后图片不显示在图库中
【发布时间】:2020-05-13 22:07:08
【问题描述】:

我正在开发一个 Xamarin 应用程序,它从数据库中检索信息,拍摄/选择照片并将它们上传到远程服务器,从远程服务器显示这些图像,用户可以通过点击并按下按钮来删除它们并下载图像从远程服务器到本地设备。

一切正常,但是当我下载图像并去画廊检查后,图像没有出现,而我可以看到它并在文件资源管理器中打开。当我重新启动手机时,图片会出现在图库中。

下面是我目前的按钮下载方式

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 = System.IO.Path.GetFileName(image_url_format.LocalPath);
        string dest_path = System.IO.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", "Download completed!", "OK");
}

我在另一台设备上尝试过,但我得到了相同的行为。

可能有某种东西不会刷新图库。

知道如何强制画廊刷新或类似的东西吗?

【问题讨论】:

  • 您的问题已经被报告了一百次,所以用 google 搜索这两个代码行的解决方案应该不难。您也可以重新启动设备。
  • @blackapps 抱歉,我没有发现任何对我的情况有用的东西,而且每次下载图像时我都无法重新启动设备..
  • 不,当然不是。它只是对您的Any idea how to force the gallery to refresh 的回答。

标签: c# android image xamarin.forms download


【解决方案1】:

插入或删除存储中的任何图片后,您需要刷新图库。

你可以试试这个。

            var mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
            mediaScanIntent.SetData(Android.Net.Uri.FromFile(new Java.IO.File(dest_path)));
            Xamarin.Forms.Forms.Context.SendBroadcast(mediaScanIntent);

在您的代码下方添加这些行。 让它像

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 = System.IO.Path.GetFileName(image_url_format.LocalPath);
    string dest_path = System.IO.Path.Combine(dest_folder, file_name);
    using (var fileStream = new FileStream(dest_path, FileMode.Create, FileAccess.Write))
    {
        image_stream.CopyTo(fileStream);
    }
    var mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
    mediaScanIntent.SetData(Android.Net.Uri.FromFile(new Java.IO.File(dest_path)));
    //for old xamarin forms version
    Xamarin.Forms.Forms.Context.SendBroadcast(mediaScanIntent);
    //for new xamarin forms version
    //Android.App.Application.SendBroadcast(mediaScanIntent);
}
catch (Exception ex)
{
    DisplayAlert("Error", ex.ToString(), "OK");
    return;
}
    DisplayAlert("Alert", "Download completed!", "OK");  
}

【讨论】:

  • Xamarin.Forms.Forms.Context.SendBroadcast(mediaScanIntent); 这行不行:/
  • 我在我的生产应用程序中使用它,它适用于我的。我的 XamarinForms 版本 - 2.3
【解决方案2】:

您只需刷新已下载的文件。很有帮助。

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            File f = new File("file://"+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
            Uri contentUri = Uri.fromFile(f);
            mediaScanIntent.setData(contentUri);
            this.sendBroadcast(mediaScanIntent);
    }else{
            sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
    }

【讨论】:

  • 我必须实现sendBroadcast 方法,否则我会错过一些参考资料?
【解决方案3】:

确保在两个平台上都获得了所需的权限。

在你的课堂上使用:

 bool success = await DependencyService.Get<IPhotoLibrary>().SavePhotoAsync(data, folder, filename);

通用接口

  public interface IPhotoLibrary
    {
        Task<bool> SavePhotoAsync(byte[] data, string folder, string filename);
    }

在 Android 服务中

  public async Task<bool> SavePhotoAsync(byte[] data, string folder, string filename)
        {
            try
            {
                File picturesDirectory = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures);
                File folderDirectory = picturesDirectory;

                if (!string.IsNullOrEmpty(folder))
                {
                    folderDirectory = new File(picturesDirectory, folder);
                    folderDirectory.Mkdirs();
                }

                using (File bitmapFile = new File(folderDirectory, filename))
                {
                    bitmapFile.CreateNewFile();

                    using (FileOutputStream outputStream = new FileOutputStream(bitmapFile))
                    {
                        await outputStream.WriteAsync(data);
                    }

                    // Make sure it shows up in the Photos gallery promptly.
                    MediaScannerConnection.ScanFile(MainActivity.Instance,
                                                    new string[] { bitmapFile.Path },
                                                    new string[] { "image/png", "image/jpeg" }, null);
                }
            }
            catch (System.Exception ex)
            {
                return false;
            }

            return true;
        }

在 iOS 服务中:

public Task<bool> SavePhotoAsync(byte[] data, string folder, string filename)
        {
            NSData nsData = NSData.FromArray(data);
            UIImage image = new UIImage(nsData);
            TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();

            image.SaveToPhotosAlbum((UIImage img, NSError error) =>
            {
                taskCompletionSource.SetResult(error == null);
            });

            return taskCompletionSource.Task;
        }

您也可以参考这个来保存图像并将其反映在媒体中,无需为此使用skiasharp。 https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/bitmaps/saving

希望这可以解决您的问题。

【讨论】:

    【解决方案4】:

    参考Blu的回答,

    我将这个 Xamarin.Forms.Forms.Context.SendBroadcast(mediaScanIntent); 更改为 Android.App.Application.Context.SendBroadcast(mediaScanIntent); 并且一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-29
      • 1970-01-01
      • 1970-01-01
      • 2020-07-05
      • 2014-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多