Search code examples
imagexamarinsavegallery

Xamarin - download image to gallery


I've found this: How to download image and save it in local storage using Xamarin-Forms.?

This partially adresses my problem except for two points:

  • I'd need to download the image to the gallery, not the apps'path
  • I need this to work for both, android and IOs. This seems to only work for Android.

Basically i know the URL of a file online, and need to download it to the gallery. It would be great if ic ould "save" it from inside the application, instead of "downloading". It would be nice if the client cant figure out the URL of the images he wants to save.

EDIT:

Now I am using FFImageLoading.. here is my current (not working) code..

 private async void SaveToGallery_Clicked(object sender, EventArgs e)
    {
        var img = await MyImage.GetImageAsJpgAsync(quality: 100);

        string fileName = uri.ToString().Split('/').Last();

        DependencyService.Get<IMediaService>().SaveImageFromByte(img, fileName);
    }

Android MediaService.cs

[assembly: Xamarin.Forms.Dependency(typeof(MediaService))]
namespace GalShare.Droid
{
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)
        {

        }
    }
}
}

Android MainActivity.cs:

namespace GalShare.Droid
{
[Activity(Label = "GalShare", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    public int STORAGE_PERMISSION_CODE = 101;
    protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;
        FFImageLoading.Forms.Platform.CachedImageRenderer.Init(enableFastRenderer: false);

        base.OnCreate(savedInstanceState);

        Forms.SetFlags("CollectionView_Experimental");

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        CachedImageRenderer.InitImageViewHandler();

        string fileName = "galleries.db3";
        string folderPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
        string completePath = Path.Combine(folderPath, fileName);

        checkPermission("android.permission.write_external_storage", STORAGE_PERMISSION_CODE);

        LoadApplication(new App(completePath));
    }


    public void checkPermission(String permission, int requestCode)
    {
        var thisActivity = Android.App.Application.Context as Activity;
        // Checking if permission is not granted 
        if (ContextCompat.CheckSelfPermission(
                Android.App.Application.Context,
                permission)
            == Android.Content.PM.Permission.Denied)
        {
            RequestPermissions(new String[] { Manifest.Permission.WriteExternalStorage }, requestCode);

        }
        else
        {

        }

    }

}
}

Solution

  • Initialilzing CrossCurrentActivity in the MainActivity.cs solved the problem:

    CrossCurrentActivity.Current.Init(this, bundle);