Add link to Preferences? - android

I have preferences in an Android Live wallpaper app as below. (These are checkboxes). I want to add a link to a Facebook page to this list. Looking at Android PreferenceCategory on the net, I don't see anything like "LinkPreference" or "ButtonPreference", but then again, a link or button isn't really a preference, so maybe I'm trying to fit a square peg in a round hole. Is this possible and if so, how?
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
android:title="#string/livewallpaper_settings">
<PreferenceCategory android:title="#string/livewallpaper_settings" >
<CheckBoxPreference
android:defaultValue="true"
android:key="showred"
android:summary="Display red."
android:title="Display red" />
<CheckBoxPreference
android:defaultValue="true"
android:key="showgreen"
android:summary="Display green."
android:title="Display green" />
</PreferenceCategory>
</PreferenceScreen>
This question has been asked before:
Android Add Link to a preference activity - how?
but not answered.
[Edit]
So now have the code below. It does go to Facebook, but only after first clicking on one of the checkbox preferences.
In livewallpaper_settings.xml:
<PreferenceCategory android:title="#string/livewallpaper_settings" >
<Preference
android:key="facebook"
android:summary="#string/facebook"
android:title="#string/facebook" />
</PreferenceCategory>
LiveWallpaperSettings.java:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
Log.d("LiveWallpaperSettings.onSharedPreferenceChanged()", "key: " + key);
final Preference mypref = (Preference) findPreference("facebook");
mypref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference arg0) {
Log.d("LiveWallpaperSettings", "mypref: " + mypref.getKey());
if (mypref.getKey().equals("facebook")) {
Log.d("LiveWallpaperSettings", "LINK TO FACEBOOK");
openWebURL("http://www.facebook.com");
return false;
}
return false;
} });
return;
}
public void openWebURL( String inURL ) {
Log.d("openWebURL", inURL);
Intent browse = new Intent( Intent.ACTION_VIEW , Uri.parse( inURL ) );
startActivity( browse );
}

How about an EditTextPreference? You can use the same attributes as an EditText in your EditTextPreference so you can restrict the input to a single line and display the correct IME for email input etc.

Related

How are changes in the Preference ie Checkbox Preference , List Preference etc.. saved in the Shared Preference?

Okay so I'm trying to make sense of how Shared Preference works with Preference.
Below is part of an app that works, but I do not understand how it works for the part of Shared Preference.
I have a UserPrefActivity.java containing the following code
public class UserPrefActivity extends PreferenceActivity {
//a preference value change listener that updates the preference summary
//to reflect its new value
private static Preference.OnPreferenceChangeListener
sBindPreferenceSummaryToValueListerner = new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
//gets string value of object
String value = newValue.toString();
Log.e("in sBind Listener", value);
//if the preference is a list preference, get the value at a given index
if (preference instanceof ListPreference) {
//for list preference look up the correct display value
//in the preference entries array
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(value);
//set the summary to reflect the new value
preference.setSummary(index >= 0 ? listPreference.getEntries()[index] : null);
} else {
//set summary to only value
preference.setSummary(value);
}
return true;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//call the deprecated method to load the preference screen
addPreferencesFromResource(R.xml.user_pref);
//get default Shared preference from preference screen
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
Preference saveNumPizza = findPreference("saveNumPizza");
//set the preference change listener to saveNumPizza
saveNumPizza.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListerner);
sBindPreferenceSummaryToValueListerner.onPreferenceChange(saveNumPizza,
PreferenceManager
.getDefaultSharedPreferences(this)
.getString(saveNumPizza.getKey(), ""));
}
}
In the MainActivity.java, I have the following as part of a bigger piece of code
//gets the default shared preference instance and assign to sharedPrefs for enabled save
// data
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences
(MainActivity.this);
//checks if save order status is true
if (sharedPrefs.getBoolean("saveOrder", false)) {
//do stuff..
}
I have the following UserPref.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:defaultValue="false"
android:key="saveOrder"
android:summary="for quick loading of favourite order"
android:title="Enable Saving Order"/>
<PreferenceCategory android:title="ORDER HISTORY">
<CheckBoxPreference
android:defaultValue="false"
android:key="keepHistory"
android:summary="of pizza orders"
android:title="Keep History"/>
<ListPreference
android:defaultValue="3"
android:dialogTitle="Choose how many to save"
android:entries="#array/number_of_pizza"
android:entryValues="#array/number_of_pizza_values"
android:summary="3 pizza orders"
android:key="saveNumPizza"
android:title="Number of Orders"/>
</PreferenceCategory>
</PreferenceScreen>
I know that in the UserPrefsActivity, I believe in the PreferenceManager.getDefaultSharedPreferences(this) call, the shared preferences is created and obtained if it does not exist, if it does its just obtained.
From what I've noticed with the app, is that on first launch when I get to the settings and launch the UserPrefActivity via intent, the shared preference of the UserPrefActivity is created, containing only the saveNumPizza key. However the minute I click on the other preferences (Checkbox preference) when I look at the shared preference file, I immediately see that the saveOrder key and keepHistory key are automatically saved.
I would just like to know how this automatic saving is exactly done since I am not using an editor to save it to the shared preference, nor am I calling apply or commit.
Thank you,

