Hello,
I've modified the interface with the specific implementation method, you could refer to the following complete example:
IDownloader.cs:
//Since you could save pictures directly to the album after downloading, it is no longer necessary to set up folders.
public interface IDownloader
{
void DownloadFile(string url);
event EventHandler<DownloadEventArgs> OnFileDownloaded;
}
public class DownloadEventArgs : EventArgs
{
public bool FileSaved = false;
public DownloadEventArgs(bool fileSaved)
{
FileSaved = fileSaved;
}
}
AndroidDownloader:
[assembly: Dependency(typeof(AndroidDownloader))]
namespace App4.Droid
{
public class AndroidDownloader : IDownloader
{
public event EventHandler<DownloadEventArgs> OnFileDownloaded;
public async void DownloadFile(string url)
{
try
{
WebClient webClient = new WebClient();
webClient.DownloadDataCompleted += Completed;
webClient.DownloadDataAsync(new Uri(url));
}
catch (System.Exception ex)
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
}
}
private void Completed(object sender, DownloadDataCompletedEventArgs e)
{
if (e.Error != null)
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
}
else
{
if (OnFileDownloaded != null)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
{
var contentValues = new ContentValues();
contentValues.Put(MediaStore.IMediaColumns.DisplayName, "test.png");
contentValues.Put(MediaStore.Files.IFileColumns.MimeType, "image/png");
contentValues.Put(MediaStore.IMediaColumns.RelativePath, "Pictures/relativePath");
try
{
var uri = MainActivity.Instance.ContentResolver.Insert(MediaStore.Images.Media.ExternalContentUri, contentValues);
var output = MainActivity.Instance.ContentResolver.OpenOutputStream(uri);
output.Write(e.Result, 0, e.Result.Length);
output.Flush();
output.Close();
}
catch (System.Exception ex)
{
Console.Write(ex.ToString());
}
contentValues.Put(MediaStore.IMediaColumns.IsPending, 1);
}
OnFileDownloaded.Invoke(this, new DownloadEventArgs(true));
}
}
}
}
}
Add the following permissions into AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Add the following code into MainActivity.cs:
public static MainActivity Instance { get; private set; }
// Then, make the assignment in the OnCreate method. global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
Instance = this;
IosDownloader:
[assembly: Dependency(typeof(IosDownloader))]
namespace App4.iOS
{
public class IosDownloader : IDownloader
{
public event EventHandler<DownloadEventArgs> OnFileDownloaded;
private string pathToNewFile;
public void DownloadFile(string url)
{
try
{
WebClient webClient = new WebClient();
webClient.DownloadDataCompleted += Completed;
webClient.DownloadDataAsync(new Uri(url));
}
catch (System.Exception ex)
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
}
}
private void Completed(object sender, DownloadDataCompletedEventArgs e)
{
if (e.Error != null)
{
if (OnFileDownloaded != null)
OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
}
else
{
if (OnFileDownloaded != null)
{
var imageData = NSData.FromArray(e.Result);
var image = UIImage.LoadFromData(imageData);
image.SaveToPhotosAlbum((img, error) =>
{
});
OnFileDownloaded.Invoke(this, new DownloadEventArgs(true));
}
}
}
}
}
Add the following permission into info.plist
:
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Please allow access to save photo in your photo library</string>
Best Regards,
Alec Liu.
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our [documentation][1] to enable e-mail notifications if you want to receive the related email notification for this thread.