Settings Screen Using PreferenceManager

In this blog post, I would like to explain how to code Settings Screen using PreferenceManager.

In this tutorial let’s learn to create a settings screen for an app with Notiifcation.

First, create a folder in res folder named – xml.

Second, create an xml file inside the xml folder named – user_setting.xml, and the following lines.


<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 android:title="Settings">

</PreferenceScreen>

xmlfolder

Now, ill explain one by one.

1) For adding EditText inside the screen, use this code.


<EditTextPreference
android:key="username"
android:summary="Change User Name"
android:title="USERNAME" />

2) For adding CheckBox inside the screen, use this code.


<CheckBoxPreference
 android:key="isAutoStartEnabled"
 android:title="Start on boot"
 android:summary="Start Notifications on boot"
 android:defaultValue="true" />

3) For adding Button inside the screen, use this code.

<Preference android:title="Feedback"
 android:key="button"
 android:summary="Email us"/>

4) For dividing into groups, use this code.

<PreferenceCategory
 android:title="GENERAL">

</PreferenceCategory>

5) For adding listview inside the screen, use this code.

<ListPreference
 android:defaultValue="3"
 android:entries="@array/Noti_timing"
 android:entryValues="@array/Noti_timing_values"
 android:key="listTime"
 android:summary="Set Notification Frequency"
 android:title="Notification Timings" />

For List Preference to work properly, we need to two arrays, i.e., one for displaying values and another for actual values to pass. Here in the example, i used frequency for notification, were user can select their prefer interval.

In res/values/arrays/xml file

<string-array name="Noti_timing">// just to display values on the screen
 <item name="1">Once every 1 hour</item>
 <item name="2">Once every 2 hour</item>
 <item name="3">Once every 3 hour</item>
 <item name="4">Once every 4 hour</item>
 </string-array>
 <string-array name="Noti_timing_values">// actual values passes from here
 <item name="1">1</item>
 <item name="3">2</item>
 <item name="3">3</item>
 <item name="4">4</item>
 </string-array>

Third, the complete user_setting.xml code is

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
 android:title="Settings">

 <PreferenceCategory
 android:title="GENERAL">

 <EditTextPreference
 android:key="username"
 android:summary="Change User Name"
 android:title="USERNAME" /> 

 <CheckBoxPreference
 android:key="NotiOnOff"
 android:title="Notifications on/off"
 android:summary="Notification to remind you - ON"
 android:defaultValue="true"
 />
 <CheckBoxPreference
 android:key="isAutoStartEnabled"
 android:dependency="NotiOnOff"
 android:title="Start on boot"
 android:summary="Start Notifications on boot"
 android:defaultValue="true"
 />
 <CheckBoxPreference
 android:key="VibrateOnOff"
 android:dependency="NotiOnOff"
 android:title="Vibration on/off"
 android:summary="Vibration On"
 android:defaultValue="true"
 />
 <CheckBoxPreference
 android:key="LightOnOff"
 android:dependency="NotiOnOff"
 android:title="LED on/off"
 android:summary="LED On"
 android:defaultValue="true"
 />
 <CheckBoxPreference
 android:key="SoundOnOff"
 android:dependency="NotiOnOff"
 android:title="Default Sound on/off"
 android:summary="Sound On"
 android:defaultValue="true"
 />
<ListPreference
 android:defaultValue="3"
 android:dependency="NotiOnOff"
 android:entries="@array/Noti_timing"
 android:entryValues="@array/Noti_timing_values"
 android:key="buttonTime"
 android:summary="Set Notification Frequency"
 android:title="Notification Timings" />
</PreferenceCategory>

<PreferenceCategory
 android:title="OTHER">

 <Preference android:title="Feedback"
 android:key="buttonemail"
 android:summary="Email us"/>

 <Preference
 android:key="buttonSuggest"
 android:summary="via Social Network&apos;s App"
 android:title="Share with friends" />

 <Preference android:title="Rate Us"
 android:key="buttonrate"
 android:summary="Google PlayStore"/>

 <Preference android:title="More from Developer"
 android:key="buttonplay"
 android:summary="Google PlayStore"/>

 <Preference android:title="About Our App"
 android:key="about"
 android:summary="version and date">
 <intent android:action="com.example.preferencemanager.WebView"/>
 </Preference>

 </PreferenceCategory>

 </PreferenceScreen>

