The Problem
Accessing preferences / configuration / settings from Android is actually pretty
straightforward as long as you are in an
Activity
.
To read:
1
2
3
4
5
6
7
8
9
10
| // PREFS_FILENAME = "nameOfPrefsFile";
SharedPreferences pref = getSharedPreferences(PREFS_FILENAME,
Context.MODE_PRIVATE);
String string = pref.getString("key", "default");
// 1 is the default if key isn't set
int intValue = pref.getInt("intKey", 1);
// and so on
|
SharedPreference
s
is the key class. To write, you also need the
[SharedPreferences.Editor](http://developer.android.com/reference/android/content/SharedPreferences.Editor.html{
class, as follows:
1
2
3
4
5
6
7
8
9
10
| // PREFS_FILENAME = "nameOfPrefsFile";
SharedPreferences pref = getSharedPreferences(PREFS_FILENAME,
Context.MODE_PRIVATE);
Editor editor = pref.edit();
editor.putString("key", "value");
editor.putInt("intKey", 5);
// Until you call commit, the changes will not
// be written, so don't forget this step
editor.commit();
|
In general however, you will need access to settings in more than one activity
and it seems a bit wasteful to get these bits littered through the application.
Since I am lazy and like to write things just once, I separated all the prefs
stuff into one class called Settings.
It has a constructor which takes a
Context
(We need this to access the SharedPreferences Object). It also has setters and
getters for each property being saved. This example, just saves/retrieves a
username and password.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
| import uk.co.kraya.HelloWS;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
/**
* @author Shriram Shri Shrikumar
*
* This class stores and manages all the preferences
* for the application.
*
*/
public class Settings {
private static final String USERNAME_KEY = "username";
private static final String PASSWORD_KEY = "password";
private static final String USERNAME_DEFAULT = "username";
private static final String PASSWORD_DEFAULT = "password";
private final SharedPreferences settings;
/**
* @param act The context from which to pick SharedPreferences
*/
public Settings (Context act) {
settings = act.getSharedPreferences(HelloWS.PREFS_NAME, Context.MODE_PRIVATE);
}
/**
* Set the username in the preferences.
*
* @param username the username to save into prefs
*/
public void setUsername(String username) {
Editor editor = settings.edit();
editor.putString(USERNAME_KEY, username);
editor.commit();
}
/**
* @return the username from the prefs
*/
public String getUsername() {
return settings.getString(USERNAME_KEY, USERNAME_DEFAULT);
}
/**
*
* Set the password in the preferences.
*
* @param password password to save into prefs
*/
public void setPassword(String password) {
Editor editor = settings.edit();
editor.putString(PASSWORD_KEY, password);
editor.commit();
}
/**
* @return the password stored in prefs
*/
public String getPassword() {
return settings.getString(PASSWORD_KEY, PASSWORD_DEFAULT);
}
// Check if there are any stored settings.
// can be used to automatically load the settings page
// where necessary
public boolean hasSettings() {
// We just check if a username has been set
return (!settings.getString(USERNAME_KEY, "").equals(""));
}
}
|
Nothing particularly exciting. Now, how do we access this. The Android framework
has a neat little feature that is not very well documented and it involved the
use of the
Application
class. If you inherit from this class, and point to it in the manifest file, it
will get initialised first before any other objects. This is an ideal place for
bits that need global access. You could use Singletons or static fields but this
works with the framework.
There are two parts to making this work
The application class:
public class MyApp extends Application {
private Settings settings;
@Override
public void onCreate() {
settings = new Settings(this);
}
public Settings getSettings() {
return settings;
}
}
The onCreate
method on MyApp
will be called before onCreate
on any of the
Activities. The Settings class described above, needs a Context to be passed in.
Lucky for us ;-) Application is also a Context.
You also need to wire it into the AndroidManifest.xml
. You need to add the
android:name
element into the
application tag
{
1
| <application android:name="com.package.MyApp" android:icon="@drawable/icon" android:label="@string/app_name">
|
Now that is all wired in, accessing the settings object from any activity is
simple:
1
2
3
| MyApp app = (MyApp) getApplicationContext();
Settings settings = app.getSettings();
|
Easy - right? While you won’t be able to access the application subclass outside
of a context, the Setting class, with its local context variable can be passed
around with impunity :-D