in the onCreate method of my PreferenceActivity i set some Properties like this:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("pref_mykey", true);
editor.commit();
It seems to work but the View is not updating so when i open the properties the onCreate runs and changes the values. I will then see the "old" values on the Screen until i close and reopen the prefs screen, then i do see the new properties.
I already tried this after the commit:
((BaseAdapter) getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
But without any effect. I still see the "old" Prefs until i close and reopen the PreferenceActivity .
What am i doing wrong? How can i refresh the PreferenceActivity after setting values in the onCreate method?
Thanks a lot for your help.
This was buggin me all day but finally found a solution.
((ListPreference)getPreferenceScreen().findPreference("key_of_preference_in_xml_file")).setValue(code);
Your example is with a boolean so it'll have to change based on what kind of preference it is.
IE:
((CheckBoxPreference)getPreferenceScreen().findPreference("key_of_preference_in_xml_file")).setChecked(true);
If you use a PreferenceFragment than you need to inject the PreferenceScreen in the activity.
public class SettingsActivity extends Activity implements ScanFragment.OnFragmentInteractionListener {
private PreferenceScreen prefScreen;
public void setPreferenceScreen(PreferenceScreen prefScreen){
this.prefScreen = prefScreen;
}
#Override
public void onFragmentInteraction(String scanContent) {
// commiting to editor retrieved from preference manager would not refresh view
EditTextPreference pref = (EditTextPreference)this.prefScreen.findPreference(getString(R.string.preference_url_key));
pref.setText(scanContent);
}
public static class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
((SettingsActivity)this.getActivity()).setPreferenceScreen(this.getPreferenceScreen());
}
}
}
Related
I'm getting a compiler error cannot resolve method findPreference when I try to intialize an OnSharedPreferencesChanged listener in my MainActivity. According to the answer here:
findPreference() should be called from a class implementing PreferenceActivity interface
but I don't understand what the code to do this would be. How can I get rid of the compiler error and successfully set listeners for preference changes?
MainActivity.java
public class MainActivity extends FragmentActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
private SharedPreferences.OnSharedPreferenceChangeListener listener;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
//Test preference menu
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals("pref_wood")) {
Preference woodPref = findPreference(key); //COMPILER ERROR HERE
MainActivity.getGLSurfaceView().setTexture("");
// Set summary to be the user-description for the selected value
woodPref.setSummary(sharedPreferences.getString(key, ""));
}
}
}
}
}
findPreference is a method which is part of both PreferenceFragment and PreferenceActivity - these are the Fragments/Activities that actually show your Preference screen (the activity is deprecated and you should be using the PreferenceFragment).
You're trying to use it in your MainActivity. This doesn't work because the Preference objects don't actually exist on this screen (they exist in another activity that usually have a PreferenceFragment as part of it). If you need to get access to a preference value of a preference in an activity that is not your preference screen, use SharedPreferences, something like:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getBoolean(R.bool.saved_high_score_default);
boolean wood = sharedPref.getBoolean(pref_wood, defaultValue);
You can check out the documentation for further examples.
If your MainActivity is supposed to be a screen that shows settings, then you should probably rename it and include a preference fragment inside of it.
I believe you're also going to run into trouble with setSummary because the Preference is not part of this activity, it's part of the activity where you actually modify the preferences. setSummary is used to update the actual UI of the Preference so that if you, for example, select one of three values when using a list preference, it shows the value you just selected on the screen.
Because I want an AppCompat Action Bar on all of my settings submenus, I had to implement a workaround and my Settings Activity extends AppCompatActivity, not PreferenceActivity. I'm using a PreferenceFragment in the activity to handle the preferences, and each PreferenceScreen has its own xml file, which the PreferenceFragment switches out for each submenu in the settings. All of this was necessary to get the Action Bar to stay put through all of my submenus.
I'm trying to read a string value from the shared preferences file from within my MainActivity, and I've tried three different methods for getting that information, none of which have worked:
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
,
SharedPreferences sharedPref = getSharedPreferences(name, MODE_PRIVATE);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
and
SharedPreferences sharedPref = getPreferences(MODE_PRIVATE);
String btSelectPref = sharedPref.getString(getString(R.string.bt_select_key), "");
Here is the relevant section of my preferences.xml:
<PreferenceCategory
android:title="Bluetooth"
android:key="pref_bt">
<Preference
android:title="Select Bluetooth Device"
android:key="#string/bt_select_key"
android:defaultValue="0">
</Preference>
</PreferenceCategory>
This should fill the btSelectPref string with a "0", but it's always empty when I test it. I have included PreferenceManager.setDefaultValues(this, R.xml.preferences, false); in onCreate in my MainActivity, so the default values should be set.
I'm not sure which of these methods I should be using since I have multiple resource files for my settings, but none of them seem to be working for me. In the case of getSharedPreferences(name, MODE_PRIVATE), I have no idea what the name parameter should be referencing, since I've never named my shared preferences file.
EDIT: It turns out my issue was not related to getting values from the shared preferences file. I just had the wrong xml tag on the preference I was trying to check the value of. I changed it from a generic <Preference> tag to a <ListPreference> and my code started working with PreferenceManager.getDefaultSharedPreferences().
What you want to do and what you are doing differs. If you just want to put default shared preference for a key then consider this example. If your whole activity has just one shared pref file then you need not specify any name. It will automatically get it.
public MainActivity extends AppCompatActivity {
SharedPreferences mPrefs;
int test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_counter);
mPrefs = this.getPreferences(Context.MODE_PRIVATE);
test = mPrefs.getInt("pref_bt_select", 0);}
}
For the above example you can define the key and default value in your strings.xml and then you can refer to it while looking for the prefs you want.
Hey I have used AppCompat for my preference screen too.I did this because I wanted to use Vintage Chroma and this was the only way. But I am able to use PreferenceManager.getDefaultSharedPreference() without any errors.
Also if you want to use default shared preferences in the Fragment you can use :
SharedPreferences preferences = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);
Here is my full code :
public class PreferencesActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager()
.beginTransaction()
.replace(android.R.id.content, new PreferencesScreen())
.commit();
ActionBar toolbar = getSupportActionBar();
if (toolbar != null) {
toolbar.setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
public static class PreferencesScreen extends PreferenceFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings_xml);
}
}
}
Here is my code snippet for MAinActivity
Just the initial part where I set the default text theme.
`public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
AutoCompleteTextView mytextview;
public static String[] list;
ArrayList<String> recent = new ArrayList<String>();
public int recent_index = 0;
Menu mMenu;
#Override
protected void onCreate(Bundle savedInstanceState) {
/*Setting default theme.*/
SharedPreferences Sp= PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
int firstRun=Sp.getInt("firstRun",0);
if(firstRun==0)
{
SharedPreferences.Editor editor=Sp.edit();
editor.putInt("paragraphFontColor", Color.parseColor("#ffffff"));
editor.putInt("headingFontColor",Color.parseColor("#DE5246"));
editor.putInt("subheadingFontColor",Color.parseColor("#597d5e"));
editor.putInt("hyperlinksFontColor",Color.parseColor("#A5D8F5"));
editor.putInt("bodyColor",Color.parseColor("#2b2b2b"));
editor.putString("paragraphFont","PrintClearly.otf");
editor.putString("headingFont","PrintBold.otf");
editor.putString("subheadingFont","PrintBold.otf");
editor.putString("hyperlinkFont","PrintBold.otf");
editor.putString("paragraphFontStyle","normal");
editor.putString("headingFontStyle","normal");
editor.putString("subheadingFontStyle","normal");
editor.putString("hyperlinkFontStyle","normal");
editor.putString("actionBarColor","#597d5e");
editor.putString("paragraphFontSize","20px");
editor.putString("headingFontSize","30px");
editor.putString("subheadingFontSize","20px");
editor.putString("hyperlinkFontSize","20px");
editor.putString("firstRun",0);
editor.commit();
}
`
So I am trying to implement a preferences menu in my app. I used the standard generated template in android studio. THe issue is that now I can't figure out how save the values the user specifies. I thought about using a click listener to determine when a user clicked a checkbox and then getting the actual value of the checkbox and saving that to sharedpreferences, but I can't figure out how to do it.
Does anyone have any suggestions on how use onClick in a preference activity?
OK, we seem to be on the right track about the system storing the values automatically, but whenever I try to reference them from my main class, it always returns null. Here is my code:
boolean trueorfalse = PreferenceManager.getDefaultSharedPreferences(getActivity())
.getBoolean("my_key", false)
;
So I assume you've already defined your Preferences in res --> xml and it looks something like this:
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="my_key"
android:summary="#string/desc_string"
android:title="#string/title_string" />
</PreferenceScreen>
As soon as the user checks or unchecks the CheckBox the systen will automatically create an entry in the default Preference-file which you can access like this:
PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean("my_key", false);
But back to your initial question: If you want to assign an onClick-Listener to your preference you have to do something like this:
Preference myPreference = (Preference) findPreference("my_key");
myPreference .setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
// do something
}
});
Note: In this example it isn't a CheckBoxPreference, it's just a simple Preference
I tried the same in my SettingsMenu by implementing OnSharedPreferenceChangeListener
public class SettingsMenu extends PreferenceActivity implements OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
Context context = getApplicationContext();
SharedPreferences menu_settings = PreferenceManager.getDefaultSharedPreferences(context);
menu_settings.registerOnSharedPreferenceChangeListener(this);
...
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// check the checkboxes
}
}
Hope it helps :)
I use some CheckBoxPreferences, but they are not indepentent. That means, wenn I change one CheckBoxPreference, others are fixed. I use the following code:
public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
Context context = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPrefs, String key) {
SharedPreferences.Editor editor = sharedPrefs.edit();
if ((key.equals("A")) & (key.equals("B"))) {
editor.putBoolean("C", true);
editor.commit();
}
}
}
After this the CheckBoxPreference "C" has a new value, but I can't see it. How can I update the screen with the new values?
By using a subclass of PreferenceActivity you do not have to handle the updating of the preferences UI. You define the preferences in the resource file loaded by addPreferencesFromResource() and the Activity will be rendered accordingly. Changes will be persisted automatically and should be visible immediately. You do not have to register your preferences Activity as a SharedPreferences.OnSharedPreferenceChangeListener.
When onSharedPreferenceChanged() is called the new value is already saved to the preferences.
This notification is for other Activities than the subclasses of PreferenceActivity. To know how to access the saved preferences you need to look at the file in res/xml/settings.xml it should contain android:key attributes. The attribute values give you the key to the preference.
You can retrieve the value via the following:
PreferenceManager.getDefaultSharedPreferences(aContext).getString(key, "");
I have a PreferenceActivity, but some of the settings can be modified from another Activities also. But when a user modifies a setting from another activity, and then goes to the PreferenceActivity this change is not reflected there.
How can I make the change made from outside be reflected in the PreferenceActivity?
public class SettingsActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.settings);
}
}
and here is the code from another activity
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(Application.getApplication());
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("my_setting", true);
editor.commit();