Xamarin Forms将来自URL的图片保存到设备相册

3

我正在使用Xamarin Forms(包括iOS和Android)。我的目标是通过使用DependencyService允许用户从URL下载图像。我尝试在iOS模拟器上运行,图像确实保存到模拟器中,但在相册中没有显示出来。

非常感谢您的帮助,以下是我的代码:

在ViewModel中:

public void DownloadImage()
{
    IFileService fileSvc = DependencyService.Get<IFileService>();

    WebClient wc = new WebClient();
    byte[] bytes = wc.DownloadData(ImgUrl);
    Stream stream = new MemoryStream(bytes);

    fileSvc.SavePicture(DateTime.Now.ToString(), stream, "temp");
}

在Xamarin.iOS中

public void SavePicture(string name, Stream data, string location = "temp")
{
    var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
    string imageFilename = Path.Combine(documentsPath, "Images", location);
    Directory.CreateDirectory(imageFilename);

    string filePath = Path.Combine(documentsPath, name);

    byte[] bArray = new byte[data.Length];
    using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
    {
        using (data)
        {
            data.Read(bArray, 0, (int)data.Length);
        }
        int length = bArray.Length;
        fs.Write(bArray, 0, length);
    }
}

在Xamarin.Droid中。
public void SavePicture(string name, Stream data, string location = "temp")
{
    var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
    documentsPath = Path.Combine(documentsPath, "Images", location);
    Directory.CreateDirectory(documentsPath);

    string filePath = Path.Combine(documentsPath, name);

    byte[] bArray = new byte[data.Length];
    using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
    {
        using (data)
        {
            data.Read(bArray, 0, (int)data.Length);
        }
        int length = bArray.Length;
        fs.Write(bArray, 0, length);
    }
}
1个回答

3
如果您想将图像保存到相册中,请按照以下代码操作。
首先,在PCL中创建IMediaService接口。
public interface IMediaService
{
    void SaveImageFromByte(byte[] imageByte,string filename);
}

然后在特定于平台的 Xamarin.Android 项目中实现此接口。

public  class MediaService : IMediaService
{
    Context CurrentContext => CrossCurrentActivity.Current.Activity;
    public void SaveImageFromByte(byte[] imageByte, string filename)
    {
        try
        {
            Java.IO.File storagePath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures);
            string path = System.IO.Path.Combine(storagePath.ToString(), filename);
            System.IO.File.WriteAllBytes(path, imageByte);
            var mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
            mediaScanIntent.SetData(Android.Net.Uri.FromFile(new Java.IO.File(path)));
            CurrentContext.SendBroadcast(mediaScanIntent);
        }
        catch (Exception ex)
        {

        }
    }
}

在平台特定的Xamarin.iOS项目中实现此接口。

public class MediaService : IMediaService
{
    public void SaveImageFromByte(byte[] imageByte,string fileName)
    {
        var imageData = new UIImage(NSData.FromArray(imageByte));
        imageData.SaveToPhotosAlbum((image, error) =>
        {
            //you can retrieve the saved UI Image as well if needed using  
            //var i = image as UIImage;  
            if (error != null)
            {
                Console.WriteLine(error.ToString());
            }
        });
    }
}

要访问 CurrentContext,需从 NuGet Package Manager 安装 Plugin.CurrentActivity 包,并检查是否具有外部存储权限


嗨,Cherry,感谢你的回复。当我尝试在iOS模拟器上运行时,一旦调试器触及 imageData.SaveToPhotosAlbum((image, error) =>应用程序就会强制退出而不生成任何错误。你有什么想法这个问题可能是什么? - LongHao Li
在iOS上,如果您想要将照片写入相册,我们需要在info.plist中添加隐私权限。在iOS 11上添加NSPhotoLibraryAddUsageDescription,在iOS 10上添加NSPhotoLibraryUsageDescription. 有一些关于iOS安全和隐私功能新的iOS 10隐私权限设置的文章。 - Cherry Bu - MSFT
嘿@CherryBu,非常感谢你的帮助!在info.plist中添加NSPhotoLibraryAddUsageDescription后,它终于起作用了! - LongHao Li

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接