MultipleMediaPickerSample icon indicating copy to clipboard operation
MultipleMediaPickerSample copied to clipboard

Android Project Not Working

Open crashnnburn opened this issue 5 years ago • 17 comments

Hello, I just wanted to let you know that your project works great for IOS. But does not work as intended for Android. I am only able to select images from gallery but when finishing selection no photos are displayed and nothing is returned. I'm using the sample here and have tried it on the android emulators and a physical device. It seems to fail in the PickMediaAsync section. Function doesn't enter OnActivityResult to continue execution. Hopefully it's a minor issue.

crashnnburn avatar May 10 '19 18:05 crashnnburn

I'm not the author of this, but I ran into the same issue and it turns out it was a bit of an oopsie on my part. For this to work on android you need to modify your MainActvity.cs to call this function. If you look at the MainActivity.cs class in the android project in this solution you will see that he overrides OnActivityResult and calls it using the shared instance declared in the IMultiMediaPickerService.

andrewndavis avatar Jun 03 '19 23:06 andrewndavis

I follow this all the way through the OnActivityResult. For some reason it never triggers the OnMediaPickedCompleted. It runs this command OnMediaPickedCompleted?.Invoke(this, mediaPicked); but I don't seem to be able to subscribe to it. any help would be appreciated. This looks like a fantastic piece of code.

linda-dge avatar Jun 20 '19 07:06 linda-dge

From what I can tell this is what is going on. I could very well be off but stepping through everything this is what I have come too.

One note before I start. I did change how I am calling the Media Picker and I am using: var multiMediaPicker = DependencyService.Get<IMultiMediaPickerService>(); To create my dependency and then calling the PickPhotosAsync like this multiMediaPicker.PickPhotosAsync(); After that I am calling the Event Handler like this. multiMediaPicker.OnMediaPicked += new EventHandler<MediaFile>((o, file) => { ViewModel.Media.Add(file); if (ViewModel.Media.Any()) { //do some stuff here. } });

My Conclusion without any answers :(.

On Android, after I am able to select multiple images the code starts looping through the OnActivityResult. Everything is fine I have a list of images from the device but when it hits OnMediaPicked?.Invoke(this, media); On MediaPicker is null.

I have been Googling everything I can think of to try to understand why this is not instantiated when the event listener is called above. multiMediaPicker.OnMediaPicked += ... I don't know if this helps anyone think of something but this is making me crazy.

kurtlmartin avatar Jun 27 '19 21:06 kurtlmartin

I'm also facing the same issue.Any update on this? @kurtlmartin

Deba22 avatar Jul 10 '19 08:07 Deba22

Can you post the code from your MainActivity.cs from your Android project?

andrewndavis avatar Jul 10 '19 15:07 andrewndavis

@andrewndavis I keep rereading your comment above and don't understand what you said you did. Below is my OnActivityResult

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data);

MultiMediaPickerService.SharedInstance.OnActivityResult(requestCode, resultCode, data);

AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data); }

I am not passing the MultiMediaPickerService through my load application LoadApplication(new App()). So I am not sure if that is my problem or not. I did not do this due to then having to pass it around everywhere in my application.

kurtlmartin avatar Jul 10 '19 21:07 kurtlmartin

I got it working in Android.This is what I did. MainActivity.cs

	protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            byte[] array = null;
            base.OnActivityResult(requestCode, resultCode, data);
            if (resultCode == Result.Ok)
            {
                if(requestCode== 9793)
                {
                    MultiMediaPickerService multiMediaPickerService=new MultiMediaPickerService();
                    multiMediaPickerService.OnMultipleGalleryImageResult(requestCode, resultCode,data);
                }
            }
        }

