Android: preferences not being stored automatically - android

I'm trying to use preference screen. I'm following all steps from online tutorial (once I couldn't get it working, I found other tutorials, and steps seem to be fine). I get to preferences screen, edit values, return to calling activity (via hardware return button). In DDMS perspective FileExplorer shows package_name_preferences.xml file with preferences that should be stored. It contains:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="false">kg</string>
</map>
while I expect (data line only shown).
<string name="weight">kg</string>
Also, if I go change only 1 preference, the same value changes, not a new row is created. I'm just tempted to write my own preference classes that would store data in files or DB, but I know that preferences should work, it just doesn't save properly my stuff.
Edit
Tutorials used:
Main Tutorial
- Was using this as a base, simplified, as I needed only 3 listPreferences so far.
Another One - Used this one back when first installed android, so referred to this one for its section on preferences
Code: (Screen loads, so I'm not showing Manifest)
public class MyPrefs extends PreferenceActivity {
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
addPreferencesFromResource(R.xml.my_prefs);
}
}
my_prefs.xml
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Value Settings">
<ListPreference android:title="Distance"
android:summary="Metric (Kilometer) vs Imperial (Imperial)"
android:defaultValue="km"
android:key="#+id/distanceMesurement"
android:entries="#array/distance"
android:entryValues="#array/distance_values"/>
<ListPreference android:title="Weight"
android:summary="Metric (Kilogram) vs Imperial (Pound)"
android:defaultValue="kg"
android:key="#+id/weightMesurement"
android:entries="#array/weight"
android:entryValues="#array/weight_values"/>
</PreferenceCategory>
</PreferenceScreen>
calling MyPrefs from MainScreen
Intent i = new Intent(MainScreen.this, MyPrefs.class);
startActivity(i);
arrays.xml
<resources>
<string-array name="weight">
<item name="kg">Kilogram (kg)</item>
<item name="lb">Pound (lb)</item>
</string-array>
<string-array name="weight_values">
<item name="kg">kg</item>
<item name="lb">lb</item>
</string-array>
<string-array name="distance">
<item name="km">Kilometer (km)</item>
<item name="mi">Mile (mi)</item>
</string-array>
<string-array name="distance_values">
<item name="km">km</item>
<item name="mi">mi</item>
</string-array>
</resources>

Your key syntax is invalid. Use:
android:key="weight"

Related

How to set multiple default values in a MultiSelectListPreference?

I have preference.xml like this
<MultiSelectListPreference
android:key="store_select"
android:title="#string/setting_store_title"
android:summary="#string/setting_store_summary"
android:dialogTitle="#string/setting_store_dialog_title"
android:entries="#array/store_names"
android:entryValues="#array/stores"
android:defaultValue="#array/stores"
/>
with my two arrays:
<string-array name="stores">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
</string-array>
<string-array name="store_names">
<item>foodbasics</item>
<item>nofrills</item>
<item>metro</item>
<item>loblaws</item>
<item>sobeys</item>
</string-array>
I want the default behaviour to be all of the options selected, but currently nothing is selected by default. Am I doing something wrong?
To make all MultiSelectListPreference items selected (on) by default, then include the attribute defaultsValue for the Preference, e.g.
android:defaultValue="#array/stores"
If it's not working, then make sure that you clear the application data as this will only take effect the first time the application is run.
I think you forgot calling PreferenceManager.setDefaultValues(this, R.xml.preference, false);
in the onCreate() method of your mainActivity.
This method will read your preference.xml file and set the default values defined there. Setting the readAgain argument to false means this will only set the default values if this method has never been called in the past so you don't need to worry about overriding the user's settings each time your Activity is created.
I know I am late but may be my answer helps someone else in future...
set
android:defaultValue="#array/empty_array"
where empty_array is an empty array.
If you are adding MultiSelectListPreference programmatically then you can simply call multiSelectListPreference.setDefaultValue():
e.g.
val preference = MultiSelectListPreference(context)
preference.setDefaultValue(setOf("US, "CN"))

android preference change diplayed preferences in same PreferenceActivity

I have two preference xml files. The first one (pref2.xml) contains 2 preferences:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="key"
android:title="title"
android:defaultValue="false"
/>
<CheckBoxPreference
android:key="key2"
android:title="title"
android:defaultValue="false"
/>
</PreferenceScreen>
and the other one (pref1.xml) contains 1 preference:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="key"
android:title="title"
android:defaultValue="false"
/>
</PreferenceScreen>
in my preference activity I am trying to change them:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref1);
this.getPreferenceScreen().removeAll();
addPreferencesFromResource(R.xml.pref2);
final ListAdapter adapter = getPreferenceScreen().getRootAdapter();
Log.d("LOG", "size of sharedPreferences"+adapter.getCount()+"(should be 2)");
actually here i get the right output and everything is displayed correctly. But I want to change the displayed preferences concerning one preference. Therefore I implemented the OnSharedPreferenceChangeListener in the preference activity:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
super.onSharedPreferenceChanged(sharedPreferences, key);
//switch the widget type
if (key.equals("key")){
this.getPreferenceScreen().removeAll();
addPreferencesFromResource(R.xml.pref1);
final ListAdapter adapter = getPreferenceScreen().getRootAdapter();
Log.d("LOG", "size of sharedPreferences "+adapter.getCount()+" (should be 1)");
}
}
Well, the pref1 preferences are displayed correctly, but the output of
"size of sharedPreferences 2"
indicated that in the background there are still the old preferences applied. If i iterate over the listAdapter i get also the old preferences.
Any idea how I could solve this?
I found out that the listadapter is some how outdated. If I get the count of items via getPreferenceScreen().getPreferenceCount() I get the right amount. But how do I access these preferences ?
I'm fairly sure that problem lies with your having two preferences with a key of "key" even though they are on different screens. A preference is identified by its key and this needs to be unique to avoid conflicts. The listener only knows which preference is being changed from the key. I would change the keys to have unique values.
EDIT: Well, wasn't right :S
...
Okey, I finally found the solution. After changing the PreferenceScreen I need to bind manually the listView again:
getPreferenceScreen().bind((ListView)findViewById(android.R.id.list));

Leaving PreferenceActivity, calling Activity still reads old preference?

I feel I'm missing something obvious, but search took me to several different hits, all of which don't directly access my odd issue.
Have an app with a main activity and a preference activity. Add to that a 'preference' class, which simplifies reading and setting preferences. The main activity has an option menu to get to the preference activity:
Preferences class (included for relevance, same thing happens if I don't use this class to read settings).
public class Preferences
{
public static SharedPreferences getPrefs(Context context)
{
SharedPreferences retCont = PreferenceManager.getDefaultSharedPreferences(context);
return retCont;
}
/* Map Page: Show Satellite */
public static boolean getMapShowSatellite(Context context)
{
return Preferences.getPrefs(context).getBoolean(Preferences.getString(context, R.string.option_showSatellite), false);
}
public static void setMapShowSatellite(Context context, boolean newValue)
{
Editor prefsEditor = Preferences.getPrefs(context).edit();
prefsEditor.putBoolean(Preferences.getString(context, R.string.option_showSatellite), newValue);
prefsEditor.commit();
}
}
PreferencesActivity:
public class AppSettings extends PreferenceActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.app_preferences);
ListPreference stationType = (ListPreference)this.findPreference(this.getString(R.string.option_filterStationType));
stationType.setOnPreferenceChangeListener(this.stationOrderEnable());
}
[...]
}
The last two lines hook up an event to enable/disable other preferences based on one's selection. That works, as expected.
The simple main activity, and related functions:
public class MainMapScreen extends MapActivity
{
private void launchSettings()
{
Intent prefsIntent = new Intent(this.getApplicationContext(), AppSettings.class);
this.startActivity(prefsIntent);
}
#Override
protected void onResume()
{
super.onResume();
Preferences.getMapShowSatellite(); // <-- Returns previous value.
// Re-start the MyLocation Layer from tracking.
this._mapView.requestLayout();
}
[...]
}
Okay, so what happens is, let's say we run the app. At app load, the getMapShowSatellite() returns True. Go into the PreferenceActivity, and change that option to False. Exit the PreferenceActivity by hitting the Back button. At this time, the main activity's onResume() is called. Getting the getMapShowSatellite() at this point returns the previous setting of True. Exiting and relaunching the app will then finally return the False expected.
I'm not calling .commit() manually - and don't think I need to, sicne the setting IS saving, I'm just not getting update values.
What'm I missing? :)
--Fox.
Edit 2: Small update. I thought the issue may be the static calls - so temporarily I changed over my Preferences class (above) to be a instantiated class, no more static. I also added the following code to my onResume() call in the main activity:
//Try reloading preferences?
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
String test = sp.getString(Preferences.OPTION_FILTERSTATIONTYPE, "---");
Log.e("BMMaps", test);
What is logged at this point, from leaving the PreferenceActivity, is the old setting. Manually reading the preferences file shows me that the .xml file is getting updated with the user's new setting.
Since it's not obvious, I am hooked into Google's Maps API. Because of this, I had to specify two ifferent processes - one for the Main activity (this one) and another for an activity not related to this issue. All other activities, including the PreferencesActivity have no specified android:process="" in their definition.
Edit 3:
As requested, here's the data preferences file:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="com.tsqmadness.bmmaps.filterStationType">V-?</string>
<boolean name="com.tsqmadness.bmmaps.deviceHasLocation" value="false" />
</map>
And here is the Preference storage XML file:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Map Options">
<CheckBoxPreference android:key="com.tsqmadness.bmmaps.mapShowSatellite" android:order="1" android:summary="Whether or not to show satellite imagery on the map." android:summaryOff="Standard road map will be shown." android:summaryOn="Satellite imagery will be show." android:title="Show Satellite Layer?" />
<CheckBoxPreference android:key="com.tsqmadness.bmmaps.mapShowScale" android:order="2" android:summary="Whether or not to show the distance bar on the map." android:summaryOff="The distance bar will not be shown on the map." android:summaryOn="The distance bar will be shown on the map." android:title="Show Map Scale?" />
<CheckBoxPreference android:defaultValue="false" android:key="com.tsqmadness.bmmaps.useMetric" android:order="3" android:summary="Whether to use Metric os SI values." android:summaryOff="SI units (mi/ft) will be shown." android:summaryOn="Metric units (km/m) will be shown." android:title="Use Metric?" />
<ListPreference android:dialogTitle="Station Load Delay" android:entries="#array/static_listDelayDisplay" android:entryValues="#array/static_listDelayValues" android:key="com.tsqmadness.bmmaps.mapBMDelay" android:negativeButtonText="Cancel" android:order="4" android:positiveButtonText="Save" android:summary="The delay after map panning before staions are loaded." android:title="Delay Before Loading" />
</PreferenceCategory>
<PreferenceCategory android:title="Control Station Filter">
<ListPreference android:dialogTitle="Station Type" android:entries="#array/static_listStationTypeDisplay" android:entryValues="#array/static_listStationTypeValues" android:key="com.tsqmadness.bmmaps.filterStationType" android:negativeButtonText="Cancel" android:positiveButtonText="Save" android:summary="The station type to filter on." android:title="Station Type" android:order="1" />
<ListPreference android:dialogTitle="Select Station Order" android:entries="#array/static_listStationHOrderDisplay" android:entryValues="#array/static_listStationHOrderValues" android:key="com.tsqmadness.bmmaps.filterStationOrder" android:negativeButtonText="Cancel" android:positiveButtonText="Save" android:summary="Station Order to filter by." android:title="Station Order" android:order="2" />
<ListPreference android:dialogTitle="Select Station Stability" android:entries="#array/static_listStationStabilityDisplay" android:entryValues="#array/static_listStationStabilityValues" android:key="com.tsqmadness.bmmaps.filterStationStability" android:negativeButtonText="Cancel" android:positiveButtonText="Save" android:summary="Station stability to filter by." android:title="Station Stability" android:order="3" />
<CheckBoxPreference android:key="com.tsqmadness.bmmaps.filterNonPub" android:summaryOff="Non-Publishable stations will not be shown." android:defaultValue="false" android:summaryOn="Non-Publishable stations will be shown on the map." android:order="4" android:title="Show Non-Publishable" />
</PreferenceCategory>
<Preference android:key="temp" android:title="Test" android:summary="Test Item">
<intent android:targetClass="com.tsqmadness.bmmaps.activities.MainMapScreen" android:targetPackage="com.tsqmadness.bmmaps" />
</Preference>
</PreferenceScreen>
When changing the filterStationType parameter, and hitting the back button out of PreferenceActivity changes the preferences file from the above from V-? to H-?, as it should. However, reading the value from the SharedPreferences on the main activity still gives the V-?, until app restart. Ah, also, I have a OnPreferenceChangeListnener() in the PreferenceActivity, and that is called when the value changes.
Final Edit: Apparently, it's the use of named android:process for the given activity. This is needed for Google maps API to allow two separate MapActivitys in the same app use different settings. If the PreferenceActivity is moved to the same named-process, then the code above, reading the setting in the onResume() returns the correct value.
Since everything checks out, my guess is that you have a typo, or incorrect or undefined, key in your PreferenceActivity's app_preferences.xml file for the key R.string.option_showSatellite (whatever that string is). This would result in two keys with [unbeknownst to you] different names that you think point to the same value. Really, the prefs activity is using one key and your Preference class is using the other -- resulting in two different keys and two different values.
Double check your keys. Make sure you are not also using the literal "R.string.options_showSatellite" as the key in the xml file, but rather, the actual string. If you want to use the localized version then #string/options_showSatellite would work for the key. However, keys need not be localized.
If you're curious, this can be double checked by opening the preference file that is created by the preference manager in your app's data directory in a standard text editor.
onResume you have to get a fresh reference to SharedPreferences, otherwise you're just using an object that is already in memory (and has your old values)
EDIT:
Rather than down-voting answers that you don't understand, why not ask for clarification instead?
What I mean is that you should pull your Prefs the correct way (rather than how you're doing it)...
SharedPreferences sp = getSharedPreferences(getPackageName(), MODE_PRIVATE);
And then see what happens.

PreferenceActivity error: doesn't show selected option after close Activity

The value is saved well in SharedPreference when i push it , but it doesn't show when i open another time the PreferenceActivity. It runs if i don't put the android:entryValues , but i can't use it cause there is some difference using distinct languages in order to see what's the value of the prefference.
¿Any idea of what can i do?
Thanks for reading.
code:
the PreferencesMenu activity:
public class PreferencesMenu extends PreferenceActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setDefaultKeyMode(MODE_PRIVATE);
addPreferencesFromResource(R.layout.preferences);
getPreferenceManager().setSharedPreferencesName("Gat_Preferences");
}
}
some of strings.xml:
<string-array name="menu_preference_general_order_array">
<item>Default</item>
<item>Alphabetical</item>
</string-array>
<string-array name="menu_preference_general_order_values">
<item>default</item>
<item>alphabetical</item>
</string-array>
preferences.xml layout:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
...
<PreferenceCategory android:title="#string/menu_preference_general">
<ListPreference
android:key="list_order"
android:persistent="true"
android:title="#string/menu_preference_general_order_title"
android:summary="#string/menu_preference_general_order_description"
android:entries="#array/menu_preference_general_order_array"
android:entryValues="#array/menu_preference_general_order_values"/>
</PreferenceCategory>
</PreferenceScreen>
mod :
I use android 2.1 , and i can't use the new fragments preference.
You need to tell the preference API what file name you want to use before loading everything up.
Instead of this:
addPreferencesFromResource(R.layout.preferences);
getPreferenceManager().setSharedPreferencesName("Gat_Preferences");
Do this:
getPreferenceManager().setSharedPreferencesName("Gat_Preferences");
addPreferencesFromResource(R.layout.preferences);
On a sidenote, don't use R.layout.preferences. You should use R.xml.preferences, putting the file under /res/xml and not under /res/layout. It does work your way, but it's not guaranteed to work in all API versions, since it's not the default way of working with preferences XML files.
Your preferences.xml should be in res/xml.
Also, you should assign the default value
<ListPreference
android:key="list_order"
android:persistent="true"
android:title="#string/menu_preference_general_order_title"
android:summary="#string/menu_preference_general_order_description"
android:entries="#array/menu_preference_general_order_array"
android:entryValues="#array/menu_preference_general_order_values"
android:defaultValue="default"
/>

