Muting Sounds in Android App with Shared Preferences Not Working - android

I'm building my first Android app, so apologies in advance for my lack of expertise. I've been banging away at this issue for 2 days so far. When I set the sound to mute in my Settings Activity via Shared Preferences, the setting does not 'stick'. Here is the code from my Main Activity:
SharedPreferences settingsSP;
boolean muteSound;
Then in onCreate:
settingsSP = getApplicationContext().getSharedPreferences("PlayerPreferences", Context.MODE_PRIVATE);
muteSound = settingsSP.getBoolean("muteSound", false);
Then I obviously use the muteSound variable to determine whether or not to play sounds within the MainActivity. Now when I go the Settings activity I have this code:
SharedPreferences settingsSP;
boolean muteSound;
Then in onCreate I have this:
settingsSP = getApplicationContext().getSharedPreferences("PlayerPreferences", Context.MODE_PRIVATE);
if (muteSound) {
activitySettingsBinding.displayMuteCheckBox.setChecked(true);
} else {
activitySettingsBinding.displayMuteCheckBox.setChecked(false);
}
activitySettingsBinding.displayMuteCheckBox.setOnClickListener(v -> {
if (activitySettingsBinding.displayMuteCheckBox.isChecked()) {
muteSound = true;
SharedPreferences.Editor editor = settingsSP.edit();
editor.putBoolean("muteSound", muteSound);
editor.apply();
} else {
muteSound = false;
SharedPreferences.Editor editor = settingsSP.edit();
editor.putBoolean("muteSound", muteSound);
editor.apply();
soundPool.play(bubble, 1, 1, 1, 0, 1);
}
The xml code:
<CheckBox
android:id="#+id/displayMuteCheckBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:gravity="center_vertical"
android:layoutDirection="rtl"
android:paddingLeft="40dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:text="Mute Sound"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold"
android:theme="#style/CheckBoxStyle" />
I placed a number of log.d tags throughout the code so that I observe what was happening. For example after I cold booted the app in Android Studio:
Open MainActivity, onCreate muteSound = false
Tap Settings button and the Settings onCreate lists muteSound = false
I check the checkbox to set it to muteSounds = true
I tap return button within Settings to return to MainActivity
MainActivity onCreate muteSound = true
Tap Settings button and the Settings onCreate lists muteSound = false
And the checkbox is unchecked - because muteSound = false
I can't figure out why the settings is not sticking. When I checked to set the muteSound to be true, that settings is lost when I return to the Settings Activity. I've searched the code to see if I set muteSound = true on accident somewhere else, but when searching the usages I did not find any. Is my assumption about sharePreferences incorrect. It doesn't appear to hold the settings. Or perhaps am I using the checkbox incorrectly, maybe I should be using another type of button here. I would like to use checkboxes to control the display of the score, time and other items on the MainActivity and throughout other app Activities, but if I can't figure this gap in my knowledge I won't be able to. What am I doing incorrectly?

For displayMuteCheckBox, use setOnCheckedChangeListener instead of setOnClickListener and use settingsSP variable to store value in SharedPreferences instead of creating new object of SharedPreferences.Editor:
activitySettingsBinding.displayMuteCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
settingsSP.edit().putBoolean("muteSound", isChecked).apply();
if (isChecked)
soundPool.play(bubble, 1, 1, 1, 0, 1);
}
});

Related

By the "Settings Activity" go and change the main activity to another activity

In the Activity Settings shown below, in general, the switch, i want when is true to have "on"/"appear"/"display"/"launch" activity_main_one to the screen and when it is false to have on activity_main_two to the screen:
Any ideas?
private void loadPref() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean isTrue = sharedPreferences.getBoolean("Guest_Mode_Key", true);
if (isTrue) {
View Guest = findViewById(R.id.guest_include);
View User = findViewById(R.id.user_include);
Guest.setVisibility(View.VISIBLE);
User.setVisibility(View.GONE);
} else {
View Guest = findViewById(R.id.guest_include);
View User = findViewById(R.id.user_include);
Guest.setVisibility(View.GONE);
User.setVisibility(View.VISIBLE);
}
}
.
<include
android:id="#+id/guest_include"
layout="#layout/content_one"
android:visibility="visible" />
<include
android:id="#+id/user_include"
layout="#layout/content_two"
android:visibility="gone" />
I created two <*include> tags and set the first to "Visible" and the second "Gone", i found how to get the data from the settings activity it was simple and then i created an if when the switch is true etc. and for the end i just call loadPref()
#DaveNOTDavid - I was lucky after all ;)

