Creating A Settings Activity For The Earthquake Viewer

In Chapter 5 you created an earthquake monitor that showed a list of recent earthquakes based on an RSS feed.

In the following example you'll build an Activity to set application preferences for this earthquake viewer. It will let users configure settings for a more personalized experience. You'll provide the option to toggle automatic updates, control the frequency of updates, and filter the minimum earthquake magnitude displayed.

Later in this chapter you'll replace this Activity with a standard settings screen.

1. Open the Earthquake project you created in Chapter 5.

Add new string resources for the labels displayed in the preferences screen. Also add a string for the new Menu Item that will let users access this Activity:

<?xml version="1.0" encoding="utf-8"?> <resources>

<string name="app_name">Earthquake</string> <string name="quake_feed"> </string>

<string name="menu_update">Refresh Earthquakes</string> <string name="auto_update_prompt">Auto Update?</string> <string name="update freq prompt">Update Frequency</string> <string name="min_quake_mag_prompt">Minimum Quake Magnitude</string> <string name="menu_preferences">Preferences</string> </resources>

2. Create a new preferences.xml layout resource for the Preferences Activity. Include a checkbox for indicating the "automatic update'' toggle, and spinners to select the update rate and magnitude filter:

<LinearLayout xmlns:android="" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent"



<CheckBox android:id="@+id/checkbox_auto_update" android:layout_width="fill_parent" android:layout_height="wrap_content"

<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/update freq prompt"

<Spinner android:id="@+id/spinner_update_freq" android:layout_width="fill_parent" android:layout_height="wrap_content" android:drawSelectorOnTop="true"

<TextView android:layout_width="fill_parent"

Prepared for ASHLEE KABAT, email: [email protected] Order number: 56760408 This PDF is for the purchaser's personal use in accordance with the Wrox Terms of Service and under US copyright as stated on this book's copyright page. If you did not purchase this copy, please visit to purchase your own copy.

android:layout_height="wrap_content" android:text="@string/min_quake_mag_prompt"

<Spinner android:id="@+id/spinner_quake_mag" android:layout_width="fill_parent" android:layout_height="wrap_content" android:drawSelectorOnTop="true"

<LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <Button android:id="@+id/okButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@android:string/ok"

<Button android:id="@+id/cancelButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@android:string/cancel"

</LinearLayout> </LinearLayout>

3. Create four array resources in a new res/values/arrays.xml file. They will provide the values to use for the update frequency and minimum magnitude spinners:

<?xml version="1.0" encoding="utf-8"?> <resources>

<string-array name="update_freq_options"> <item>Every Minute</item> <item>5 minutes</item> <item>10 minutes</item> <item>15 minutes</item> <item>Every Hour</item> </string-array>

<array name="magnitude"> <item>3</item> <item>5</item> <item>6</item> <item>7</item> <item>8</item> </array>

<string-array name="magnitude_options"> <item>3</item> <item>5</item> <item>6</item> <item>7</item> <item>8</item> </string-array>

<array name="update_freq_values"> <item>1</item>

<item>5</item> <item>10</item> <item>15</item> <item>60</item> </array> </resources>

4. Create the Preferences Activity.

Override onCreate to inflate the layout you created in Step 2, and get references to the checkbox and both the spinner controls. Then make a call to the populateSpinners stub:

package com.paad.earthquake;


import android.content.SharedPreferences;

import android.content.SharedPreferences.Editor;

import android.os.Bundle;

import android.view.View;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.CheckBox;

import android.widget.Spinner;

