Tuesday, November 23, 2010

How to use Preferences in Android App programming

This article is inspired from
Chapter 6 - Files, Saving State, and Preferences
Professional Android 2 Application Development
by Reto Meier
Wrox Press

The application has a main screen that will display the information gathered from the user by  Preferences menu. Options Menu will let the user go to the Preferences.
Therefore we will  use the Options Menu and PreferenceActivity,

Screens will be as follows:
Main Screen

Preferences


Preferences Activity:
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;

public class Preferences extends PreferenceActivity {

  public static final String CONTACT_NAME = "CONTACT_NAME";
  public static final String CONTACT_EMAIL = "CONTACT_EMAIL";
  public static final String PREF_GPS = "PREF_GPS";
  public static final String PREF_BEATS = "PREF_BEATS";
  public static final String PREF_MIN_VALUE="PREF_MIN_VALUE";
  SharedPreferences prefs;

  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);  
   addPreferencesFromResource(R.xml.userpreferences);   

  } 
}

Corresponding userpreferences.xml file will be:
<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
    <EditTextPreference  android:defaultValue="Owner"
        android:key="CONTACT_NAME"

       android:summary="Person to call in lock down situation"
        android:title="Contact Name" />
    <EditTextPreference android:key="CONTACT_EMAIL"
        android:summary="This email will be informed when lock down happens"
      android:defaultValue="tigrek@colorado.edu" android:title="Contact Email" />

    <CheckBoxPreference android:title="GPS on/off"
        android:defaultValue="true"
android:key="PREF_GPS" android:summary="Turn the GPS on" />

    <ListPreference android:key="PREF_BEATS"
        android:summary="Beats Length
will be fixed " android:dialogTitle="Choose Beat Size"

        android:entries="@array/beats"
android:defaultValue="4" android:title="Beats to Use"
android:entryValues="@array/beat_values" />

    <ListPreference android:key="PREF_MIN_VALUE"
        android:title="Minimum value"
android:summary="Select the minimum value to report"
android:entries="@array/value_options"
android:entryValues="@array/values"
        android:dialogTitle="Minimum
Value" android:defaultValue="3" />

</PreferenceScreen>


strings.xml will provide the strings

Arrays are in arrays.xml
<?xml version="1.0" encoding="utf-8"?>

<resources>
  <string-array name="beats">
    <item>Slow</item>
    <item>Medium</item>
    <item>Fast</item>
    <item>Very Fast</item>
  </string-array>
<string-array name="beat_values">
    <item>4</item>
    <item>8</item>
    <item>16</item>
    <item>32</item>
  </string-array>

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

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

</resources>



To use Preferences activity we have Preferences Option Menu In Main Activity.
We will cover how to use options menu in another article
 Of course you can call preferences from any point of your application:

Intent i = new Intent(this, Preferences.class);
startActivityForResult(i, SHOW_PREFERENCES);
 // assuming you know how to call another activity.

StartActivityForResult is used when we expect result from another activity. In this case we will read the user input from Preferences activity by the following code (in main activity):
@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();
        }
    }

updateFromPreferences()  is a custom code to take the inputs from prefs and store them  into variables to use  as desired. In our example I will display them in main screen.
/// variables defined global at the top
      String contactName;
      String contactEmail;
      boolean gpsOn;
      int beats;
      int minValue;

private void updateFromPreferences() {

        Context context = getApplicationContext();
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        contactName = prefs.getString(Preferences.CONTACT_NAME, "Seyit");
        contactEmail =prefs.getString(Preferences.CONTACT_EMAIL, "tigrek@colorado.edu");
        gpsOn = prefs.getBoolean(Preferences.PREF_GPS, false);
beats=Integer.parseInt(prefs.getString(Preferences.PREF_BEATS, "1"));
minValue=Integer.parseInt(prefs.getString(Preferences.PREF_MIN_VALUE,
"3"));
        // set the values to the main screen
        EditText contactField = (EditText) findViewById(R.id.textContact); 
        contactField.setText(contactName);
        EditText emailField =
(EditText) findViewById(R.id.textEmail);
        emailField.setText(contactEmail);
        CheckBox gpsCheck = (CheckBox)
findViewById(R.id.checkGPS);
        gpsCheck.setChecked(gpsOn);
        EditText beatsField = (EditText)
findViewById(R.id.textBeats);
beatsField.setText(String.valueOf(beats));
        EditText valueField = (EditText)
        findViewById(R.id.textValue);
valueField.setText(String.valueOf(minValue);
      }
System Settings from App

From the options menu "GPS Settings" will  go to the system settings.
By using  the following code it is possible
to go to System settings directly from your app.

startActivityForResult(new Intent( android.provider.Settings. ACTION_LOCATION_SOURCE_SETTINGS), 0);



email to : seyit.geen1400@gmail.com to receive the working example as zip file
References:
http://www.kaloer.com/android-preferences
http://developer.android.com
http://www.helloandroid.com/tutorials/calling-system-settings-android-app-gps-example