Using Android Preferences in a background service
In this post I will explain how I have used the Android Preferences in a background service. The preference is used as an interval for updating a listview with some simple text items.
Preferences
To create the preferences screen I added an Options Menu. This options menu is part of the HomeActivity. The HomeActivity simply shows a listview. When clicking on the options menu button it will start the SettingsActivity. This activity extends the PreferenceActivity.
The only thing that is really necessary in the SettingsActivity is to add the preferences that are specified in the corresponding xml. In my implementation I have added a method that sets the selected value below the title. In the screenshot on the left you can see that the summary shows 15.
SettingsActivity.java
public class SettingsActivity extends PreferenceActivity { public static final String UPDATE_PREF = "updatePref"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); setUpdatePreferences(); } private void setUpdatePreferences() { ListPreference updatePref = (ListPreference) findPreference(UPDATE_PREF); updatePref.setSummary(updatePref.getValue()); updatePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { ListPreference listPreference = (ListPreference) preference; listPreference.setSummary((String) newValue); SharedPreferences mySharedPreferences = getSharedPreferences("preferences", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = mySharedPreferences.edit(); editor.putString(UPDATE_PREF, (String) newValue); editor.commit(); return true; } }); } }Preferences.xml
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="Settings"> <ListPreference android:title="Update interval (seconds)" android:key="updatePref" android:defaultValue="5" android:entries="@array/interval" android:entryValues="@array/interval"/> </PreferenceCategory> </PreferenceScreen>Service
Nick Fox published a great post about how to create a background service, so I have used his example to expand it with the use of the Preferences.
In the method onStart() I have added the following piece of code to load the update interval from the preferences:
@Override public void onStart(Intent intent, int startId) { SharedPreferences mySharedPreferences = getApplicationContext().getSharedPreferences("preferences", Activity.MODE_PRIVATE); updateInterval = Integer.valueOf(mySharedPreferences.getString(SettingsActivity.UPDATE_PREF, "5")); Log.d(TAG, "*** Configured update interval: " + updateInterval); handler.removeCallbacks(sendUpdatesToUI); handler.postDelayed(sendUpdatesToUI, 1000); }This interval is then used in the run() method of the Runnable object to tell the handler that it needs to delay the execution of the runnable.
private Runnable sendUpdatesToUI = new Runnable() { public void run() { DisplayLoggingInfo(); handler.postDelayed(this, updateInterval * 1000); } };HomeActivity
The two most important methods in the HomeActivity are the onResume() and onPause(). When we open the settings screen from the home screen, the HomeActivity will call the onPause() method. In this method we will stop the service. When going back from the settings screen to the home screen, the onResume() method will be called. In this method we will start the service again. And as we retrieved the preferences in the onStart() method of the Service, it will gets our newly selected interval from the preferences.
@Override public void onResume() { super.onResume(); startService(intent); registerReceiver(broadcastReceiver, new IntentFilter(BroadcastService.BROADCAST_ACTION)); Log.d(TAG, "Started service"); } @Override public void onPause() { super.onPause(); unregisterReceiver(broadcastReceiver); stopService(intent); Log.d(TAG, "Stopped service"); }Logging the process
To give you an impression of how the flow of the process goes, I have logged a few statements. The one with the three stars are mine, the others are from Android.
Here you can see that the service is started from the HomeActivity and that the service found a configured interval (5 seconds) from the preferences.After that you can see that the HomeActivity logs every 5 seconds the recieved message. Then I open the SettingsActivity, which stops the service. Change the interval and go back to the HomeActivity, which is triggered again to start the service.
From that point the service now uses the new interval preference (10 seconds) to broadcast the message every 10 seconds.
11:41:39: HomeActivity(352): *** Started service
11:41:39: BroadcastService(352): *** Configured update interval: 5
11:41:39: ActivityManager(60): Displayed activity nl.jteam/.HomeActivity
11:41:40: HomeActivity(352): *** Sending at: Fri Aug 12 11:41:40 GMT 2011
11:41:45: HomeActivity(352): *** Sending at: Fri Aug 12 11:41:45 GMT 2011
…
11:42:25: HomeActivity(352): *** Sending at: Fri Aug 12 11:42:25 GMT 2011
11:42:27: ActivityManager(60):Starting activity: Intent { cmp=nl.jteam/.settings.SettingsActivity }
11:42:27: HomeActivity(352): *** Stopped service
11:42:27: ActivityManager(60): Displayed activity nl.jteam/.settings.SettingsActivity
11:42:32: HomeActivity(352): *** Started service
11:42:32: BroadcastService(352): *** Configured update interval: 10
11:42:33: HomeActivity(352): *** Sending at: Fri Aug 12 11:42:33 GMT 2011
11:42:43: HomeActivity(352): *** Sending at: Fri Aug 12 11:42:43 GMT 2011
11:42:53: HomeActivity(352): *** Sending at: Fri Aug 12 11:42:53 GMT 2011
11:43:03: HomeActivity(352): *** Sending at: Fri Aug 12 11:43:03 GMT 2011
…I hope that this post helped a few of you in your journey of creating more great Android apps!