Add preferences to specific places in PreferenceScreen programmatically

I am populating parts of my preferences programmatically. This works fine. Unfortunately new preferences there has to be added, when the user changes some preferences (think of an 'add a new alarm'-preference). This works fine as well, when I use PreferenceCategories (because the new ones are added at the end of one such, so myPreferenceCategory.addPreference(newPreference) does the trick). But what can I do to programmatically add a Preference to any specific place (not just the end of usual categories/the prefScreen??
I tried to use some kind of "invisible" PreferenceCategory, by setting android:layout="my_custom_invis_layout" with
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_custom_invis_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"/>
Unfortunately those padding and margin does not seem to have an impact on the minimum space the empty category take (but do so with positive values, which is - of cause - of no help).
I tried as well to nullify the layout by
<PreferenceCategory
android:layout="#null">
but this just enlarges the space the category takes to those the other preferences have.
Unfortunately SO did not help me on this so far. I would be very happy if anyone can point me to something like "add a preference A below preference B" or on how to make a category taking no space at all (as this would resolve my problem as well).
I see this question is quite old, but since I was facing a similar problem and managed to solved it, I figured there would be no harm done by posting anyway.
The way I solved this is by adding the Preference (in my case a category that needed to be added in a particular spot amongst the other categories) in xml from the start, removing it programmatically if not yet needed. When putting it back (programmatically) afterwards, it appears at the same position it was before removing it. Haven't tried your particular case (with single Preferences needing to go in a particular spot within a category), but I bet it works the same way.
public class PreferencesFragment extends PreferenceFragmentCompat {
private SharedPreferences mSharedPreferences;
private PreferenceCategory mPreferenceCategory;
#Override
public void onCreatePreferences(#Nullable Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences);
mPreferenceCategory = (PreferenceCategory) findPreference("preferenceCategoryKey");
if (preferenceNotRequiredYet) {
removePreferenceCategory();
}
// an I have a SharedPreferenceListener attached that calls
// addPreferenceCategory when I need to add it back
}
private void removePreferenceCategory() {
PreferenceScreen parentScreen = (PreferenceScreen) findPreference("parent_screen_key");
parentScreen.removePreference(mPreferenceCategory);
}
private void addPreferenceCategory() {
PreferenceScreen parentScreen = (PreferenceScreen) findPreference("parent_screen_key");
parentScreen.addPreference(mPreferenceCategory);
}
}
Ok, I've tried that other approach with Preferences#setOrder(int). (I left the previous answer there, cause for some use cases it might be the easier solution.) Does this one better suit your needs?
public class PreferencesFragment extends PreferenceFragmentCompat {
private SharedPreferences mSharedPreferences;
PreferenceCategory mMyPreferenceCategory;
// ArrayList to keep track of the currently added Preferences
ArrayList<Preference> mPreferenceList = new ArrayList<>();
// this counter only serves for name-giving of the added
// Preferences in this example
int mCounter = 0;
#Override
public void onCreatePreferences(#Nullable Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences);
mMyPreferenceCategory = (PreferenceCategory) findPreference("preferenceCategoryKey");
addPreference(null);
}
// adds a Preference that is inserted on the position of the
// clicked Preference, moving the clicked Preference - and all
// Preferences after - one position down
private void addPreference(Preference pref) {
int order = 0;
if (pref != null) {
order = pref.getOrder();
}
for (Preference preference : mPreferenceList) {
int oldOrder = preference.getOrder();
if (oldOrder >= order) {
preference.setOrder(oldOrder+1);
}
}
Preference newPreference = new Preference(getContext());
newPreference.setTitle("Preference " + mCounter);
newPreference.setOrder(order);
newPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
addPreference(preference);
return false;
}
});
mMyPreferenceCategory.addPreference(newPreference);
mPreferenceList.add(newPreference);
mCounter++;
}
}

Is there only one shared preferences object per application?

