Issue
I am working on Xamarin Forms (with iOS and Android). What I want to do is to allow users to download image from an url by using DependencyService. I tried run in IOS emulator and the image did save into the emulator but does not show up in the gallery. Appreciate help in that and following is my code:
In 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");
}
In 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);
}
}
In 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);
}
}
Solution
If you Want to save image into Gallery, please follow the code below.
Firstly, create Create the IMediaService Interface in PCL.
public interface IMediaService
{
void SaveImageFromByte(byte[] imageByte,string filename);
}
Then implement this interface in Platform-specific Xamarin.Android Project
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)
{
}
}
}
implement this interface in Platform-specific Xamarin.iOS Project
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());
}
});
}
}
For accessing the CurrentContext Install the NuGet Package (Plugin.CurrentActivity) from NuGet Package Manager, also check for the external storage permission.
Answered By – Cherry Bu – MSFT