CheckBoxPreference dependency not found error - android

I have this CheckBoxPreference
CheckBoxPreference sendToEmailPref = new CheckBoxPreference(this);
sendToEmailPref.setTitle("Send To Email");
sendToEmailPref.setDependency("emailList");
I want to set its dependency on a key "emailList"
emailList is a custom build preference which stores the email addressees as a String.
However, I am getting this error
Caused by: java.lang.IllegalStateException: Dependency not found.....

you should call setDependency after you have finished calling addPreference
It works for me well!

Get your .setDependency() to just after setPreferenceScreen() in your onCreate. It should work.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setPreferenceScreen(createPreferenceHierarchy());
getPreferenceScreen().findPreference("_key_of_depend_to_").setDependency("emailList");
}

final CheckBoxPreference sendImageToEmail = (CheckBoxPreference) findPreference("send_image_to_email");
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
if (key.equals("emailList")) {
String emails = sharedPreferences
.getString("emailList", "");
if (emails.equals("")) {
sendImageToEmail.setChecked(false);
I used a OnSharedPreferenceChangeListener to do it.

Make sure you have added a preference with a "emailList" key before you add the dependency to your CheckBoxPreference. I've had something like below working for me (in my PreferenceFragment).
Context context = getActivity();
PreferenceScreen root = getPreferenceManager.createPreferenceScreen(context);
setPreferenceScreen(root);
CustomPreference customPref = new CustomPreference(context);
customPref.setTitle("My Custom Preference");
customPref.setKey("emailList");
root.addPreference(customPref);
CheckBoxPreference sendToEmailPref = new CheckBoxPreference(context);
sendToEmailPref.setTitle("Send To Email");
root.addPreference(sendToEmailPref);
sendToEmailPref.setDependency("emailList");

you should write sendToEmailPref.setDependency("emailList") after setPreferenceScreen(yourScreen)
assume i write:
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
val context = preferenceManager.context
val screen = preferenceManager.createPreferenceScreen(context)
...
and have a switchPreference :
val mySwitchPreference = SwitchPreference(context)
mySwitchPreference.key = "my_switch_preference"
screen.addPreference(mySwitchPreference )
...
and have a SeekBarPreference that i want to be dependent on "mySwitchPreference".
if switch is "ON" then seekbar is enabled else seekbar is disabled:
val mySeekBarPreference = SeekBarPreference(context)
mySeekBarPreference.key = "my_seekbar_preference"
screen.addPreference(mySeekBarPreference)
...
preferenceScreen = screen
mySeekBarPreference.dependency = mySwitchPreference.key
if you do try to set dependency for seekBarPrefernece, before setting
screen as PreferenceScreen, it gives you this error:
java.lang.IllegalStateException: Dependency "my_switch_preference" not found for preference "my_seekbar_preference"

You can try the following code:-
private static final String PARENT_CHECKBOX_PREFERENCE = "parent_checkbox_preference";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);
setPreferenceScreen(root);
populatePreferenceHierarchy(root);
}
private void populatePreferenceHierarchy(PreferenceScreen pScreenRoot) {
// Preference attributes
PreferenceCategory prefAttrsCat = new PreferenceCategory(this);
prefAttrsCat.setTitle("preference_attributes");
pScreenRoot.addPreference(prefAttrsCat);
// Visual parent toggle preference
CheckBoxPreference parentCheckBoxPref = new CheckBoxPreference(this);
parentCheckBoxPref.setKey(PARENT_CHECKBOX_PREFERENCE);
parentCheckBoxPref.setTitle("title_parent_preference");
parentCheckBoxPref.setSummary("summary_parent_preference");
prefAttrsCat.addPreference(parentCheckBoxPref);
// Visual child toggle preference
// See res/values/attrs.xml for the <declare-styleable> that defines TogglePrefAttrs.
TypedArray typeA = obtainStyledAttributes(R.styleable.TogglePrefAttrs);
CheckBoxPreference childCheckBoxPref = new CheckBoxPreference(this);
childCheckBoxPref.setKey("child_checkbox_preference");
childCheckBoxPref.setTitle("title_child_preference");
childCheckBoxPref.setSummary("summary_child_preference");
childCheckBoxPref.setLayoutResource(typeA.getResourceId(R.styleable.TogglePrefAttrs_android_preferenceLayoutChild, 0));
prefAttrsCat.addPreference(childCheckBoxPref);
childCheckBoxPref.setDependency(PARENT_CHECKBOX_PREFERENCE);
typeA.recycle();
}

Related

Fix Fragment Injection vulnerability in Xamarin Android

As you know Android Developers:
Beginning March 1, 2017, Google Play will block publishing of any new apps or updates where PreferenceActivity classes may be vulnerable to Fragment Injection
In the page https://support.google.com/faqs/answer/7188427 it gives some advices on how to fix this vulnerability but what about the applications developed with Xamarin?
I haven't been able to found any information on this. It says that my affected class is SettingActivity, which inherits from PreferenceActivity, and my class SettingActivity is this:
[Activity(
Label = "#string/ApplicationName",
Icon = "#drawable/ic_launcher",
Theme = "#android:style/Theme.Holo.Light",
ParentActivity = typeof(MainActivity))]
[IntentFilter(
new [] {Intent.ActionManageNetworkUsage},
Categories= new [] {Intent.CategoryDefault}
)]
public class SettingsActivity : PreferenceActivity
{
public static readonly string KeyWifiOnly = "pref_wifi_only";
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
AddPreferencesFromResource(Resource.Xml.preferences);
ActionBar.SetHomeButtonEnabled(true);
ActionBar.SetDisplayHomeAsUpEnabled(true);
PreferenceManager.SetDefaultValues(this, Resource.Xml.preferences, false);
SetupNetworkPreferences();
}
private void SetupNetworkPreferences()
{
var prefs = PreferenceManager.GetDefaultSharedPreferences(this);
ListPreference list = FindPreference(
AppSettings.PreferenceNetworkProvider) as ListPreference;
list.SetEntries(
Enum.GetNames(typeof(AppSettings.FtpHostNetwork)));
list.SetEntryValues(Enum
.GetValues(typeof(AppSettings.FtpHostNetwork))
.Cast<int>()
.Select(x => x.ToString())
.ToArray());
}
protected override void OnResume()
{
base.OnResume();
var tracker = (Application as App).Tracker;
tracker.Screen("PantallaPreferencias");
}
}
As suggested by Mike Ma in the comments:
Adding the exported=false propierty worked just fine.
[Activity( Label = "#string/ApplicationName", Exported =false, Icon = "#drawable/ic_launcher", Theme = "#android:style/Theme.Holo.Light", ParentActivity = typeof(MainActivity))]