How-to init a ListPreference to one of its values

I'm trying to set a defaultValue to a ListPreference item.
Here is an sample of my preference.xml file:
<ListPreference android:key="notification_delay"
android:title="#string/settings_push_delay"
android:entries="#array/settings_push_delay_human_value"
android:entryValues="#array/settings_push_delay_phone_value"
android:defaultValue="????">
</ListPreference>
The two arrays:
<string-array name="settings_push_delay_human_value">
<item>every 5 minutes</item>
<item>every 10 minutes</item>
<item>every 15 minutes</item>
</string-array>
<string-array
name="settings_push_delay_phone_value">
<item>300</item>
<item>600</item>
<item>900</item>
</string-array>
When i go into the preference activity, no item of the ListPreference is selected. I've tried to set an int value like 1 in the "android:defaultValue" fied to select "10 minutes" but it does not work.
<ListPreference android:key="notification_delay"
android:title="#string/settings_push_delay"
android:entries="#array/settings_push_delay_human_value"
android:entryValues="#array/settings_push_delay_phone_value"
android:defaultValue="1">
</ListPreference>
Any Idea?
You need to specify the value. So to get the first entry selected by default specify defaultValue="300" in your example.
Happened to be in same situation. Specifying a consistent default value. But graphically was not selected. I cleared the application data. And then it worked as expected.
So a clear may be useful at dev time when adding new XxxPreference items.
In addition to Sven's answer, you have to call the setDefaultValues() method in the starting activity. This will set once all default values.
public class MainActivity extends Activity {
protected void onCreate(final Bundle savedInstanceState) {
// Set all default values once for this application
// This must be done in the 'Main' first activity
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
...
}
}
If it is a valid value from the list, then re-install the app. It will work.

Categories

Resources