MultiMediaPickerService.cs

 public void OnMultipleGalleryImageResult(int requestCode, Result resultCode, Intent data)
        {
            ObservableCollection<MediaFile> mediaPicked = null;

            if (requestCode == MultiPickerResultCode)
            {
                if (resultCode == Result.Ok)
                {
                    mediaPicked = new ObservableCollection<MediaFile>();
                    if (data != null)
                    {
                        ClipData clipData = data.ClipData;
                        if (clipData != null)
                        {
                            for (int i = 0; i < clipData.ItemCount; i++)
                            {
                                ClipData.Item item = clipData.GetItemAt(i);
                                Android.Net.Uri uri = item.Uri;
                                var media = CreateMediaFileFromUri(uri);
                                if (media != null)
                                {
                                    mediaPicked.Add(media);
                                    //OnMediaPicked?.Invoke(this, media);
                                }

                            }
                        }
                        else
                        {
                            Android.Net.Uri uri = data.Data;
                            var media = CreateMediaFileFromUri(uri);
                            if (media != null)
                            {
                                mediaPicked.Add(media);
                               // OnMediaPicked?.Invoke(this, media);
                            }
                        }

                       // OnMediaPickedCompleted?.Invoke(this, mediaPicked);
                        MessagingCenter.Send<Object, Object>(this, "Multiplesel",mediaPicked.ToList());
                    }
                }

                mediaPickedTcs?.TrySetResult(mediaPicked);

            }
        }

Then I had to use Messaging center to display the selected images in the flowlistview.

Deba22 avatar Jul 11 '19 06:07 Deba22

I got it working in Android.This is what I did. MainActivity.cs

	protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            byte[] array = null;
            base.OnActivityResult(requestCode, resultCode, data);
            if (resultCode == Result.Ok)
            {
                if(requestCode== 9793)
                {
                    MultiMediaPickerService multiMediaPickerService=new MultiMediaPickerService();
                    multiMediaPickerService.OnMultipleGalleryImageResult(requestCode, resultCode,data);
                }
            }
        }

MultiMediaPickerService.cs

 public void OnMultipleGalleryImageResult(int requestCode, Result resultCode, Intent data)
        {
            ObservableCollection<MediaFile> mediaPicked = null;

            if (requestCode == MultiPickerResultCode)
            {
                if (resultCode == Result.Ok)
                {
                    mediaPicked = new ObservableCollection<MediaFile>();
                    if (data != null)
                    {
                        ClipData clipData = data.ClipData;
                        if (clipData != null)
                        {
                            for (int i = 0; i < clipData.ItemCount; i++)
                            {
                                ClipData.Item item = clipData.GetItemAt(i);
                                Android.Net.Uri uri = item.Uri;
                                var media = CreateMediaFileFromUri(uri);
                                if (media != null)
                                {
                                    mediaPicked.Add(media);
                                    //OnMediaPicked?.Invoke(this, media);
                                }

                            }
                        }
                        else
                        {
                            Android.Net.Uri uri = data.Data;
                            var media = CreateMediaFileFromUri(uri);
                            if (media != null)
                            {
                                mediaPicked.Add(media);
                               // OnMediaPicked?.Invoke(this, media);
                            }
                        }

                       // OnMediaPickedCompleted?.Invoke(this, mediaPicked);
                        MessagingCenter.Send<Object, Object>(this, "Multiplesel",mediaPicked.ToList());
                    }
                }

                mediaPickedTcs?.TrySetResult(mediaPicked);

            }
        }

Then I had to use Messaging center to display the selected images in the flowlistview.

Im getting

"MultiMediaPickerService.MultiMediaPickerService()' is inaccessible due to its protection level Flipper.Android

Why is that? Also how do you instantiate the "MainViewModel()" ?? what do I have to put inside the brackets?

haxor211 avatar Jul 11 '19 12:07 haxor211

  1. Check if your MultiMediaPickerService class is public.It should be public and not private.
  2. I am not using ViewModel concept.I'm doing everything in code behind.

Deba22 avatar Jul 12 '19 04:07 Deba22

  1. Check if your MultiMediaPickerService class is public.It should be public and not private.
  2. I am not using ViewModel concept.I'm doing everything in code behind.

Could you paste your code on how to use the above??

haxor211 avatar Jul 12 '19 06:07 haxor211