public class Preferences extends Activity {

CheckBox autoUpdate; Spinner updateFreqSpinner; Spinner magnitudeSpinner;

©Override public void onCreate(Bundle savedlnstanceState) { super.onCreate(savedlnstanceState); setContentView(R.layout.preferences);

updateFreqSpinner = (Spinner)findViewById(; magnitudeSpinner = (Spinner)findViewById(; autoUpdate = (CheckBox)findViewById(;


private void populateSpinners() { }

5. Fill in the populateSpinners method, using Array Adapters to bind each spinner to its corresponding array:

private void populateSpinners() {

// Populate the update frequency spinner ArrayAdapter<CharSequence> fAdapter;

fAdapter = ArrayAdapter.createFromResource(this, R.array.update_freq_options, android.R.layout.simple_spinner_item); int spinner_dd_item = android.R.layout.simple_spinner_dropdown_item; fAdapter.setDropDownViewResource(spinner_dd_item); updateFreqSpinner.setAdapter(fAdapter); Prepared for ASHLEE KABAT, email: [email protected] Order number: 56760408 This PDF is for the purchaser's personal use in accordance with the Wrox Terms of Service and under US copyright as stated on this book's copyright page. If you did not purchase this copy, please visit to purchase your own copy.

// Populate the minimum magnitude spinner ArrayAdapter<CharSequence> mAdapter; mAdapter = ArrayAdapter.createFromResource(this, R.array.magnitude_options, android.R.layout.simple_spinner_item); mAdapter.setDropDownViewResource(spinner_dd_item); magnitudeSpinner.setAdapter(mAdapter);

6. Add public static string values that you'll use to identify the Shared Preference keys you'll use to store each preference value. Update the onCreate method to retrieve the named preference and call updateUIFromPreferences. The updateUIFromPreferences method uses the get<type> methods on the Shared Preference object to retrieve each preference value and apply it to the current UI.

Use the default application Shared Preference object to save your settings values:

public static final String PREF_AUTO_UPDATE = "PREF_AUTO_UPDATE"; public static final String PREF_MIN_MAG = "PREF_MIN_MAG"; public static final String PREF_UPDATE_FREQ = "PREF_UPDATE_FREQ";

SharedPreferences prefs;

©Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.preferences);

updateFreqSpinner = (Spinner)findViewById(; magnitudeSpinner = (Spinner)findViewById(; autoUpdate = (CheckBox)findViewById(;


Context context = getApplicationContext();

prefs = PreferenceManager.getDefaultSharedPreferences(context); updateUIFromPreferences();

private void updateUIFromPreferences() {

boolean autoUpChecked = prefs.getBoolean(PREF_AUTO_UPDATE, false); int updateFreqIndex = prefs.getInt(PREF_UPDATE_FREQ, 2); int minMagIndex = prefs.getInt(PREF_MIN_MAG, 0);

updateFreqSpinner.setSelection(updateFreqIndex); magnitudeSpinner.setSelection(minMagIndex); autoUpdate.setChecked(autoUpChecked);

7. Still in the onCreate method, add event handlers for the OK and Cancel buttons. Cancel should close the Activity, while OK should call savePreferences first:

©Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.preferences); Prepared for ASHLEE KABAT, email: [email protected] Order number: 56760408 This PDF is for the purchaser's personal use in accordance with the Wrox Terms of Service and under US copyright as stated on this book's copyright page. If you did not purchase this copy, please visit to purchase your own copy.

updateFreqSpinner = (Spinner)findViewById(; magnitudeSpinner = (Spinner)findViewById(; autoUpdate = (CheckBox)findViewById(;


Context context = getApplicationContext();

prefs = PreferenceManager.getDefaultSharedPreferences(context); updateUIFromPreferences();

Button okButton = (Button) findViewById(; okButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) { savePreferences();

Preferences.this.setResult(RESULT_OK); finish();

Button cancelButton = (Button) findViewById(; cancelButton.setOnClickListener(new View.OnClickListener() {

public void onClick(View view) {

Preferences.this.setResult(RESULT_CANCELED); finish();

private void savePreferences() { }

8. Fill in the savePreferences method to record the current preferences, based on the UI selections, to the Shared Preference object:

private void savePreferences() {

int updateIndex = updateFreqSpinner.getSelectedItemPosition(); int minMagIndex = magnitudeSpinner.getSelectedItemPosition(); boolean autoUpdateChecked = autoUpdate.isChecked();

Editor editor = prefs.edit();

editor.putBoolean(PREF_AUTO_UPDATE, autoUpdateChecked); editor.putInt(PREF_UPDATE_FREQ, updateIndex); editor.putInt(PREF_MIN_MAG, minMagIndex); editor.commit();

9. That completes the Preferences Activity. Make it accessible in the application by adding it to the manifest:

<activity android:name=".Preferences"

android:label="Earthquake Preferences"> </activity>

10. Now return to the Earthquake Activity, and add support for the new Shared Preferences file and a Menu Item to display the Preferences Activity. Start by adding the new Menu Item. Extend the onCreateOptionsMenu method to include a new item that opens the Preferences Activity:

static final private int MENU_PREFERENCES = Menu.FIRST+1; @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu);

menu.add(0, MENU_UPDATE, Menu.NONE, R.string.menu_update); menu.add(0, MENU_PREFERENCES, Menu.NONE, R.string.menu_preferences);

return true;

11. Modify the onOptionsltemSelected method to display the Preferences Activity when the new Menu Item is selected. Create an explicit Intent and pass it in to the startActivityForResult method. This will launch the Preferences screen and alert the Earthquake class when the preferences are saved through the onActivityResult handler:

private static final int SHOW_PREFERENCES = 1; public boolean onOptionsItemSelected(MenuItem item) {


switch (item.getItemId()) { case (MENU_UPDATE): { refreshEarthquakes(); return true;


Intent i = new Intent(this, Preferences.class); FIGURE 6-1 startActivityForResult(i, SHOW_PREFERENCES); return true;

return false;

12. Launch your application and select Preferences from the Activity menu. The Preferences Activity should be displayed as shown in Figure 6-1.

13. All that's left is to apply the preferences to the earthquake functionality. Implementing the automatic updates will be left until Chapter 9, when you'll learn to use Services and background threads. For now you can put the framework in place and apply the magnitude filter.


Earthquake ftn fa rfn r er,

HUtD 'Jrfili i

UpdSts fJequinty

[ 10 minutes


Start by creating a new updateFromPreferences method that reads the Shared Preference values and creates instance variables for each of them:

int minimumMagnitude = 0; boolean autoUpdate = false; int updateFreq = 0;

private void updateFromPreferences() {

Context context = getApplicationContext(); SharedPreferences prefs =


int minMagIndex = prefs.getInt(Preferences.PREF_MIN_MAG, 0); if (minMaglndex < 0) minMaglndex = 0;

int freqIndex = prefs.getInt(Preferences.PREF_UPDATE_FREQ, 0); if (freqIndex < 0) freqIndex = 0;

autoUpdate = prefs.getBoolean(Preferences.PREF_AUTO_UPDATE, false);

Resources r = getResources();

// Get the option values from the arrays.

int[] minMagValues = r.getIntArray(R.array.magnitude);

int[] freqValues = r.getIntArray(R.array.update_freq_values);

// Convert the values to ints. minimumMagnitude = minMagValues[minMagIndex]; updateFreq = freqValues[freqIndex];

14. Apply the magnitude filter by updating the addNewQuake method to check a new earthquake's magnitude before adding it to the list:

private void addNewQuake(Quake _quake) {

if (_quake.getMagnitude() > minimumMagnitude) { // Add the new quake to our list of earthquakes. earthquakes.add(_quake);

// Notify the array adapter of a change. aa.notifyDataSetChanged();

15. Override the onActivityResult handler to call updateFromPreferences and refresh the earthquakes whenever the Preferences Activity saves changes:

©Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data);

if (requestCode == SHOW_PREFERENCES)

if (resultCode == Activity.RESULT_OK) { updateFromPreferences();


16. Finally, call updateFromPreferences in onCreate (before the call to refreshEarthquakes) to ensure the preferences are applied when the Activity starts:

©Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedlnstanceState); setContentView(R.layout.main);

earthquakeListView = (ListView)this.findViewByld(; earthquakeListView.setOnItemClickListener(new OnItemClickListener() { ©Override public void onItemClick(AdapterView _av, View _v, int _index, long arg3) { selectedQuake = earthquakes.get(_index); showDialog(QUAKE_DIALOG);

int layoutID = android.R.layout.simple_list_item_1;

aa = new ArrayAdapter<Quake>(this, layoutID , earthquakes);


updateFromPreferences(); refreshEarthquakes();

All code snippets in this example are part of the Chapter 6 Earthquake project, available for download at

Mobile Apps Made Easy

Mobile Apps Made Easy

Quick start guide to skyrocket your offline and online business success with mobile apps. If you know anything about mobile devices, you’ve probably heard that famous phrase coined by one of the mobile device’s most prolific creators proclaiming that there’s an app for pretty much everything.

Get My Free Training Guide


  • Flambard
    How to add a spinner to preferences?
    6 years ago

Post a comment