Create “Press back again to exit” toast on Xamarin Androd

I found this relatively simple to implement.

AndroidToast

In the Activity that represents the final view of your application, i.e. the one that you want the user to see the Toast popup message, add this override code:

private double _backPressTime = 0;

public override void OnBackPressed()
{
	double t = new TimeSpan(DateTime.Now.Ticks).TotalMilliseconds;

	if (t - _backPressTime > 2000) // i.e. 2000 milliseconds
	{
		_backPressTime = t;
		Toast.MakeText(this, "Press back again to exit", ToastLength.Short)
				.Show();
	}
	else
	{
		base.OnBackPressed(); // now we can quit
	}
}

Visual Studio Dark Theme with light designer background color

I found this extremely useful at times because I like to use a Dark theme in Visual Studio. Making the following change in App.xaml means I can see all of my controls properly in the designer while I’m developing my app.

<Style TargetType="{x:Type UserControl}">
    <Style.Triggers>
        <Trigger Property="ComponentModel:DesignerProperties.IsInDesignMode" Value="true">
            <Setter Property="Background" Value="White" />
        </Trigger>
    </Style.Triggers>
</Style>

What does Samsung Android Power Saving Power do?

I recently googled “what does Android Power Saving Mode do ?”. There didn’t seem to be many clear answers, in fact the question could mean a few things. So for clarity I mean, what effect does Power Saving Mode have on the applications & services on my device.

It turns out that the Power Saving Mode is in fact a device feature and not part of Android, so I looked a bit closer at my A5 and found the answer.

Simply swipe down on the device to reveal the notification bar, then find press and hold on the Power Saving Mode Quick Connect button.

Samsung A5 Notification Bar showing Power Saving Mode quick button
Samsung A5 Notification Bar

You will be presented with the Power Saving Mode page.  Selecting Restrict Performance will give you even more details and options to tweak the setting as you wish.  Very cool.

Samsung A5 Power Saving Mode options
Samsung A5 Power Saving Mode options
Samsung A5 Power Saving Mode Restrict Performance options
Samsung A5 Power Saving Mode Restrict Performance options

Restricting Background Data is quite extreme and would probably mean I would not get notifications for things like my email, until I check my phone.  So I have that option switched off.

Samsung A5 Power Saving Mode Restrict backgorund data warning
Samsung A5 Power Saving Mode Restrict backgorund data warning

 

WPF Switch Color Theme at Runtime

This very simple class will allow you to switch Themes in a WPF application. Its not the only way to do it and is not a MVVM implementation, but can be modified easily if needed.

Here is the resource (theme) switching code:

public static class ThemeHelper
{
	public static void SwitchTheme(string stylefile)
	{
		if (File.Exists(stylefile))
		{
			using (FileStream fs = new FileStream(stylefile, FileMode.Open))
			{
				ResourceDictionary dic = (ResourceDictionary) XamlReader.Load(fs);
				Application.Current.Resources.MergedDictionaries.Clear();
				Application.Current.Resources.MergedDictionaries.Add(dic);
			}
		}   
	}

	public static void SwitchTheme(Uri themeUri)
	{
		var theme = new ResourceDictionary();
		theme.Source = themeUri;
		Application.Current.Resources.MergedDictionaries.Clear();            
		Application.Current.Resources.MergedDictionaries.Add(theme);
	}
}

For this to work just create a folder called “Themes” add your Theme files into there and mark as content. Each theme file must be in the same structure (i.e. use the same Key names obviously) for this to work.

Here is an example of a theme file:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="ThemeColor1">Green</SolidColorBrush>
    <SolidColorBrush x:Key="ThemeColor2">Red</SolidColorBrush>
    <SolidColorBrush x:Key="ThemeColor3">Orange</SolidColorBrush>
</ResourceDictionary>

Then anywhere in code you can changes themes like so (assuming you added a file called MangoTheme.xaml into the \Themes\ directory:

ThemeHelper.SwitchTheme(new Uri("/Themes/MangoTheme.xaml", UriKind.Relative));

Make sure you use DynamicResource markup extension in your bindings for anything that could change during runtime, i.e.

Background="{DynamicResource ThemeColor1}"

Generic Storage Manager

All of my apps make use of a common class for data storage management. Its simple and works for my needs, even providing a way to create a default context if one does not already exist.

Obviously any type you want to use with this must be decorated with the DataContractAttribute.

class StorageManager<T> where T : class 
{
	private readonly string _filename;
	private readonly Func<T> _defCtxFunc;
	
	public StorageManager(string filename, Func<T> defaultContextCreation)
	{
		_filename = filename;
		_defCtxFunc = defaultContextCreation;
	}
	
	public async Task<T> Load(Func<T> defaultContextCreation)
	{
		object existingData = null;

		try
		{
			var serializer = new DataContractSerializer(typeof (T));
			using (
				var stream =
					await
						ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(_filename))

			{
				existingData = serializer.ReadObject(stream);
				stream.Flush();
			}
		}
		catch (Exception e)
		{
			Debug.WriteLine("StorageManager.Load({1}) failed with exception :: {0}", _filename, e);
		}

		return (existingData ?? defaultContextCreation.Invoke()) as T;
	}

	public async Task<bool> Save(T data)
	{
		try
		{
			var serializer = new DataContractSerializer(typeof (T));
			using (
				var stream =
					await
						ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(_filename,
							CreationCollisionOption.ReplaceExisting))
			{
				serializer.WriteObject(stream, data);
				stream.Flush();                    
			}

			Debug.WriteLine("Save [{0}] to [{1}] success", _filename, ApplicationData.Current.LocalFolder.Path);
			return true;
		}
		catch(Exception e)
		{
			Debug.WriteLine("Save [{0}] failed with exception :: {1}", _filename, e);
			return false;
		}
	}
}