MultipleMediaPickerSample
MultipleMediaPickerSample copied to clipboard
Android Project Not Working
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.
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.
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.
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.
I'm also facing the same issue.Any update on this? @kurtlmartin
Can you post the code from your MainActivity.cs from your Android project?
@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.
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.
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?
- Check if your MultiMediaPickerService class is public.It should be public and not private.
- I am not using ViewModel concept.I'm doing everything in code behind.
- Check if your MultiMediaPickerService class is public.It should be public and not private.
- I am not using ViewModel concept.I'm doing everything in code behind.
Could you paste your code on how to use the above??
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!
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
Solved my own problem.
This line should say FlowItemsSource and not ItemSource
FlvItems.FlowItemsSource = mvm.Media;
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!
- 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??
- 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??
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
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 Can you provide code for resolving in OnActivityResult()? Using Prism with Unity
Thanks