In the above xml file, i have separated settings into two groups.
i) General settings – for user notification settings
ii) Others – for promoting the app, rate-us, feedback, more from developer and about the app.

Fourth, In the MainActivity.java, add the following code.

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.net.Uri;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;

public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);

 // Display the fragment as the main content.
 if (savedInstanceState == null)
 getFragmentManager().beginTransaction()
 .add(android.R.id.content, new PrefFragment()).commit();
 }

 public static class PrefFragment extends PreferenceFragment implements
 OnSharedPreferenceChangeListener {
 Context cont;
 Preference cbp1, cbp2, cbp3, cbp4, cbp5,list_time, edt_UserName, button_Rate, button_Play,buttonSuggest, button_Email, verison_No;
 SharedPreferences prefs;

 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);

 cont = getActivity();
 prefs = PreferenceManager.getDefaultSharedPreferences(cont);
 addPreferencesFromResource(R.xml.user_setting);
 button_Rate = (Preference) findPreference("buttonrate");
 button_Play = (Preference) findPreference("buttonplay");
 buttonsuggest = (Preference) findPreference("buttonsuggest");
 button_Email = (Preference) findPreference("buttonemail");
 verison_No = (Preference) findPreference("about");
 edt_UserName = (Preference) findPreference("username");
 cbp1 = (Preference) findPreference("NotiOnOff");
 cbp2 = (Preference) findPreference("VibrateOnOff");
 cbp3 = (Preference) findPreference("LightOnOff");
 cbp4 = (Preference) findPreference("SoundOnOff");
 cbp5 = (Preference) findPreference("isAutoStartEnabled");
 list_time = (Preference) findPreference("buttonTime");

 button_Email
 .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
 @Override
 public boolean onPreferenceClick(Preference arg0) {
 // code for what you want it to do

 String to = "xyz@gmail.com";
 Intent email = new Intent(Intent.ACTION_SEND);
 email.putExtra(Intent.EXTRA_EMAIL,
 new String[] { to });
 email.putExtra(Intent.EXTRA_SUBJECT, "FeedBack");
 email.putExtra(Intent.EXTRA_TEXT, " ");

 // we need setType to prompts only email clients.
 email.setType("message/rfc822");

 startActivity(Intent.createChooser(email,
 "Choose an Email client :"));

 return true;
 }
 });
 buttonsuggest
 .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
 @Override
 public boolean onPreferenceClick(Preference arg0) {
// Please read this <a title="Share this application with your friends on settings screen via social network" href="http://www.geeks.gallery/share-this-application-with-your-friends-on-settings-screen-via-social-network/" target="_blank">blog</a>
 return true;
 }
 });
 button_Play
 .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
 @Override
 public boolean onPreferenceClick(Preference arg0) {
 // code for what you want it to do

 // final String appPackageName = cont.getPackageName();</pre>
 // getPackageName() from Context or Activity

 try {
 startActivity(new Intent(Intent.ACTION_VIEW,
 Uri.parse("your market link here"))); // example
 // "market://search?q=clixoo%20solutions"
 } catch (android.content.ActivityNotFoundException anfe) {
 startActivity(new Intent(Intent.ACTION_VIEW,
 Uri.parse(""))); // example
 // "https://play.google.com/store/search?q=clixoo%20solutions&hl=en"
 }

 return true;
 }
 });
 button_Rate
 .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
 @Override
 public boolean onPreferenceClick(Preference arg0) {
 // code for what you want it to do

 final String appPackageName = cont.getPackageName();
 try {
 startActivity(new Intent(Intent.ACTION_VIEW,
 Uri.parse("market://details?id="
 + appPackageName)));
 } catch (android.content.ActivityNotFoundException anfe) {
 startActivity(new Intent(
 Intent.ACTION_VIEW,
 Uri.parse("http://play.google.com/store/apps/details?id="
 + appPackageName)));
 }

 return true;
 }
 });
 }

