Android Tutorial PreferenceActivity tutorial

This tutorial explains how to use the new PreferenceActivity library. This library allows you to create the "standard" settings screen.

The settings screen is hosted in its own activity. As this is an external activity its declaration should be manually added to the manifest file.
I will take this opportunity to give some tips about manual modification of the manifest file which is sometimes required.

Editing AndroidManifest.xml (general overview)
As of Basic4android v1.8 it is no longer required to manually maintain the manifest file. Instead the manifest editor allows you to add extra elements as needed.
See this link for more information: http://www.b4x.com/forum/showthread.php?p=78136
For PreferenceActivity you should add the following code to the manifest editor:
B4X:
AddApplicationText(<activity android:name="anywheresoftware.b4a.objects.preferenceactivity"/>)
Back to PreferenceActivity

preference_1.png


* This image was taken on a Samsung Galaxy Tab device. On other devices the screen will look a bit different based on their default style.

PreferenceActivity library includes two main objects: PreferenceScreen and PreferenceManager.
PreferenceScreen is responsible for building the settings UI. PreferenceManager allows you to read the settings and also modify them by code.
Both these objects should usually be declared in Sub Process_Globals.
The settings are saved in a file in the internal files folder. File handling is done automatically. Note that when you reinstall an application (without uninstalling it) the files are kept so the settings will also be kept.

Each preference entry is stored as a key/value pair. The key is a string (case sensitive) and the value can be either a string or a boolean value.
Each entry must have a unique key.

Building the UI
In order to build the UI we start with a PreferenceScreen object and add entries to this object directly or to PreferenceCategory which can hold other entries.
In the above screenshot you can see a PreferenceScreen with two categories holding other entries.
Note that a PreferenceScreen can also hold secondary PreferenceScreens. In this case when the user presses on the secondary entry a new screen will appear with its entries.
There are three types of preference entries:
- Checkbox
- EditText - Opens an input dialog when the user presses on it.
- List - Open a list dialog when the user presses on it, allowing the user to select a single item.
The code that creates the above UI is:
B4X:
Sub CreatePreferenceScreen
    screen.Initialize("Settings", "")
    'create two categories
    Dim cat1, cat2 As PreferenceCategory
    cat1.Initialize("Category 1")
    cat1.AddCheckBox("check1", "Checkbox1", "This is Checkbox1", True)
    cat1.AddCheckBox("check2", "Checkbox2", "This is Checkbox2", False)
    cat1.AddEditText("edit1", "EditText1", "This is EditText1", "Hello!")
 
    cat2.Initialize("Category 2")
    cat2.AddList("list1", "List1", "This is List1", "Black", _
        Array As String("Black", "Red", "Green", "Blue"))
     
    'add the categories to the main screen
    screen.AddPreferenceCategory(cat1)
    screen.AddPreferenceCategory(cat2)
End Sub
The first string in the Add methods is the entry key followed by the title, summary and default value.
The default value is used if the key does not yet exist.

To show the preferences we use this code:
B4X:
Sub btn_Click
    StartActivity(screen.CreateIntent)
End Sub
Reading the settings
Reading the settings is done with PreferenceManager.
To retrieve the value of a specific key you should use Manager.GetString or Manager.GetBoolean with this key.
You can get a Map with all the stored keys and values by calling Manager.GetAll
If you want to only handle updated settings then you can call Manager.GetUpdatedKeys. This will return a List with the keys that were updated since the last call to this method.
Usually you will want to handle settings updated in Activity_Resume. Activity_Resume will be called right after Activity_Create when you start your program and also when the user closes the preferences screen.
Whether you want to handle all keys or just the updated keys depends on your application.

Tip:
The default values set in the PreferenceScreen.Add calls have no effect till the user actually sees the screen. It is recommended to explicitly set the default values if they do not already exist.
A simple way to do it is with code similar to:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        CreatePreferenceScreen
        If manager.GetAll.Size = 0 Then SetDefaults
    End If
End Sub

Sub SetDefaults
    'defaults are only set on the first run.
    manager.SetBoolean("check1", True)
    manager.SetBoolean("check2", False)
    manager.SetString("edit1", "Hello!")
    manager.SetString("list1", "Black")
End Sub
This way our code in Activity_Resume will work correctly whether it is the first time the program runs or after the user has closed the settings page.

The program is attached.
 

Attachments

  • PreferenceActivity.zip
    6.5 KB · Views: 943
Last edited:

corwin42

Expert
Licensed User
Longtime User
I don't see the error. Will try your code later to reproduce it.

