Hi Guys,
I'm writing an app that allows the user to take photo's (using Xam.Plugin.Media) and then display them in a list view.
I noticed the app data growing with each photo taken. And I'm hoping someone could shed some light on what the issue is.
I do not wish to save the photo on the device.
I've only tested this on android at the moment.
I wrote a sample app to simulate the issue. Steps taken as well as the XAML and view model code to follow.
- Install app.
- Go to Android / Settings / Apps / {AppName} / Storage
- The app data is now approximately 10Mb and cache less than 1Mb.
- Start the app, take a photo but DO NOT press 'OK' to confirm the photo taken.
- Note that the app data has now increased with approximately the size of the photo in memory. (Let's use 5Mb, which brings the app data to 15Mb)
- Press 'OK' to confirm the photo taken which then adds the photo to the list view.
- Note that the app data has again increased with approximately the size of the photo in memory. (Again 5Mb, which brings the app data to 20Mb)
So with each photo taken the app data increases with approximately double the size of the photo taken, and as a result the app will end up using most of the device storage after a month of use.
I'm not sure if I'm missing something simple, or if this is a result of poor coding.
Any advice would be greatly appreciated.
Thanks in advance.
XAML:
<ContentPage.Content>
<Grid RowSpacing="0" Margin="10,10,10,0">
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Text="Take Photo" Command="{Binding TakePhotoCommand}"/>
<Label Grid.Row="1" Text="Photo List" HorizontalOptions="Center"/>
<ListView Grid.Row="2" ItemsSource="{Binding PhotoList}" RowHeight="250">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Image Source="{Binding ImageSource}" Aspect="Fill" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</ContentPage.Content>
View Model:
public class CameraVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
private ObservableCollection<MyPhoto> photoList {get;set;}
public ObservableCollection<MyPhoto> PhotoList
{
get { return photoList; }
set
{
if(value != photoList)
{
photoList = value;
OnPropertyChanged("PhotoList");
}
}
}
public ICommand TakePhotoCommand { get; set; }
public async void TakePhoto()
{
try
{
await CrossMedia.Current.Initialize();
var mediaFile = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions() { });
if (mediaFile == null)
{
return;
}
PhotoList.Add(new MyPhoto()
{
ImageSource = ImageSource.FromStream(() =>
{
Stream stream = mediaFile.GetStream();
mediaFile.Dispose();
return stream;
})
});
}
catch (Exception ex)
{
throw ex;
}
}
public CameraVM()
{
PhotoList = new ObservableCollection<MyPhoto>();
TakePhotoCommand = new Command(() =>
{
TakePhoto();
});
}
}