//call this method to read a string value from a preference with a parameter context and key - id (for example, to get username from EditTextPreference in this code, call Read(cont, "username");

public static String Read(Context context, final String key) {
 SharedPreferences pref = PreferenceManager
 .getDefaultSharedPreferences(context);
 return pref.getString(key, "");
 }

//call this method to write a string value to change the preference with a parameter context and key - id (for example, to change username from EditTextPreference in this code, call Write(cont, "geeks.gallery");

public static void Write(Context context, final String key,
 final String value) {
 SharedPreferences settings = PreferenceManager
 .getDefaultSharedPreferences(context);
 SharedPreferences.Editor editor = settings.edit();
 editor.putString(key, value);
 editor.commit();
 }

//call this method to read a boolean value from a preference with a parameter context and key - id and a default value(for example, to get sound on or off in this code, call ReadBoolean(cont, "SoundOnOff", true);

public static boolean ReadBoolean(Context context, final String key,
 final boolean defaultValue) {
 SharedPreferences settings = PreferenceManager
 .getDefaultSharedPreferences(context);
 return settings.getBoolean(key, defaultValue);
 }

//call this method to write or change a boolean value to a preference with a parameter context and key - id and a boolean value to change(for example, to change sound on or off in this code, call WriteBoolean(cont, "SoundOnOff", false);

public static void WriteBoolean(Context context, final String key,
 final boolean value) {
 SharedPreferences settings = PreferenceManager
 .getDefaultSharedPreferences(context);
 SharedPreferences.Editor editor = settings.edit();
 editor.putBoolean(key, value);
 editor.commit();
 }

// Now to get the value from the ListPreference, you can either choose Read Method from above or use setOnPreferenceChangeListerner, if you cant to do any extras on changing the preference

list_time
 .setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {

 @Override
 public boolean onPreferenceChange(
 Preference preference, Object newValue) {
 // TODO Auto-generated method stub

 int newVal = Integer.parseInt((String) newValue);// here i'm converting newValue from Object to String and in my case im type casting to int value again.

//for boolean value u can do like this.(change list_time on above to cbp2 and use below code to work properly)
//if ((Boolean) newValue) {
//cbp2.setSummary("Vibration On");
// } else {
// cbp2.setSummary("Vibration Off");
// }

  return true;
 }
 });
}

Your AndroidManifest.xml should like this.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.preferencemanager"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
             android:name=".WebView"
             android:label="@string/app_name">
        </activity>
    </application>

</manifest>

Few Tips to remember:

1) Here i’m creating Activity and transaction to PreferenceFragment, because PreferenceActivity is currently drepreciated.

2) As id’s in xml, preference uses android:key to find the widget.

3) Title is used to define what it is and Summary is used to define currently what it does.

4) You can also enable or disable each widgets by using setEnabled() boolean function.

5) If you use my code, you should notify that while disabling Notification, all of its sub-widgets gets disabled, i.e Sound, Vibrate, LED widgets. I used android:dependency=”NotiOnOff” to access this.

6) To use Intent from setting screen, take a deep look on user_setting.xml file at Line On: 64. I’m redirecting to WebView Activity.

7) For buttonSuggest, i have created another blog for this, so please visit this blog post.

8) Everytime when a value has been changed in the screen, No-Need to call Write or WriteBoolean method. This code snippet is to change the preference values outside the preference screen, i.e., from another activity.

ScreenShot:
Screenshot_2014-09-29-18-11-53[1]
Screenshot_2014-09-29-18-10-06[1]

Congrats, you have sucessfully created Settings Screen Using PreferenceManager in Android.
Hope this helpful. Your valuable comments are always welcomed. It will help to improve my post and understanding.

 

I have added another content for this blog – share with friends option via social network. Please visit this blog.

 
Download Source Code from here.

durga chiranjeevi

durga chiranjeevi

I'm currently working as Android developer at Energy Alternatives India. Interested in Application and Game development.
durga chiranjeevi
Comments
  1. Ahriman

Leave a Reply

Your email address will not be published. Required fields are marked *