Adding a TextView inside a PreferenceScreen's Preference

In this preferenceScreen the user unlinks the device from his account. At the moment I just have it as Unlink device, once the user clicks it, the unlinking happens.
But I would like to add a piece text like this:
Joe Foo's Device (joefoo#gmail.com) - Unlink Device
Hoe would I do this? I also need to add the user name dynamically from settingsActivity.
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<Preference android:title="#string/pref_title_advanced_unlink" >
<TextView somehow must be in here
android:id="#id/user_name_and_email" />
<intent android:action="android.intent.action.VIEW"
android:targetPackage="com.example.tvrplayer"
android:targetClass="com.example.tvrplayer.UnlinkActivity"
android.setflags="FLAG_ACTIVITY_CLEAR_TOP"/>
</Preference>
</PreferenceScreen>
preferences.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:key="pref_title_advanced"
android:title="Advanced" >
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_title_advanced_link"
android:title="Link Device" />
</PreferenceCategory>
</PreferenceScreen>
PrefsActivity.java
private SharedPreferences mPreferences;
private SharedPreferences.OnSharedPreferenceChangeListener mPrefListener;
private CheckBoxPreference mCheckBoxPref;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
mCheckBoxPref = (CheckBoxPreference) getPreferenceScreen().findPreference(
"pref_title_advanced_link");
/*
* set initial summary as you desire. For example, userIdCurrent can be:
* "No Devices linked."
*/
mCheckBoxPref.setSummary(userIdCurrent);
mPrefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs,
String key) {
if (key.equals("pref_title_advanced_link")) {
/*
* set post-click summary as you desire. For example,
* userIdPost can be:
* "Joe Foo's Device (joefoo#gmail.com)".
*/
mCheckBoxPref.setSummary(userIdPost);
}
}
};
mPreferences.registerOnSharedPreferenceChangeListener(mPrefListener);
}
Preferences have a subtitle called summary. Give your preference a key, then you can use findPreference(CharSequence key) in your PreferenceFragment to get a reference to your preference object, sort of like calling findViewById to get references to Views. Then call setSummary(int) or setSummary(CharSequence) on the preference object.
Alternatively, you could do something entirely more complex by providing a custom layout for your preference objects and/or subclass Preference and implement some custom data binding. But I think the above should do what you want.

Android SharedPreferences How is it mean to be used?

