Persistence

Storing Arbitrary Data with SharedPreferences

Using SQLite to Store Data

Retrieving Data from SQLite with SimpleCursorAdapter

Using an ORM for SQLite - SQLite.NET

Using Realm Database

Creating a Settings Screen with PreferenceActivity

Creating a Settings Screen with PreferenceFragment

Adding a Setting Screen Using PreferenceFragmentCompat

They are several ways to add a Settings\/Preference Screen to your app :

  1. Use the PreferenceActivity

  2. Use the PreferenceFragment

  3. Use the PreferenceFragmentCompat

Adding an xml Resource File

For both methods you will need an an xml resource file to be added into the Resources folder under the xml directory.

  1. Create the xml folder if it does not yet exists under the Resources directory

  2. Create a new xml resource file into the just created xml resource directory or use the existing one.

  3. Add the preferences. The preferences have the equivalent names to their views with the additional Preference suffix, e.g to add an EditText preference you use EditTextPreference. Also preferences use keys instead of id since they are stored as key\/value pairs

Resources/xml/prefs.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="General">
        <EditTextPreference
            android:key="nickname"
            android:title="Nickname" />
    </PreferenceCategory>
    <PreferenceCategory android:title="Notifications">
        <SwitchPreference
            android:title="Notifications"
            android:summary="Get notifications when you receive messages"
            android:key="notifications"
            android:defaultValue="true" />
        <RingtonePreference
            android:defaultValue="content://settings/system/notification_sound"
            android:dependency="notifications"
            android:key="user_joined"
            android:title="User Joined"
            android:summary="Alert for when a user joins the chat"
            android:ringtoneType="notification" />
        <RingtonePreference
            android:defaultValue="content://settings/system/notification_sound"
            android:dependency="notifications"
            android:key="user_left"
            android:title="User Left"
            android:summary="Alert for when a user leaves the chat"
            android:ringtoneType="notification" />
        <RingtonePreference
            android:defaultValue="content://settings/system/notification_sound"
            android:dependency="notifications"
            android:key="mew_message"
            android:title="New Message"
            android:summary="Alert for when a new message arrives"
            android:ringtoneType="notification" />
    </PreferenceCategory>
</PreferenceScreen>

The settings UI is defined inside the following tags :

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
  ...
</PreferenceScreen>

Adding Categories

We add categories to the settings UI by using the

<PreferenceCategory android:title="General">
  ...
</PreferenceCategory>

Adding a Switch Preference

<SwitchPreference
   android:title="Notifications"
   android:summary="Get notifications when you receive messages"
   android:key="notifications"
   android:defaultValue="true" />

Adding a Ringtone Preference

The ringtone preference will load the phone ringtones settings into your settings screen and lets the user pick a ringtone. You can also add a default ringtone

 <RingtonePreference
     android:defaultValue="content://settings/system/notification_sound"
     android:dependency="notifications"
     android:key="user_joined"
     android:title="User Joined"
     android:summary="Alert for when a user joins the chat"
     android:ringtoneType="notification" />

Adding a Settings Screen using PreferenceActivity

The easiest way to add a settings screen is to create an activity that inherits from the PreferenceActivity class. We will use the xml resource defined above.

  1. Create a new Activity

  2. Inherit from PreferenceActivity instead of Activity or AppCompatActivity

  3. In the OnCreate method, instead of setting the SetContentView method use AddPreferencesFromResource method. Notice this method is deprecated, so you will need to use the other methods

PrefsActivity.cs

[Activity(Label = "PreActivity")]
public class PrefsActivity : PreferenceActivity
{
	protected override void OnCreate(Bundle savedInstanceState)
	{
		base.OnCreate(savedInstanceState);
		AddPreferencesFromResource(Resource.Xml.prefs);
	}
}

Add a Menu option to Open the Settings Screen

You will need to define a menu so you can use it to open the settings screen.

  1. Add the menu folder in the Resources folder if one does not yet exist

  2. Create a menu.xml file

<?xml version="1.0" encoding="UTF-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
	<item 
		android:id="@+id/action_menu"
		android:title="Settings" />