Be aware that the AddIntent() implementation is very poor because not all information of the intent is passed. But as I can see you use similar code like in the example so it should work.
 

mitsusdev

Member
Licensed User
Longtime User
I don't see the error. Will try your code later to reproduce it.

Be aware that the AddIntent() implementation is very poor because not all information of the intent is passed. But as I can see you use similar code like in the example so it should work.

Thx a lot corwin42,
i'll wait your tests.

Regards
 

corwin42

Expert
Licensed User
Longtime User
I tried your code and it works fine here on a GB device and on a ICS emulator.

Have you tried to delete data for your app. As Erel said it looks like you have changed datatype for one setting and the app gets confused with different datatypes.
 

mitsusdev

Member
Licensed User
Longtime User
I tried your code and it works fine here on a GB device and on a ICS emulator.

Have you tried to delete data for your app. As Erel said it looks like you have changed datatype for one setting and the app gets confused with different datatypes.

Hi corwin42,
when you and Erel spoken of delete data for your app you mean to delete the application data after it is installed on the phone? Going to delete the data from application settings section?

If so I have tried many times, but when i click on settings button of my app...it crashed!:BangHead: ...but only on ICS smartphone and emulator!

...i don't know
 

mitsusdev

Member
Licensed User
Longtime User
Can you upload your project? Or the APK file?

HI Erel,
i can't upload/share project for now, because it would be unusable.

I can share a piece of my app...the piece that goes wrong when i click button that start preference Activity (..and then it crash on ICS).
The code is the same of mine.

Attached the piece of my app.

Thanks a lot
 

Attachments

  • test_activity.zip
    7.8 KB · Views: 384

mitsusdev

Member
Licensed User
Longtime User
The problem is in this line:
B4X:
manager.SetString("chktts", True)
You should use SetBoolean.

Thanks a lot Erel. Sorry for my oversight.

It work fine after apply your correction

Best Regards
 

tamadon

Active Member
Licensed User
Longtime User
It seems that while I can create two separate preference activities, the second call to manager2.GetAll.Size will return the first value manager1.GetAll.Size.

In the process global, I've declared manager1, manager2 individually.

Is it possible to have two separate PreferenceManager object?
 

elitistnot

Member
Licensed User
Longtime User
Event when user leaves setting menu

Is there an event for when the user exits the settings menu?

I want to capture that event and call a sub... anyway to do that?

Thanks.
 

EduardoElias

Well-Known Member
Licensed User
Longtime User
Hi there,

Please a little help, I have searched the forums but I am not having luck on solve this.

I have added the PreferenceManager and PreferenceScreen, it is working perfectly. I have followed the examples.

I have added a button on the activity and it shows up the PreferenceScreen and so on.

However the only thing I could not manage to work is to have the defauld android button to call the menu.

In activity_create i have added one Activity.AddMenuItem("config", "config")

Sub Config_Click
StartActivity(prefscreen.CreateIntent)
End Sub

I have added the following line on Manifest Editor:
AddApplicationText(<activity android:name="anywheresoftware.b4a.objects.preferenceactivity"/>)

I am using Android 4.0.4, b4a 2.02

How to make the default menu (3 dots) shows up for my app?

Thanks
 

EduardoElias

Well-Known Member
Licensed User
Longtime User
Yes, the standard menu button. I am suffering with the name conventions, even to ask and search. I am new on this platform.

I see on my ICS tablet, on the botton, few options: back, home, speaker volume. Somes apps makes a button appear that give access to the menu.

I dont know what is wrong since that menu button do not show up
 

EduardoElias

Well-Known Member
Licensed User
Longtime User
The menu button doesn't show when you add targetSdkVersion="14" or above to the manifest editor.

I have changed to 7 and it now is showing.

AddManifestText(
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="7"/>
<uses-permission android:name="android.permission.INTERNET" />
<supports-screens android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
AddApplicationText(<activity android:name="anywheresoftware.b4a.objects.preferenceactivity"/>)

What is the reason of that? Or guide me where to learn about that.

Thanks
 

SandroB4A

Member
Licensed User
Longtime User
Hi to all! this is my first post:sign0104:

My first app has four activities each with the same menu and I 'd like have a "setting button" in every menu.

Now I call the settings from one of this activity and all woks :). Of course I want to extend functionality to the others.

My question is: wich is the best strategy to obtain that?

I must recreate every time PreferenceManager and PreferenceScreen object? or (I suppose) I can do it once?

Probably it's an obvious question, so be patient...

P.S. I didn't see properties (colors, text...) for setting screen, probably match system colors, you know some escamotage for personalising the preference screen look?
 
Top