The Android for .NET Developers Series
Part 1 Starting with this article, I'll discuss what you need to know to approach Android programming without any aid from your .NET expertise.
Part 2 In this article, we'll go through an Android application that accepts input from the user and handles user's clicking.
Part 3 In this article, you will learn how to build the user interface.
Part 4 In this article, I'll be delving deep into menus and dialog boxes in Android for .NET, and discuss a few very common (and frequently used) types of menus and dialogs.
Part 5 In this article, Dino Esposito focuses on the options that the Android SDK offers for local storage.
Part 6 In this article, Dino Esposito shows how to build settings dialog boxes using a built-in feature of Android for .NET.
Part 7 In this article, I'll dissect the code of a realistic application - a waterpolo score manager - to show how to save and resume the status of a game using both the internal storage and SD card.
Part 8 In this article, I'll focus on the execution of common tasks from within an Android application. I'll build the skeleton of an application that takes a photo and emails to the specified address. For both tasks I'll use native Android components.
Introduction
All developers agree that nearly any applications should have their own collection of settings to modify the behavior according
to business needs and in some cases user preferences. At the same time, all developers agree that writing an additional layer of
user interface to enable the input of these settings is one of the most boring tasks, almost as annoying as writing technical
documentation. Thanks to templated helpers, in ASP.NET MVC you can go very close to an ideal scenario in which, as a developer, you
just write the class that contains your settings and let a system component automatically build an HTML editor around that. In
ASP.NET MVC, however, the automatic behavior stops once the form is displayed. Persistence, in other words, is entirely up to
you.
The great news for .NET developers approaching Android programming is that the SDK just provides a set of classes that
read layout information from an XML file and build a native user interface automatically. Nicely enough, however, Android classes -
specifically the Preferences framework - also manage persistence in a way that is completely transparent to developers. In this
article, I'll show how to build settings dialog boxes using this built-in feature.
Experimenting with Preference Screens
The first step consists in defining the layout of the settings dialog. You create an XML file with any name and place it under
the res/xml folder of your Android project. To start off, let's consider a very simple but still effective layout for a settings
dialog that is fairly common in mobile applications - the dialog where the user enters login information to sign in to a given
service. To clarify, you see a similar dialog box when you connect to Skype or social network applications on Android and other
mobile platforms as well.
At the very minimum, this login settings dialog will gather three pieces of information: user name
and password (credentials) and a flag indicating whether the user wants to stay logged in and possibly for how long. With this
scenario in mind, here's a sample XML to describe preferences:
The PreferenceScreen element represents a page containing some editable settings. You can have multiple
screens, you can import a settings screen from another application and you can also create a logical chain of dependencies between
screens. Each screen is made of a bunch of preference widgets, namely input elements for data to enter. Table 1 presents the list of
available preference widgets.
Table 1: Preference widgets in Android.
Widget | Description |
CheckBoxPreference | Gets and sets a Boolean value through a check-box user
interface. |
EditTextPreference | Gets and sets a String value through a classic text-box user
interface. |
DialogPreference | Gets and sets custom types through a handmade dialog layout. |
ListPreference | Gets and sets an array of data through a list user interface. |
Preference | Base class for all preference widget elements. |
PreferenceCategory | Container element, it groups child preference widgets in a distinct
piece of user interface. The overall behavior is similar to what a fieldset element does in HTML. |
RingtonePreference | Gets and sets a ringtone. You use this widget when you're choosing
a distinct ringtone to be associated with a particular notification. |
You can create your own preference widgets (i.e., a DatePreference) by deriving a new class from
Preference. The XML elements in the preference file will define at least four properties: title for the
label of the input element, summary for a brief description of the input element, defaultValue for the
default value you want to display initially, and finally key to indicate the name of the entry where the entered value
will be stored in the preference dictionary. The key attribute is a plain string.
Now that we have a simple but
functional preference screen in place, let's see what it takes to integrate it with a real Android application.
Integrating the Preference Framework in Applications
Each preference screen should be wrapped up in a custom activity that inherits from the PreferenceActivity class.
This is a necessary step because, as we'll see in a moment, there's a lot of behavior that goes on under the hood. Because there's
no magic in software this behavior must be coded somewhere. In this specific case, the invisible location is just the
PreferenceActivity class. Here's a sample activity for the login preference screen.
A preference class is a very simple one that calls addPreferencesFromResources from within its
onCreate method. More precisely, you call this method when you have your XML layout defined in the resources of the
application. In this case, the parameter you pass just point to the specific resource. In Android, the expression R.xml.Xxx
means you want to pick up an element from the application's resource, specifically a resource named Xxx from the xml
folder.
You can also add a preference dialog from an Intent object. In this case, you call the method
addPreferencesFromIntent and pass it an Intent object as its sole argument. Here's an example of how you
create an Intent out of a preference screen.
This activity is different from the main activity that governs the main flow of the application. If you want that the
preference dialog shows up at startup, you do the following in your primary activity:
It is necessary that the login preference activity is registered in the application's manifest file.
Figure 1 shows the output being displayed to the user.
Figure 1: The login preference activity in action.