Here is my code UploadPicture.xaml.cs

 private async void Gallery_Tapped(object sender, EventArgs e)
        {
            try
            {
               
                MessagingCenter.Unsubscribe<Object, Object>(this, "Multiplesel");
                MessagingCenter.Subscribe<Object, Object>(this, "Multiplesel", (sender1, arg) =>
                {
                //manipulate the args
                });

                await DependencyService.Get<IMultiMediaPickerService>().PickPhotosAsync();
         }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

IMultiMediaPickerService.cs

 public interface IMultiMediaPickerService
    {
        Task<IList<MediaFile>> PickPhotosAsync();
        void Clean();
    }

MultiMediaPickerService.cs

[assembly: Dependency(typeof(MultiMediaPickerService))]
namespace ConstellationInHouse.Droid
{
   
   public class MultiMediaPickerService:IMultiMediaPickerService
    {
     
        int MultiPickerResultCode = 9793;
        const string TemporalDirectoryName = "TmpMedia";

       
        TaskCompletionSource<IList<MediaFile>> mediaPickedTcs;

        public void OnMultipleGalleryImageResult(int requestCode, Result resultCode, Intent data)
        {
            ObservableCollection<MediaFile> mediaPicked = null;

            if (requestCode == MultiPickerResultCode)
            {
                if (resultCode == Result.Ok)
                {
                    mediaPicked = new ObservableCollection<MediaFile>();
                    if (data != null)
                    {
                        ClipData clipData = data.ClipData;
                        if (clipData != null)
                        {
                            for (int i = 0; i < clipData.ItemCount; i++)
                            {
                                ClipData.Item item = clipData.GetItemAt(i);
                                Android.Net.Uri uri = item.Uri;
                                var media = CreateMediaFileFromUri(uri);
                                if (media != null)
                                {
                                    mediaPicked.Add(media);
                                    //OnMediaPicked?.Invoke(this, media);
                                }

                            }
                        }
                        else
                        {
                            Android.Net.Uri uri = data.Data;
                            var media = CreateMediaFileFromUri(uri);
                            if (media != null)
                            {
                                mediaPicked.Add(media);
                               // OnMediaPicked?.Invoke(this, media);
                            }
                        }

                       // OnMediaPickedCompleted?.Invoke(this, mediaPicked);
                        MessagingCenter.Send<Object, Object>(this, "Multiplesel",mediaPicked.ToList());
                    }
                }

                mediaPickedTcs?.TrySetResult(mediaPicked);

            }
        }

        MediaFile CreateMediaFileFromUri(Android.Net.Uri uri)
        {
            MediaFile mediaFile = null;
            var type = CrossCurrentActivity.Current.Activity.ContentResolver.GetType(uri);

            var path = GetRealPathFromURI(uri);
            if (path != null)
            {
                string fullPath = string.Empty;
                string thumbnailImagePath = string.Empty;
                var fileName = System.IO.Path.GetFileNameWithoutExtension(path);
                var ext = System.IO.Path.GetExtension(path) ?? string.Empty;
                MediaFileType mediaFileType = MediaFileType.Image;
                byte[] UploadImage=null;
                if (type.StartsWith(Enum.GetName(typeof(MediaFileType), MediaFileType.Image), StringComparison.CurrentCultureIgnoreCase))
                {
                    var fullImage = ImageHelpers.RotateImage(path, 1);
                    var thumbImage = ImageHelpers.RotateImage(path, 0.25f);


                    fullPath = FileHelper.GetOutputPath(MediaFileType.Image, TemporalDirectoryName, $"{fileName}{ext}");
                    File.WriteAllBytes(fullPath, fullImage);
                  UploadImage= File.ReadAllBytes(fullPath);

                    thumbnailImagePath = FileHelper.GetOutputPath(MediaFileType.Image, TemporalDirectoryName, $"{fileName}-THUMBNAIL{ext}");
                    File.WriteAllBytes(thumbnailImagePath, thumbImage);

                }
                else if (type.StartsWith(Enum.GetName(typeof(MediaFileType), MediaFileType.Video), StringComparison.CurrentCultureIgnoreCase))
                {
                    fullPath = path;
                    var bitmap = ThumbnailUtils.CreateVideoThumbnail(path, ThumbnailKind.MiniKind);

                    thumbnailImagePath = FileHelper.GetOutputPath(MediaFileType.Image, TemporalDirectoryName, $"{fileName}-THUMBNAIL{ext}");
                    var stream = new FileStream(thumbnailImagePath, FileMode.Create);
                    bitmap?.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
                    stream.Close();

                    mediaFileType = MediaFileType.Video;
                }

                if (!string.IsNullOrEmpty(fullPath) && !string.IsNullOrEmpty(thumbnailImagePath))
                {
                    mediaFile = new MediaFile()
                    {
                        Path = fullPath,
                        Type = mediaFileType,
                        PreviewPath = thumbnailImagePath,
                        ImageFile = UploadImage
                    };
                }

            }

            return mediaFile;
        }

        public static string GetRealPathFromURI(Android.Net.Uri contentURI)
        {
            ICursor cursor = null;
            try
            {

                string mediaPath = string.Empty;
                cursor = CrossCurrentActivity.Current.Activity.ContentResolver.Query(contentURI, null, null, null, null);
                cursor.MoveToFirst();
                int idx = cursor.GetColumnIndex(MediaStore.MediaColumns.Data);

                if (idx != -1)
                {
                    var type = CrossCurrentActivity.Current.Activity.ContentResolver.GetType(contentURI);

                    int pIdx = cursor.GetColumnIndex(MediaStore.MediaColumns.Id);

                    var mData = cursor.GetString(idx);

                    mediaPath = mData;

                }
                else
                {

                    var docID = DocumentsContract.GetDocumentId(contentURI);
                    var doc = docID.Split(':');
                    var id = doc[1];
                    var whereSelect = MediaStore.Images.ImageColumns.Id + "=?";
                    var dataConst = MediaStore.Images.ImageColumns.Data;
                    var projections = new string[] { dataConst };
                    var internalUri = MediaStore.Images.Media.InternalContentUri;
                    var externalUri = MediaStore.Images.Media.ExternalContentUri;
                    switch (doc[0])
                    {
                        case "video":
                            internalUri = MediaStore.Video.Media.InternalContentUri;
                            externalUri = MediaStore.Video.Media.ExternalContentUri;
                            whereSelect = MediaStore.Video.VideoColumns.Id + "=?";
                            dataConst = MediaStore.Video.VideoColumns.Data;
                            break;
                        case "image":
                            whereSelect = MediaStore.Video.VideoColumns.Id + "=?";
                            projections = new string[] { MediaStore.Video.VideoColumns.Data };
                            break;
                    }

                    projections = new string[] { dataConst };
                    cursor = CrossCurrentActivity.Current.Activity.ContentResolver.Query(internalUri, projections, whereSelect, new string[] { id }, null);
                    if (cursor.Count == 0)
                    {
                        cursor = CrossCurrentActivity.Current.Activity.ContentResolver.Query(externalUri, projections, whereSelect, new string[] { id }, null);
                    }
                    var colDatax = cursor.GetColumnIndexOrThrow(dataConst);
                    cursor.MoveToFirst();

                    mediaPath = cursor.GetString(colDatax);
                }
                return mediaPath;
            }
            catch (Exception)
            {
                Toast.MakeText(CrossCurrentActivity.Current.Activity, "Unable to get path", ToastLength.Long).Show();

            }
            finally
            {
                if (cursor != null)
                {
                    cursor.Close();
                    cursor.Dispose();
                }
            }

            return null;

        }

        public void Clean()//not used
        {

            var documentsDirectory = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), TemporalDirectoryName);

            if (Directory.Exists(documentsDirectory))
            {
                Directory.Delete(documentsDirectory);
            }
        }

        public async Task<IList<MediaFile>> PickPhotosAsync()
        {
            return await PickMediaAsync("image/*", "Select Images", MultiPickerResultCode);
        }

     

        async Task<IList<MediaFile>> PickMediaAsync(string type, string title, int resultCode)
        {

            mediaPickedTcs = new TaskCompletionSource<IList<MediaFile>>();

            var imageIntent = new Intent(Intent.ActionPick);
            imageIntent.SetType(type);
            imageIntent.PutExtra(Intent.ExtraAllowMultiple, true);
            var res = CrossCurrentActivity.Current.Activity;
            res.StartActivityForResult(Intent.CreateChooser(imageIntent, title), resultCode);

            return await mediaPickedTcs.Task;

        }
    }
}