My question is: If I call:
PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
in two different Activities in my application, does it refers to the same SharedPreferences file?
More concretely, I have a rememberMe check box in my SharedPreferences.
which I can change from two locations in my application. It looks like when I change it in one location it doesn't take effect in the second location.
Edit:
I have this code:
public View createSettingsOverlay(){
ViewGroup root = (ViewGroup)findViewById(R.id.absoluteOverlay);
LayoutInflater inflater = getLayoutInflater();
View result = inflater.inflate(R.layout.overlay_baloon_settings, root, false);
((TextView)result.findViewById(R.id.loginText)).setText(application.getCurrentlyLoggedUser());
((TextView)result.findViewById(R.id.passwordText)).setText(application.getCurrenlyLoggedPass());
((TextView)result.findViewById(R.id.loginTimeText)).setText(application.getTimeOfLogin().toString());
((TextView)result.findViewById(R.id.settings_popup_server_url)).setText(application.getCurrentUrl());
//Emil Edit
CheckBox rememberMe = (CheckBox)result.findViewById(R.id.cbRememberMe);
//boolean rememberMePreference = PreferenceManager.getDefaultSharedPreferences(DynamicDataActivity.this).getBoolean(SettingsActivity.REMEMBER_ME_CHECKBOX_KEY, false);
Log.d(TAG, "Remember Me set in the preference is: " + PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(SettingsActivity.REMEMBER_ME_CHECKBOX_KEY, false));
rememberMe.setChecked(PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(SettingsActivity.REMEMBER_ME_CHECKBOX_KEY, false));
rememberMe.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.d(TAG, "boolean isChecked is: " + isChecked);
if (isChecked)
{
Log.d(TAG, "Remember me checkbox in setting overlay set to True");
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit().putBoolean(SettingsActivity.REMEMBER_ME_CHECKBOX_KEY, true);
application.setRememberMeChecked(true);
}
else
{
Log.d(TAG, "Remember me checkbox in setting overlay set to False");
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit().putBoolean(SettingsActivity.REMEMBER_ME_CHECKBOX_KEY, false);
application.setRememberMeChecked(false);
}
}
});
Which basically created a popup window with setting from SharedPreferences when I check the rememberMe checkbox in this popup window, close it and open it again. for some reason it is not checked again, in other Activity (Setting Activity), I can see that this change didn't took effect as well.
Uses this for get SharedPreferences (myPrefs is your file):
For save:
SharedPreferences prefs = getSharedPreferences("myPrefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("rememberMe", yourState);
editor.commit();
For get:
SharedPreferences prefs = getSharedPreferences("myPrefs", Context.MODE_PRIVATE);
boolean state = prefs.getBoolean("rememberMe", state_by_default);
Converting comments to answer,
Your problem is you haven't commit your preference. SharedPreference will update only after commit
Yes, default shared pref file is same for Application context.

Android: checkbox.isChecked() is always returning a false condition

I'm trying to code a checkbox into a help screen which is essentially a pop up view (an activity that's started by the main program) containing a ScrollView that has the help text, and OK button, and a checkbox that asks if you want the help screen to appear automatically at program start. Everything displays properly on the screen, and the checkbox toggles, when touched. However, when OK is pressed, and I test the state of the checkbox with .isChecked() I'm always getting a false. I'm sure it's something simple I've missed. XML file follows follows:
helpdialog.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:background="#ffffff">
<ScrollView android:id="#+id/ScrollView01"
android:layout_width="wrap_content" android:layout_below="#+id/ImageView01"
android:layout_height="300px">
<TextView android:text="#+id/helpView" android:id="#+id/helpView"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textColor="#000000"/>
</ScrollView>
<Button android:id="#+id/Button01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:text=" OK "
android:layout_below="#id/ScrollView01"/>
<CheckBox android:id="#+id/chkNoHelp" android:textColor="#000000"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Don't Display at Startup"
android:layout_below="#id/Button01" />
</RelativeLayout>
HelpBox.java:
public class HelpBox extends Activity {
CheckBox checkBox;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set up dialog
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.helpdialog);
dialog.setTitle("Help");
dialog.setCancelable(true);
//set up text
TextView text = (TextView) dialog.findViewById(R.id.helpView);
text.setText(getString(R.string.help_text));
//set up button
Button button = (Button) dialog.findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Boolean mDisplayHelp;
setContentView(R.layout.helpdialog);
checkBox = (CheckBox) findViewById(R.id.chkNoHelp);
if (checkBox.isChecked()) {
mDisplayHelp = true;
} else {
mDisplayHelp = false;
}
finish();
}
});
//now that the dialog is set up, it's time to show it
dialog.show();
}
}
Setting breakpoints on both "mDisplayHelp" lines always breaks at the 'false' branch regardless of whether the check box displays a green check or not when the OK button is pressed.
Thanks in advance.
Edit (10/10):
Its clear what I want to do is pick up information after the user exits the dialog, so I can sense the state of the checkbox and store it as a preference. For this I assume I have to test it in onDestory. So, I did that:
#Override
public void onDestroy() {
Boolean mDisplayHelp;
setContentView(R.layout.helpdialog);
checkBox = (CheckBox) findViewById(R.id.chkNoHelp);
if (checkBox.isChecked()) {
mDisplayHelp = true;
} else {
mDisplayHelp = false;
}
}
However, I'm still always coming up with FALSE as a result, regardless of whether the checkbox is display checked or off. In this instance, if I don;t include the setContentView, I get a NullPointerException on the isChecked.
Why are you calling setContentView a second time? After the second time you call it, your checkbox is being reset to unchecked (the default state) and then you are immediately checking its state to set a flag.
Its not clear what your intention is here by inflating helpdialog.xml twice, once in a Dialog and once in your main Activity. It sounds like you want to use a dialog-themed activity here and only call setContentView() once in onCreate. It should behave as expected after that.
I finally figured this out, and boy was I going about things the wrong way. Chalk it up to learning curve.
What I needed to do was save the checkbox state. I needed to use SharedPreferences for that. I needed to detect when the checkbox was touched by using a listener on it and then saving the preference at that time. Upon opening the help box, I load the preference state and set the check box to that state so it shows properly based on the user's previous setting.
Finally, load the preference in onCreate at the main activity and call the showHelpBox() if the preference was so set.
In onCreate of main activity:
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
Boolean mDisplayHelp = prefs.getBoolean("checkboxPref", false);
if (mDisplayHelp == false)
showHelpBox();
In help box activity pre-initialize the check box based on previous setting:
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
mDisplayHelp = prefs.getBoolean("checkboxPref", false);
final CheckBox ckBox = (CheckBox) dialog.findViewById(R.id.chkNoHelp);
ckBox.setChecked(mDisplayHelp);
When checkbox is touched:
ckBox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (ckBox.isChecked()) {
mDisplayHelp = true;
} else {
mDisplayHelp = false;
}
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("checkboxPref", mDisplayHelp);
// Don't forget to commit your edits!!!
editor.commit();
}
});
Hopefully others can learn from my foolish mistakes and misunderstanding.