I am struggling to restore the default values I specified in the preferences.xml, Here is my code:
Preference reset = findPreference(res.getString(R.string.DEFAULT_PREFS));
reset.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference p) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(Preferences.this);
sp.edit().clear().commit();
PreferenceManager.setDefaultValues(Preferences.this, R.layout.preferences, true);
return true;
}
});
This code is my understanding of the android's developers reference for the function setDefaultValues(context, resId, readAgain):
Parameters
context The context of the shared preferences.
resId The resource ID of the preference hierarchy XML file.
readAgain Whether to re-read the default values.
Note: this will NOT reset preferences back to their default values.
For that functionality, use getDefaultSharedPreferences(Context)
and clear it followed by a call to this method with
this parameter set to true.
Well, it does not work, the preferences values are the same after this code is executed.
Then I looked into the SharedPreferences variable sp, and it points to a system generated file in the path:
/data/data/<packagename>/shared_prefs/<packagename>_preferences.xml
which I can only assume is the same xml I provided when I created the activity.
addPreferencesFromResource(R.layout.preferences);
Also inspecting the sp variable, the hash table has all the preferences, but there is no field for default value.
EDIT:
Before I am asked to, here is an excerpt from the preferences.xml file
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<EditTextPreference
android:defaultValue="5000"
android:key="#string/MAX_MESSAGES"
android:numeric="integer"
android:summary="#string/MAX_MESSAGES_desc"
android:title="#string/MAX_MESSAGES_title" />
<EditTextPreference
android:defaultValue="10"
android:key="#string/VIEW_EDGE_ROWS"
android:numeric="integer"
android:summary="#string/VIEW_EDGE_ROWS_desc"
android:title="#string/VIEW_EDGE_ROWS_title" />
<ListPreference
android:defaultValue="0"
android:entries="#array/level_list"
android:entryValues="#array/level_values"
android:key="#string/INITIAL_ORG"
android:summary="#string/INITIAL_ORG_desc"
android:title="#string/INITIAL_ORG_title" />
<ListPreference
android:defaultValue="2"
android:entries="#array/view_list"
android:entryValues="#array/view_values"
android:key="#string/INITIAL_VIEW"
android:summary="#string/INITIAL_VIEW_desc"
android:title="#string/INITIAL_VIEW_title" />
<CheckBoxPreference
android:defaultValue="true"
android:key="#string/AUTOSCROLL"
android:summary="#string/AUTOSCROLL_desc"
android:title="#string/AUTOSCROLL_title" />
<CheckBoxPreference
android:defaultValue="true"
android:key="#string/SEND_THEN_EXIT"
android:summary="#string/SEND_THEN_EXIT_desc"
android:title="#string/SEND_THEN_EXIT_title" />
<Preference
android:key="#string/DEFAULT_PREFS"
android:summary="#string/DEFAULT_PREFS_desc"
android:title="#string/DEFAULT_PREFS_title" />
</PreferenceScreen>
This is my solution so far. After debugging into the Android source code I find out that setDefaultValues() is not reliable and does not work as intended (at least according to my expectations).
I restore the default values manually now. I have a map where I can fetch from the default values.
Here is an interesting note: Inspecting the Preference class shows it has a field called mDefaultValue which contains the default value for the preference. But this field can only be set by setDefaultValue() method, and there is no method to get it. It would have save me the need for a Map
This is the code I use now, tested and working:
Preference reset = findPreference(getResources().getString(R.string.DEFAULT_PREFS));
reset.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference p) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(Preferences.this);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
// PreferenceManager.setDefaultValues(Preferences.this, R.layout.preferences, false);
for(int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
restoreDefault(editor, getPreferenceScreen().getPreference(i));
}
editor.commit();
return true;
}
}
private void restoreDefault(Editor editor, Preference p) {
if(p instanceof PreferenceCategory) {
PreferenceCategory pCat = (PreferenceCategory) p;
for(int i = 0; i < pCat.getPreferenceCount(); i++) {
restoreDefault(editor, pCat.getPreference(i));
}
}
if(p instanceof ListPreference) {
editor.putString(p.getKey(), resMap.get(p.getKey())._default);
}
if(p instanceof EditTextPreference) {
editor.putString(p.getKey(), resMap.get(p.getKey())._default);
}
if(p instanceof CheckBoxPreference) {
editor.putBoolean(p.getKey(), resMap.get(p.getKey())._default.equals("true"));
}
}
Another note: editor.commit() updates the preferences file, but does not update the preferences screen. You have to update each preference by using the listener (OnSharedPreferenceChangeListener()).

Android CheckBoxPreference java.lang.StackOverflowError