</menu>
We will use the defined id on the menu to find which menu option have been selected.
  1. Modify the activity you want to be able to access the settings from and create the menu.

MainActivity.cs

//Create the options menu
public override bool OnCreateOptionsMenu(Android.Views.IMenu menu)
{
	MenuInflater.Inflate(Resource.Menu.menu, menu);
	return base.OnCreateOptionsMenu(menu);
}

MainActivity.cs

//Handle the selecting of the options menu
public override bool OnOptionsItemSelected(Android.Views.IMenuItem item)
{
	var id = item.ItemId;
	if (id == Resource.Id.action_menu) { 
		StartActivity(new Android.Content.Intent(this, typeof(PrefsActivity)));
	}
	return true;
}

Now when you run you should be able to get an option item called Settings. When click it, the settings screen should load up.

Adding a Settings Screen Using a PreferenceFragment

Use the following steps to create a settings screen using the PreferenceFragment :

  1. Create a class that derives from PreferenceFragment

  2. In the OnCreate method use the AddPreferenceFromResource method to inflate the preference xml file

    PrefsFragment.cs

public class PrefsFrgament : PreferenceFragment
{
	public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        AddPreferencesFromResource(Resource.Xml.prefs);
    }
}
	```

3. In the activity you would like to show the preference, replace an exisiting container, usually FrameLayout with the PrefsFragment

 Resources/layout/activity_main.axml

 

```xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

PrefsActivity.cs

Use the FragmentManager to replace the FrameLayout with the PrefsFragment

FragmentManager
	.BeginTransaction()
	.Replace(Resource.Id.content, new PrefsFragment())
	.Commit();

PrefsActivity.cs

using Android.App;
using Android.OS;
using Android.Support.V4.App;
using Android.Support.V7.App;
using Android.Views;

namespace sharedPreferenceDemo
{
	[Activity(Label = "PrefsActivity", Theme = "@style/AppTheme", ParentActivity = typeof(MainActivity))]

	[MetaData("android.support.PARENT_ACTIVITY", Value = "md51c3958e33f8e72dae9076079df527ba2.MainActivity")]

	public class PrefsActivity : AppCompatActivity
	{
		protected override void OnCreate(Bundle savedInstanceState)
		{
			base.OnCreate(savedInstanceState);
			SetContentView(Resource.Layout.activity_prefs);
			FragmentManager
				.BeginTransaction()
				.Replace(Resource.Id.content, new PFrgament())
				.Commit();

			if (SupportActionBar != null) { 
				SupportActionBar.SetDisplayHomeAsUpEnabled(true);
			}
		}

		public override bool OnOptionsItemSelected(IMenuItem item)
		{
			if (item.ItemId == Android.Resource.Id.Home) { 
				NavUtils.NavigateUpFromSameTask(this);
			}
			return base.OnOptionsItemSelected(item);
		}
	}
}

Adding Up Arrow for Back Navigation

In the Oncreate method we check if we have an ActionBar and set the up arrow to display :

if (SupportActionBar != null) { 
	SupportActionBar.SetDisplayHomeAsUpEnabled(true);
}

Then we handle the clicking of the up arrow in the OnOptionsItemSelected methods :

public override bool OnOptionsItemSelected(IMenuItem item)
{
	if (item.ItemId == Android.Resource.Id.Home) { 
		NavUtils.NavigateUpFromSameTask(this);
	}
	return base.OnOptionsItemSelected(item);
}

Adding a Parent Activity

In oder to go back to a parent activity when we click the up arrow, we need to add attribute to the activity. We specify the ParentActivity

[Activity(Label = "PrefsActivity", Theme = "@style/AppTheme", ParentActivity = typeof(MainActivity))]

For this to also work on older devices, we have to use a MetaData attribute and use the the name as android.support.PARENT_ACTIVITY and the value to be fully qualified name of the activity to navigate back to.

[MetaData("android.support.PARENT_ACTIVITY", Value = "md51c3958e33f8e72dae9076079df527ba2.MainActivity")]

You can find the MD5Sum, md51c3958e33f8e72dae9076079df527ba2 of the activity by check the generated AndroidManifest.xml file in the obj folder