Android: CheckBoxPreference enable/disable email address inputtype (override default settings)

Hey everyone, I'm trying to make an activity so that when a CheckBox Preference is enabled (true), programmatically the on-screen keyboard InputType will change. I want the user to have the option to turn on/off the keyboard's email address option while keeping the inputType's already set.
Essentially doing the equivalent of changing:
android:inputType="textAutoCorrect|textCapSentences|textMultiLine"
to
android:inputType="typeAutoCorrect|textCapSentences|textmultiLine|textEmailAddress"
Preferences.xml
<CheckBoxPreference android:key="pref_key_enable_email"
android:title="#string/pref_title_enable_email"
android:summary="#string/pref_summary_enable_email"
android:defaultValue="false" />
This is what I have as of now.
public void setInputType(int type) {
boolean showEmail = false;
// Show the Email keyboard if the pref_key_enable_email preference is TRUE
mTextEditor = (EditText) findViewById(R.id.embedded_text_editor);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if(prefs.getBoolean("pref_key_enable_email",false)== true){
showEmail = true;
if (showEmail) {
mTextEditor.setInputType(InputType.TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS); w
} else {
mTextEditor.getInputType();
}
}
I've checked the /data/data/myappname/shared_prefs com.myappnamehere.preferences.xml. I at least know that the boolean values do change from false to true when the box is checked. It just doesn't do anything :(
Consider cleaning your code a little bit
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean showEmail = prefs.getBoolean("pref_key_enable_email",false);
mTextEditor = (EditText) findViewById(R.id.embedded_text_editor);
if(showEmail) {
mTextEditor.setInputType( mTextEditor.getInputType() | TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
}
I'm assuming you have your "default" flags in the xml for your layout:
android:inputType="textAutoCorrect|textCapSentences|textMultiLine"

Categories

Resources