MainActivity.cs

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            byte[] array = null;
            base.OnActivityResult(requestCode, resultCode, data);
            if (resultCode == Result.Ok)
            {
                if(requestCode== 9793)
                {
                    MultiMediaPickerService multiMediaPickerService=new MultiMediaPickerService();
                    multiMediaPickerService.OnMultipleGalleryImageResult(requestCode, resultCode,data);
                }
            }
        }

Let me know if it works!

Deba22 avatar Jul 12 '19 12:07 Deba22

I have tried your code and I cannot seem to get it to refresh the grid of images selected. I'm with @kurtlmartin . I do not want to carry this around and want to instantiate on the page it is utilized in.

I have this in the constructor

public MultiMediaPickerService() { this.OnMediaPickedCompleted += MultiMediaPickerService_OnMediaPickedCompleted; }

    void MultiMediaPickerService_OnMediaPickedCompleted(object sender, IList<MediaFile> e)
    {
        MessagingCenter.Send<App, IList<MediaFile>>((App)Xamarin.Forms.Application.Current, "ImagesSelected", e);
    }

Then in the .xaml.cs

MessagingCenter.Subscribe<App, IList<MediaFile>>((App)Xamarin.Forms.Application.Current, "ImagesSelected", (msgSender, arg) => { MediaViewModel mvm = (MediaViewModel)BindingContext; mvm.Media.Clear(); foreach (MediaFile mf in arg) { Device.BeginInvokeOnMainThread(() => { mvm.Media.Add(mf); }); } FlvItems.ItemsSource = mvm.Media; });