Android: issue with data storage (SharedPreferences)

I'm learning android and for this project I need to save user's data - color change of buttons, in this case -. During the program the change occurs (onClick), but when I restart the app, nothing happens - the change has not been saved (or read...) Can someone help me? Code:
final String paintKey = "paint";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonCreate();
preferences();
togglePlay();
}
public void preferences(){ //the issue in this method?
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
data = settings.getString("stage", "Indoors");
settings.getBoolean(paintKey,false);
String backGround = settings.getString("stage", "Indoors");
if (backGround.equals("Indoors")) {
Picasso.with(this).load(R.drawable.shocked_crowd).fit().centerCrop().into(stage);
}
if (backGround.equals("Street")) {
Picasso.with(this).load(R.drawable.coins).fit().centerCrop().into(stage);
}
}
public void changeColor(){
if(!paint) { //paint variable has global scope and it is set to false
c1.setBackgroundColor(Color.YELLOW);
paint = true;
}else{
c1.setBackgroundColor(Color.BLUE);
paint = false;
}
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("paint", paint);
editor.commit();
}
EDIT: the onClick method:
public void onClick(View v) {
if(v==color){
changeColor();
}
EDIT: this is how I have it now:
public void preferences(){
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
data = settings.getString("stage", "Indoors");
final String paintKey = "paint";
settings.getBoolean(paintKey,false);
Wrong? if I put editor instead of settings i get red underlined
In order to work with SharedPreferences you need a global key
final String paintKey = "paint"
To write boolean value info SharedPreferences use
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
editor.putBoolean(paintKey, paint).commit();
To read that data later
paint = settings.getBoolean(paintKey, false);
settings.getBoolean(paintKey,false);
This line gets a value from the SharedPreferences and promptly ignores it. You must save the return value in a variable in order to use it later:
boolean paint = settings.getBoolean(paintKey,false);
This will create a local variable that can only be used in the same method. If you need to use the value in other methods, create a field instead.

Confused on Reading SharedPreferences Without a PreferenceActivity

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();
}
`

Android How to update Background color from PreferenceList directly

I have a ListPreference containing colors. Only when I restart the application that the colors are being changed, not directly. How do I make it change directly when I click ?
public class Preferences extends PreferenceActivity {
SharedPreferences sharedpreferences;
SharedPreferences sharedpreferences2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.preferences);
sharedpreferences2 = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
ListPreference listPreference = (ListPreference) findPreference("Color");
CharSequence entry = listPreference.getEntry();
final String value = listPreference.getValue();
final ListView rel = this.getListView();
if (sharedpreferences2.contains("Color")) {
if (value.toString().equals("Red")) {
rel.setBackgroundColor(Color.RED);
}
if (value.toString().equals("Blue")) {
rel.setBackgroundColor(Color.BLUE);
}
if (value.toString().equalsIgnoreCase("Green")) {
rel.setBackgroundColor(Color.GREEN);
}
}
}
you will need the OnSharedPreferenceChangeListener. Use registerOnSharedPreferenceChangeListener() in your onResume() and override the onSharedPreferenceChanged() method to perform actions on preference change.
Unregister the listener in your onPause() method.
P.S. PreferenceActivity is deprecated, consider using PreferenceFragment instead.

Handling preference.xml file in android

I have created a check box preference for the settings of my app.
So whenever I check or uncheck the box, android automatically created myapp_preferences.xml file. Which is the default work of android.
And here is my question:
I also maintain a separate xml file to maintain the state of this checkbox. So I think there is no need for myapp_preferences.xml file, which is created by android.
Is there any way to avoid myapp_preferences.xml file from being created.?
Here is my code:
final CheckBoxPreference CheckBoxPreference = (CheckBoxPreference) getPreferenceManager().findPreference(rsrc.getString(R.string.settings_checked));
CheckBoxPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
{
public boolean onPreferenceChange(Preference preference, Object newPreference)
{
final SharedPreferences prefs = getSharedPreferences(Custom_Preference, 0);
final Editor edit = prefs.edit();
Boolean newBoolPreference = (Boolean) newPreference;
edit.putBoolean(rsrc.getString(R.string.settings_checked), newBoolPreference);
edit.commit();
return true;
}
});
Whenever I check or uncheck this box, android automatically created its own preference xml file. I don't want this action.
In your PreferenceActivity , add this code:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
PreferenceManager prefMgr = getPreferenceManager();
prefMgr.setSharedPreferencesName("your custom filename");
prefMgr.setSharedPreferencesMode(Context.MODE_PRIVATE);
addPreferencesFromResource(R.xml.preference);
this.appPreferences.sharedPreferences.registerOnSharedPreferenceChangeListener(listener);
}

Categories

Resources