Interacting with this dialog
box is fairly easy. The user clicks on the button near each widget and an editor is displayed with the current data if any or the
default value. See Figure 2.
Figure 2: Editing data in a preference dialog.

It should be noted that all the
preferences you enter through such a dialog are automatically saved to a local file using the SharedPreferences
dictionary. Data is saved as the user interacts with the widgets and is transparent to the developer.
Improving the User Experience
Settings saved locally make sense only if they can be read back and, more importantly, if they're used to improve the user
experience by modifying the user interface. In mobile applications, you always want to minimize typing. For applications that need
credentials, a common practice consists in persisting username and password locally with an application specific expiration policy.
Our sample application therefore will first read login information from the saved preferences and displays the settings dialog if no
such information is found. Here's how to rewrite the onCreate method on the primary activity.
LoginInfo is a helper class that reads preferences and stores values. To read preferences, you need an instance of the
SharedPreferences class. More importantly, you need just the instance shared at application level by all participating
activities.
The static method getDefaultSharedPreferences on the PreferenceManager class returns the
SharedPreferences dictionary for the specified context. Because settings are saved by the LoginPreferences activity and retrieved by
the primary activity of the application, it is important that you pass a shared context - for example the application context.
Here's why this call is absolutely necessary:
If you pass this instead of getApplicationContext(), then the code compiles and runs, but
you just won't be able to read anything back from preferences. It saves correctly in one place, but then reads back from another
location. If the login information is missing or invalid, the application shows the settings dialog; otherwise it proceeds and
displays the regular interface as in Figure 3.
Figure 3: The primary interface when login data is available.

To
display the settings you use the code below. This is the same code that is also bound to the Edit button in Figure 3.
Changes made to the settings during the application's lifecycle can be notified to the application so that they can be
immediately reflected in the user interface. You can register an event listener for the saved event like below. You
call this code from onCreate.
Here's some sample code that is invoked when a change occurs.
The first argument gets the current status of preferences; the second argument indicates which field has been
modified. You'll receive this notification for each individual change. The method Refresh in the code snippet is a
placeholder for any UI code that updates the visual elements based on preferences.
It is worth noting that the preferences
dialog doesn't have a Save or OK button. As you can see in Figure 1, it doesn't have any commit/cancel pair of buttons. This is
another key pattern of mobile applications - you should try to keep tapping to a bare minimum. In more and more applications any
typed data is taken for good and saved or processed as if there was an explicit OK command. Hitting the Back button doesn't cancel
anything but simply moves you back to the previous activity - it is the Implicit Save pattern (or Back-and-Save
pattern) of mobile applications.
Summary
Most of the time programming for Android is boring and .NET developers often find the programming model overzealous. However, I
confess that the part of the Android SDK that deals with preferences is really nice and effective. And compared to how picky and
slow it could be to develop a custom dialog box, the automatic behavior of the Preferences framework is a big relief for
developers.
The Android for .NET Developers Series
Part 1 Starting with this article, I'll discuss what you need to know to approach Android programming without any aid from your .NET expertise.
Part 2 In this article, we'll go through an Android application that accepts input from the user and handles user's clicking.
Part 3 In this article, you will learn how to build the user interface.
Part 4 In this article, I'll be delving deep into menus and dialog boxes in Android for .NET, and discuss a few very common (and frequently used) types of menus and dialogs.
Part 5 In this article, Dino Esposito focuses on the options that the Android SDK offers for local storage.
Part 6 In this article, Dino Esposito shows how to build settings dialog boxes using a built-in feature of Android for .NET.
Part 7 In this article, I'll dissect the code of a realistic application - a waterpolo score manager - to show how to save and resume the status of a game using both the internal storage and SD card.
Part 8 In this article, I'll focus on the execution of common tasks from within an Android application. I'll build the skeleton of an application that takes a photo and emails to the specified address. For both tasks I'll use native Android components.
About Dino Esposito
 |
Dino Esposito is one of the world's authorities on Web technology and software architecture. Dino published an array of books, most of which are considered state-of-the-art in their respective areas. His most recent books are “Microsoft ® .NET: Architecting Applications for the Enterprise” and “...
This author has published 53 articles on DotNetSlackers. View other articles or the complete profile here.
|
You might also be interested in the following related blog posts
You should NOT use ASP.NET MVC if. . .
read more
Hey, nice package!
read more
2009 Predictions - ASP.NET, BizTalk and LINQ 2 SQL are dead and so are VB, C# and Azure
read more
Oxite - Oh Dear Lord Why?!
read more
Baby-sitter Framework 2.0: Change tracking in the EF v2, it's still your problem
read more
Best Practices for Wrapping Native Code
read more
I'll get to your application in a minute - First, we need to build the framework
read more
Loving the South African Developer Community
read more
WPF Series: IFrameworkElement - the missing interface
read more
SQL Server Reporting Services Subscriptions with custom security
read more
|
|
Please login to rate or to leave a comment.