I can see the mediafiles and all of their attributes. It just won't refresh the FlowListView

linda-dge avatar Jul 28 '19 21:07 linda-dge

Solved my own problem.

This line should say FlowItemsSource and not ItemSource

FlvItems.FlowItemsSource = mvm.Media;

linda-dge avatar Jul 28 '19 21:07 linda-dge

Here is my code UploadPicture.xaml.cs

 private async void Gallery_Tapped(object sender, EventArgs e)
        {
            try
            {
               
                MessagingCenter.Unsubscribe<Object, Object>(this, "Multiplesel");
                MessagingCenter.Subscribe<Object, Object>(this, "Multiplesel", (sender1, arg) =>
                {
                //manipulate the args
                });

                await DependencyService.Get<IMultiMediaPickerService>().PickPhotosAsync();
         }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

IMultiMediaPickerService.cs

 public interface IMultiMediaPickerService
    {
        Task<IList<MediaFile>> PickPhotosAsync();
        void Clean();
    }

MultiMediaPickerService.cs

[assembly: Dependency(typeof(MultiMediaPickerService))]
namespace ConstellationInHouse.Droid
{
   
   public class MultiMediaPickerService:IMultiMediaPickerService
    {
     
        int MultiPickerResultCode = 9793;
        const string TemporalDirectoryName = "TmpMedia";

       
        TaskCompletionSource<IList<MediaFile>> mediaPickedTcs;

        public void OnMultipleGalleryImageResult(int requestCode, Result resultCode, Intent data)
        {
            ObservableCollection<MediaFile> mediaPicked = null;

            if (requestCode == MultiPickerResultCode)
            {
                if (resultCode == Result.Ok)
                {
                    mediaPicked = new ObservableCollection<MediaFile>();
                    if (data != null)
                    {
                        ClipData clipData = data.ClipData;
                        if (clipData != null)
                        {
                            for (int i = 0; i < clipData.ItemCount; i++)
                            {
                                ClipData.Item item = clipData.GetItemAt(i);
                                Android.Net.Uri uri = item.Uri;
                                var media = CreateMediaFileFromUri(uri);
                                if (media != null)
                                {
                                    mediaPicked.Add(media);
                                    //OnMediaPicked?.Invoke(this, media);
                                }

                            }
                        }
                        else
                        {
                            Android.Net.Uri uri = data.Data;
                            var media = CreateMediaFileFromUri(uri);
                            if (media != null)
                            {
                                mediaPicked.Add(media);
                               // OnMediaPicked?.Invoke(this, media);
                            }
                        }

                       // OnMediaPickedCompleted?.Invoke(this, mediaPicked);
                        MessagingCenter.Send<Object, Object>(this, "Multiplesel",mediaPicked.ToList());
                    }
                }

                mediaPickedTcs?.TrySetResult(mediaPicked);

            }
        }

        MediaFile CreateMediaFileFromUri(Android.Net.Uri uri)
        {
            MediaFile mediaFile = null;
            var type = CrossCurrentActivity.Current.Activity.ContentResolver.GetType(uri);

            var path = GetRealPathFromURI(uri);
            if (path != null)
            {
                string fullPath = string.Empty;
                string thumbnailImagePath = string.Empty;
                var fileName = System.IO.Path.GetFileNameWithoutExtension(path);
                var ext = System.IO.Path.GetExtension(path) ?? string.Empty;
                MediaFileType mediaFileType = MediaFileType.Image;
                byte[] UploadImage=null;
                if (type.StartsWith(Enum.GetName(typeof(MediaFileType), MediaFileType.Image), StringComparison.CurrentCultureIgnoreCase))
                {
                    var fullImage = ImageHelpers.RotateImage(path, 1);
                    var thumbImage = ImageHelpers.RotateImage(path, 0.25f);


                    fullPath = FileHelper.GetOutputPath(MediaFileType.Image, TemporalDirectoryName, $"{fileName}{ext}");
                    File.WriteAllBytes(fullPath, fullImage);
                  UploadImage= File.ReadAllBytes(fullPath);

                    thumbnailImagePath = FileHelper.GetOutputPath(MediaFileType.Image, TemporalDirectoryName, $"{fileName}-THUMBNAIL{ext}");
                    File.WriteAllBytes(thumbnailImagePath, thumbImage);

                }
                else if (type.StartsWith(Enum.GetName(typeof(MediaFileType), MediaFileType.Video), StringComparison.CurrentCultureIgnoreCase))
                {
                    fullPath = path;
                    var bitmap = ThumbnailUtils.CreateVideoThumbnail(path, ThumbnailKind.MiniKind);

                    thumbnailImagePath = FileHelper.GetOutputPath(MediaFileType.Image, TemporalDirectoryName, $"{fileName}-THUMBNAIL{ext}");
                    var stream = new FileStream(thumbnailImagePath, FileMode.Create);
                    bitmap?.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
                    stream.Close();

                    mediaFileType = MediaFileType.Video;
                }

                if (!string.IsNullOrEmpty(fullPath) && !string.IsNullOrEmpty(thumbnailImagePath))
                {
                    mediaFile = new MediaFile()
                    {
                        Path = fullPath,
                        Type = mediaFileType,
                        PreviewPath = thumbnailImagePath,
                        ImageFile = UploadImage
                    };
                }

            }

            return mediaFile;
        }

        public static string GetRealPathFromURI(Android.Net.Uri contentURI)
        {
            ICursor cursor = null;
            try
            {

                string mediaPath = string.Empty;
                cursor = CrossCurrentActivity.Current.Activity.ContentResolver.Query(contentURI, null, null, null, null);
                cursor.MoveToFirst();
                int idx = cursor.GetColumnIndex(MediaStore.MediaColumns.Data);

                if (idx != -1)
                {
                    var type = CrossCurrentActivity.Current.Activity.ContentResolver.GetType(contentURI);

                    int pIdx = cursor.GetColumnIndex(MediaStore.MediaColumns.Id);

                    var mData = cursor.GetString(idx);

                    mediaPath = mData;

                }
                else
                {

                    var docID = DocumentsContract.GetDocumentId(contentURI);
                    var doc = docID.Split(':');
                    var id = doc[1];
                    var whereSelect = MediaStore.Images.ImageColumns.Id + "=?";
                    var dataConst = MediaStore.Images.ImageColumns.Data;
                    var projections = new string[] { dataConst };
                    var internalUri = MediaStore.Images.Media.InternalContentUri;
                    var externalUri = MediaStore.Images.Media.ExternalContentUri;
                    switch (doc[0])
                    {
                        case "video":
                            internalUri = MediaStore.Video.Media.InternalContentUri;
                            externalUri = MediaStore.Video.Media.ExternalContentUri;
                            whereSelect = MediaStore.Video.VideoColumns.Id + "=?";
                            dataConst = MediaStore.Video.VideoColumns.Data;
                            break;
                        case "image":
                            whereSelect = MediaStore.Video.VideoColumns.Id + "=?";
                            projections = new string[] { MediaStore.Video.VideoColumns.Data };
                            break;
                    }

                    projections = new string[] { dataConst };
                    cursor = CrossCurrentActivity.Current.Activity.ContentResolver.Query(internalUri, projections, whereSelect, new string[] { id }, null);
                    if (cursor.Count == 0)
                    {
                        cursor = CrossCurrentActivity.Current.Activity.ContentResolver.Query(externalUri, projections, whereSelect, new string[] { id }, null);
                    }
                    var colDatax = cursor.GetColumnIndexOrThrow(dataConst);
                    cursor.MoveToFirst();

                    mediaPath = cursor.GetString(colDatax);
                }
                return mediaPath;
            }
            catch (Exception)
            {
                Toast.MakeText(CrossCurrentActivity.Current.Activity, "Unable to get path", ToastLength.Long).Show();

            }
            finally
            {
                if (cursor != null)
                {
                    cursor.Close();
                    cursor.Dispose();
                }
            }

            return null;

        }

        public void Clean()//not used
        {

            var documentsDirectory = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), TemporalDirectoryName);

            if (Directory.Exists(documentsDirectory))
            {
                Directory.Delete(documentsDirectory);
            }
        }

        public async Task<IList<MediaFile>> PickPhotosAsync()
        {
            return await PickMediaAsync("image/*", "Select Images", MultiPickerResultCode);
        }

     

        async Task<IList<MediaFile>> PickMediaAsync(string type, string title, int resultCode)
        {

            mediaPickedTcs = new TaskCompletionSource<IList<MediaFile>>();

            var imageIntent = new Intent(Intent.ActionPick);
            imageIntent.SetType(type);
            imageIntent.PutExtra(Intent.ExtraAllowMultiple, true);
            var res = CrossCurrentActivity.Current.Activity;
            res.StartActivityForResult(Intent.CreateChooser(imageIntent, title), resultCode);

            return await mediaPickedTcs.Task;

        }
    }
}

