Forum General

OOM when using MediaPicker from XLabs

IuliaJecanIuliaJecan USMember ✭✭

Hey. I am stuck from some time with this:
I am using the next code for selecting an image or/and take an image in a cross-platform application in the purpose of sending it to the server. After choosing the image it is previewed on a second page where the user can cancel or send the image. On iOS the code works perfectly, but on Android if the user cancels the sending and tries to send another image an OOM error it's thrown when adding the photo to preview page.

The code for capturing an image or choosing one:

using System;
using System.Diagnostics;
using System.Threading.Tasks;
using ***;
using Xamarin.Forms;

using XLabs.Forms.Mvvm;
using XLabs.Ioc;
using XLabs.Platform.Device;
using XLabs.Platform.Services.Media;

namespace ***
{

    public class CameraViewModel : ViewModel
    {
        private IMediaPicker mediaPicker;
        private ImageSource _imageSource;
        private string _pathInfo;
        private string _status;
        private int _imageQuality = 80;
        private int _maxPixelDimension = 400;

        public ImageSource ImageSource
        {
            get { return _imageSource; }
            set { SetProperty(ref _imageSource, value); }
        }

        public string PathInfo
        {
            get { return _pathInfo; }
            set { SetProperty(ref _pathInfo, value); }
        }

        public string Status
        {
            get { return _status; }
            set { SetProperty(ref _status, value); }
        }

        private void Setup()
        {
            if (mediaPicker == null)
            {
                mediaPicker = new MediaPicker();
                //mediaPicker.OnMediaSelected += (sender, e) => DisposeObjects();
            }
        }

        public async Task TakePicture()
        {
            Setup();

            ImageSource = null;

            await mediaPicker.TakePhotoAsync(new CameraMediaStorageOptions
            {
                DefaultCamera = CameraDevice.Rear,
                MaxPixelDimension = _maxPixelDimension,
                PercentQuality = _imageQuality,
                SaveMediaOnCapture = false,
            }).ContinueWith(t =>
            {
                if (t.IsCanceled || t.IsFaulted) // user canceled or error
                    return;
                PathInfo = t.Result.Path;
                t.Result.Dispose();
                t.Dispose();
                GC.Collect();
            });
        }

        public async Task SelectPicture()
        {
            Setup();
            await mediaPicker.SelectPhotoAsync(new CameraMediaStorageOptions()
            {
                PercentQuality = _imageQuality,
                MaxPixelDimension = _maxPixelDimension,
            }).ContinueWith(t =>
            {
                if (t.IsCanceled || t.IsFaulted) // user canceled or error
                    return;

                PathInfo = t.Result.Path;
                t.Result.Dispose();
                t.Dispose();
            });
        }

        public void DisposeObjects()
        {
            mediaPicker = null;
            PathInfo = "";
        }
    }
}

The code of the preview page:

using System;
using Rg.Plugins.Popup.Extensions;
using Xamarin.Forms;
using Rg.Plugins.Popup.Pages;
using Entractes;
using System.Threading.Tasks;

namespace ***
{
    public class PreviewImagePopupPage : PopupPage
    {
        private double viewSize = 400;
        private CameraViewModel camera;
        private InterventionModel inter;

        public PreviewImagePopupPage(CameraViewModel cam, InterventionModel interention)
        {
            inter = interention;
            camera = cam;
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            initializeView();
        }

        private void initializeView()
        {
            var headerStyle = new Style(typeof(Label))
            {
                BaseResourceKey = "InterSimpleHeaderStyle"
            };
            Label titleLabel = new Label
            {
                Style = headerStyle,
                Text = "Envoyer photo",
                FontAttributes = FontAttributes.Bold
            };

            Entry imageTitleEntry = new Entry
            {
                Margin = new Thickness(10, 15),
                FontSize = 18,
                Keyboard = Keyboard.Text,
                Placeholder = "Saisir ici le nom de fichier!",
                PlaceholderColor = Color.Silver,
                TextColor = Color.DarkGray,
            };
            imageTitleEntry.TextChanged += (sender, e) =>
            {
                if (!string.IsNullOrEmpty(imageTitleEntry.Text))
                {
                    imageTitleEntry.PlaceholderColor = Color.Silver;
                }
            };

            double imageHeight = viewSize - 180;
            Image imagePreview = new Image
            {
                HeightRequest = imageHeight,
                Source = ImageSource.FromFile(camera.PathInfo),
                Aspect = Aspect.AspectFit,
                Margin = new Thickness(10, 0, 10, 3),
            };

            var buttonStyle = new Style(typeof(Label))
            {
                BaseResourceKey = "V3_ButtonStyle1"
            };

            Button sendButton = new Button
            {
                Text = "Envoyer",
                Style = buttonStyle,
            };
            sendButton.Clicked += (sender, e) =>
            {
                if (string.IsNullOrEmpty(imageTitleEntry.Text))
                {
                    imageTitleEntry.PlaceholderColor = Color.Red;
                }
                else
                {
                    EAFTPManager fsManager = new EAFTPManager();
                    bool result = fsManager.SendFileFtpAsync(imageTitleEntry.Text, camera.PathInfo, inter);
                    if (result)
                    {
                        camera.DisposeObjects();
                    }
                }
            };

            Button cancelButton = new Button
            {
                Text = "Annuler",
                Style = buttonStyle,
            };
            cancelButton.Clicked += (sender, e) =>
            {
                camera.DisposeObjects();
                Navigation.PopPopupAsync();
            };

            StackLayout stContent = new StackLayout
            {
                HorizontalOptions = LayoutOptions.CenterAndExpand,
                VerticalOptions = LayoutOptions.CenterAndExpand,
                Margin = new Thickness(3),
                Spacing = 0,
                HeightRequest = viewSize,
                MinimumHeightRequest = viewSize,
                BackgroundColor = Color.White,
                Children =
                {
                    titleLabel,
                    imageTitleEntry,
                    imagePreview,
                    new StackLayout {
                        Orientation= StackOrientation.Horizontal,
                        Spacing = 6,
                        Padding = new Thickness(10,3),
                        Children = {
                            cancelButton,
                            sendButton,
                        }
                    }
                }
            };
            Content = stContent;
        }

        protected override void OnSizeAllocated(double width, double height)
        {
            base.OnSizeAllocated(width, height);
            double transparentSurface = ((height * 10) / 100);
            viewSize = height - transparentSurface;
        }
    }
}

Thanks in advance.

Answers

  • IuliaJecanIuliaJecan USMember ✭✭

    The problem is the PreviewImagePopupPage: PopupPage. Change it to a ContentPage and now is working as expected.
    I don't understand why.

    Still, I would love a solution to keep using the PopupPage.

Sign In or Register to comment.