I have this CheckBoxPreference in my code. I have implemented onSharedPreferenceChanged() in my code to perform some action. The problem is that when i click on the checkbox preference, the function gets called in a loop with same value. Can anyone help me with this?
Here are the relevant code snippets:
onSharedPreferenceChanged() section in preference activity:
if(key.equals(LOCATION_UPDATE_KEY)) {
boolean update = sharedPreferences.getBoolean(LOCATION_UPDATE_KEY, false);
Log.v("preferences", update + "");
editor.putBoolean(LOCATION_UPDATE_KEY, update);
editor.commit();
}
preference activity's xml section:
<PreferenceCategory
android:title="Location">
<CheckBoxPreference
android:title="Track Location"
android:defaultValue="false"
android:summary="Keep track of handset location (Consumes Battery)"
android:key="track_option" />
<ListPreference
android:title="Location Update Source"
android:summary=""
android:key="track_source"
android:defaultValue="2"
android:entries="#array/location_sources"
android:entryValues="#array/location_sources_values"
android:dependency="track_option" />
<ListPreference
android:title="Location Update Interval"
android:summary=""
android:key="track_interval"
android:defaultValue="2"
android:entries="#array/location_update_interval"
android:entryValues="#array/location_update_interval_values"
android:dependency="track_option" />
</PreferenceCategory>
simple: if you change the SharedPreference in onSharedPreferenceChanged you create a loop because you trigger yourself. The loop is actually a recursion and if you call yourself endlessly you fill up the memory (not the normal one - the "stack") until you get a stackoverflow.
a normal (somewhat useful) recursion looks like this:
public int sumAllNumbersUpTo (int number) {
if (number > 0) {
return number + sumAllNumbersUpTo(number - 1);
} else {
return 0;
}
}
int result = sumAllNumbersUpTo(3);
// result is 3 + ( 2 + ( 1 + ( 0 ) ) )
it is calling itself until some condition is met. If you remove that condition then this method will never end.

Using Android preferences and dont show a variable to user

I have a sharedPreferences implementation where I store user preferences. When the user clicks "preferences" in menu, I open the standar editor to allow the user to change preferences. This is the code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.MENU_PREFERENCES:
Intent intent = new Intent(context, PreferencesActivity.class);
startActivity(intent);
return true;
case xx:
....
}
Toast.makeText(this, "ERROR: Bad menu item", Toast.LENGTH_SHORT).show();
return true;
}
In PreferencesActivity.java I have:
public class PreferencesActivity extends PreferenceActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
My question is if can I have a variable in the preferences for internal use, I mean, that will not be showed to user when startActivity(intent)? how?
I suppose I must change something in preferences.xml but dont know exactly what....
thanks
EDIT: as requested, I paste xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory>
<ListPreference android:title="Pomodoro duration" android:key="pomodoro_duration" android:summary="Duration of each pomodoro" android:entryValues="#array/array_duration_values" android:defaultValue="25" android:entries="#array/array_duration"/><ListPreference android:key="short_break_duration" android:title="Short break duration" android:summary="Duration of break after each pomodoro" android:entryValues="#array/array_duration_values" android:entries="#array/array_duration" android:defaultValue="5"/>
<ListPreference android:title="Long break interval" android:summary="Interval of the longer break" android:key="intervalos" android:entryValues="#array/interval_array_values" android:defaultValue="4" android:entries="#array/interval_array"/>
<ListPreference android:defaultValue="20" android:title="Long break duration" android:summary="Duration of break after each pomodoro" android:key="long_break_duration" android:entries="#array/array_duration" android:entryValues="#array/array_duration_values"/><RingtonePreference android:title="Notification sound" android:ringtoneType="notification" android:summary="Tone that will sound after pomodoro ends" android:key="notification_tone" android:showDefault="true" android:showSilent="true"/>
<ListPreference android:summary="Period used to calculate productivity" android:title="Calculus period" android:key="calculus_period" android:entryValues="#array/array_calculo_valores" android:entries="#array/array_calculo"/>
</PreferenceCategory>
</PreferenceScreen>
When I inveke the standar UI to allow user to set this variables, I would like to hide one of them programmaticaly. Is possible?
If it is not in preferences.xml, it won't be displayed, so just don't add it there. You can use the SharedPreferences class to get/set preferences without displaying a UI. Something like:
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(context);
boolean flag = prefs.getBoolean("flag", false);

Categories

Resources