MainActivity.cs

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            byte[] array = null;
            base.OnActivityResult(requestCode, resultCode, data);
            if (resultCode == Result.Ok)
            {
                if(requestCode== 9793)
                {
                    MultiMediaPickerService multiMediaPickerService=new MultiMediaPickerService();
                    multiMediaPickerService.OnMultipleGalleryImageResult(requestCode, resultCode,data);
                }
            }
        }

Let me know if it works!

  1. its working great bro but there is one thing Im getting these errors:

08-06 13:08:53.639 W/ExifInterface(22980): Skip the tag entry since tag number is not defined: 2 08-06 13:08:53.639 W/ExifInterface(22980): Stop reading file since a wrong offset may cause an infinite loop: 0 08-06 13:08:53.639 I/chatty (22980): uid=10689(com.companyname.Flipper) identical 2 lines 08-06 13:08:53.639 W/ExifInterface(22980): Stop reading file since a wrong offset may cause an infinite loop: 0 08-06 13:08:53.712 I/anyname.Flippe(22980): Explicit concurrent copying GC freed 179(32KB) AllocSpace objects, 0(0B) LOS objects, 71% free, 2MB/8MB, paused 61us total 13.127ms 08-06 13:08:53.916 W/ExifInterface(22980): Skip the tag entry since tag number is not defined: 2 08-06 13:08:53.916 W/ExifInterface(22980): Stop reading file since a wrong offset may cause an infinite loop: 0 08-06 13:08:53.917 I/chatty (22980): uid=10689(com.companyname.Flipper) identical 2 lines 08-06 13:08:53.917 W/ExifInterface(22980): Stop reading file since a wrong offset may cause an infinite loop: 0 08-06 13:08:54.502 I/anyname.Flippe(22980): Explicit concurrent copying GC freed 852(46KB) AllocSpace objects, 0(0B) LOS objects, 71% free, 2MB/8MB, paused 64us total 13.846ms 08-06 13:08:54.504 W/System (22980): A resource failed to call close. 08-06 13:08:54.505 W/System (22980): A resource failed to call close.

Where the hell is that loop and why is that happening??

  1. Its working great for my if I just put it in code behind the page, but if I do it in the viewmodel I can open and select the photos, but they never arrive at messaging center when from viewmodel - how can I fix that??

haxor211 avatar Aug 06 '19 11:08 haxor211

Thank goodness I found this issue, it wasn't working for me either and I had no clue as to why it wasn't working. But the fix is mainly to use MessagingCenter. Unsubscribe and re-subscribe from your view (or wherever you intend to receive the image(s) selected), and in the MultiMediaPickerService class send the image(s) selected via MessagingCenter so that your view can receive it and handle it appropriately. Thanks to @Deba22 for the fix :D

hharzan avatar Oct 29 '19 22:10 hharzan

Hello Guys, instead of using MessagingCenter you can use any IOC Container and register the IMultipickerService, MultipickerService as Singleton and resolve it OnActivityResult() Method.

osamaelhosany avatar Dec 09 '19 11:12 osamaelhosany

@osamaelhosany Can you provide code for resolving in OnActivityResult()? Using Prism with Unity

Thanks

meopoc avatar Jul 24 '20 16:07 meopoc