I follow this blog to implement downloading image from URL and saving it to device.
My code:
IDownloader.cs
public interface IDownloader
{
void DownloadFile(string url, string folder);
event EventHandler<DownloadEventArgs> OnFileDownloaded;
}
public class DownloadEventArgs : EventArgs
{
public bool FileSaved = false;
public DownloadEventArgs(bool fileSaved)
{
FileSaved = fileSaved;
}
}
AndroidDownloader.cs
[assembly: Dependency(typeof(AndroidDownloader))]
namespace MyApp.Droid.Renderer
{
public class AndroidDownloader : IDownloader
{
public event EventHandler<DownloadEventArgs> OnFileDownloaded;
public void DownloadFile(string url, string folder)
{
string pathToNewFolder = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, folder);
Directory.CreateDirectory(pathToNewFolder);
try
{
WebClient webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
string pathToNewFile = Path.Combine(pathToNewFolder, Path.GetFileName(url));
webClient.DownloadFileAsync(new Uri(url), pathToNewFile);
}
catch (Exception ex)
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
}
}
private void Completed(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
}
else
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(true));
}
}
}
}
On my xaml.cs (I have added permission check on LIVE running)
IDownloader downloader = DependencyService.Get<IDownloader>();
private async void DownloadImage(object sender, EventArgs e)
{
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync<StoragePermission>();
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Plugin.Permissions.Abstractions.Permission.Storage))
{
await DisplayAlert("Storage permission", "Need storage permision to download images.", "OK");
}
status = await CrossPermissions.Current.RequestPermissionAsync<StoragePermission>();
}
if (status == PermissionStatus.Granted)
{
downloader.DownloadFile("http://www.dada-data.net/uploads/image/hausmann_abcd.jpg", "My App");
}
else if (status != PermissionStatus.Unknown)
{
//location denied
}
}
catch (Exception ex)
{
//Something went wrong
}
}
private async void OnFileDownloaded(object sender, DownloadEventArgs e)
{
await PopupNavigation.Instance.PopAsync();
if (e.FileSaved)
{
UserDialogs.Instance.Toast("The image saved Successfully.");
}
else
{
UserDialogs.Instance.Toast("Error while saving the image.");
}
}
IosDownloader.cs
[assembly: Dependency(typeof(IosDownloader))]
namespace MyApp.iOS.Renderer
{
public class IosDownloader : IDownloader
{
public event EventHandler<DownloadEventArgs> OnFileDownloaded;
public void DownloadFile(string url, string folder)
{
string pathToNewFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), folder);
Directory.CreateDirectory(pathToNewFolder);
try
{
WebClient webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
string pathToNewFile = Path.Combine(pathToNewFolder, Path.GetFileName(url));
webClient.DownloadFileAsync(new Uri(url), pathToNewFile);
}
catch (Exception ex)
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
}
}
private void Completed(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
}
else
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(true));
}
}
}
}
I am facing below issues:
- It is working on android 10 and not working on android 12. Should I add anything else for the proper working on android 12 or above?
- Not working on the ios platform. Added the permissions on info.plist.
UPDATE-20230205
I need to view the downloaded images on the device gallery and file manager applications.