SettingActivity by using switchpreferenceCompat - android

I have a preference screen having multiple SwitchpreferenceCompat. I need to give a user choice of theme change,vibration,etc in settingActivity. Can any one help me in how to set vibrate or theme change by clicking switch in settingactivity. I used this inside my settingActivity fragment but when i click setting activity the app stops
SwitchPreferenceCompat switchPref = findPreference("key");
switchPref.setChecked(true);
`res/xml/root_preference.xml
<SwitchPreferenceCompat
android:id="#+id/vibrate"
app:key="On"
app:title="Vibrate"
android:summaryOff="Off"
android:summaryOn="On"
app:icon="#drawable/ic_baseline_vibration_24"
android:defaultValue="true" />
<SwitchPreferenceCompat
app:key="On"
app:title="Sound"
app:summaryOff="Off"
app:summaryOn="On"
app:icon="#drawable/ic_baseline_volume_up_24"
android:defaultValue="true"/>
</PreferenceCategory>
User clicks the vibration on the app must vibrate when the button is clicked in the activity. How can i do this?

Use Androidx library
implementation 'androidx.preference:preference:1.1.1'
Then create xml folder and add your SwitchPreferenceCompat like below:
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<SwitchPreferenceCompat
android:id="#+id/vibrate"
android:key="vibrate"
android:summary="It will vibrate your phone"
android:title="Vibrate"/>
<SwitchPreferenceCompat
android:id="#+id/changeTheme"
android:key="theme"
android:title="Change Theme"
android:summary="It will toggle your app theme"/>
</androidx.preference.PreferenceScreen>
Then create SwitchPreferenceCompatActivity like below:
public class SwitchPreferenceCompatActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_switch_preference_compat);
if(savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.preferences_container, new MySettingsFragment())
.commit();
}
}
public static class MySettingsFragment extends PreferenceFragmentCompat {
SharedPreferences.OnSharedPreferenceChangeListener listener;
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.my_switch_preference_compat, rootKey);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.e("key", key);
if(key.equals("vibrate") && sharedPreferences.getBoolean("vibrate", false)) {
vibratePhone();
}
}
};
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(listener);
}
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener);
}
private void vibratePhone() {
Vibrator vibrator = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null) {
// Vibrate for 500 milliseconds
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
//deprecated in API 26
vibrator.vibrate(500);
}
}
}
}
}
Note: add <uses-permission android:name="android.permission.VIBRATE" /> permission on manifest file.

Related

App crashes when changes are made to preferences on resume

I'm having an issue with my preference page crashing my app. On the first visit, it acts as expected. But as soon as I revisit the page and try to change a switch, the app crashes. Here's what the XML looks like for my preferences:
xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory
android:gravity="left"
android:title="#string/description_title"
app:iconSpaceReserved="false">
<SwitchPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:key="#string/pallet_pref_key"
android:title="#string/pallet_pref"
app:iconSpaceReserved="false" />
<SwitchPreference
android:key="#string/nose_pref_key"
android:title="#string/nose_pref"
app:iconSpaceReserved="false" />
<SwitchPreference
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:key="#string/finish_pref_key"
android:title="#string/finish_pref"
app:iconSpaceReserved="false" />
</PreferenceCategory>
</PreferenceScreen>
The Java looks like this:
import android.os.Bundle;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.SwitchPreference;
public class SettingsActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings, new SettingsFragment())
.commit();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
public static class SettingsFragment extends PreferenceFragmentCompat {
private SharedPreferences sharedPref;
private boolean pNose;
private boolean pPallet;
private boolean pFinish;
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.root_preferences, rootKey);
sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
sharedPref.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
if(s.equals(getResources().getString(R.string.pallet_pref_key))) {
pPallet = sharedPreferences.getBoolean(s,false);
SwitchPreference pNose = findPreference(getResources().getString(R.string.nose_pref_key));
SwitchPreference pFinish = findPreference(getResources().getString(R.string.finish_pref_key));
if (pPallet) {
pNose.setChecked(false);
pFinish.setChecked(false);
}
}
else if(s.equals(getResources().getString(R.string.nose_pref_key))) {
pNose = sharedPreferences.getBoolean(s,false);
SwitchPreference pPallet = findPreference(getResources().getString(R.string.pallet_pref_key));
SwitchPreference pFinish = findPreference(getResources().getString(R.string.finish_pref_key));
if (pNose) {
pPallet.setChecked(false);
pFinish.setChecked(false);
}
}
else if(s.equals(getResources().getString(R.string.finish_pref_key))) {
pFinish = sharedPreferences.getBoolean(s,false);
SwitchPreference pPallet = findPreference(getResources().getString(R.string.pallet_pref_key));
SwitchPreference pNose = findPreference(getResources().getString(R.string.nose_pref_key));
if (pFinish) {
pNose.setChecked(false);
pPallet.setChecked(false);
}
}
}
});
}
}
}
So basically I'm just trying to make it so only one switch can be enabled at a time. I did some research and found a few threads on here that mentioned I should add this code:
#Override
protected void onResume() {
super.onResume();
// Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onPause() {
super.onPause();
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
I'm thinking that's probably the reason for the crash, but when I add that code below the "OnSharedPreferenceChangeListener() {" statement onResume() and onPause() are greyed out unless I hoist it to the top in which case the this keyword throws an error. Does anyone see what I'm doing wrong?
Here's the error that I get on the crash:

PreferenceFragment doesn't invoke on onSharedPreferenceChanged

onSharedPreferenceChanged isn't called when preferences is changed, I use following code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings2);
getFragmentManager().beginTransaction().replace(android.R.id.content, new Frag()).commit();
}
public static class Frag extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref);
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
System.out.println(key);
}
}
pref.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference android:title="show floating touch" android:defaultValue="false"></SwitchPreference>
</PreferenceScreen>
it doesn't invoke onSharedPreferenceChanged when i change SwitchPreference, why?
the code SwitchPreference doesn't set android:key:
<SwitchPreference android:title="show floating touch" android:defaultValue="false"></SwitchPreference>
when change it to:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference android:key="show_float_toucher" android:title="show floating toucher" android:defaultValue="false"/>
</PreferenceScreen>
it work
I found useful the following link for the same problem :
How to listen for preference changes within a PreferenceFragment?
code sample:
public class PrefActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new PrefFragment()).commit();
}
public static class PrefFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set xml
addPreferencesFromResource(R.xml.pref);
// set texts correctly
onSharedPreferenceChanged(null, "");
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("show_float_toucher"))
{
//TODO
}
}
}
}
Tip: check you minSdkVersion !
best regards!

Preference onClick Not Detected

i have setup an onpreference click listener for a preference but it fails to fire even though the preference is found by the find preference command.
Activity
public class PreferenceActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display the fragment as the main content
setContentView(R.layout.activity_preference);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.replace(R.id.settings, new SettingsFragment())
.commit();
}
}
public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
Context context;
private final String DOB = "date";
private SharedPreferences prefs;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
context = getActivity().getApplicationContext();
Preference dob = findPreference(DOB);
Log.i("test", dob.getKey() + "");
dob.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Log.i("test", "2");
return false;
}
});
}
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
}
}
The preference xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="My Account">
<EditTextPreference
android:key="profile_name"
android:summary="Taylor Swift"
android:title="Username" />
<Preference
android:key="date"
android:summary="N.A."
android:title="#string/date" />
</PreferenceCategory>
</PreferenceScreen>
The log output for "test" correctly displays the key of the preference but the log within the onclick never fires.
I've created simple project with your code and everything seems to be working fine.
Log.i("test", "2");
is being called when I click "Date" field.

SharedPreference Change Listener and custom preference

I have those preference:
<xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<CheckBoxPreference
android:key="pk1"
android:title="#string/pt1"
android:summary="#string/pt1s"
android:defaultValue="false" />
<CheckBoxPreference
android:key="pk2"
android:title="#string/pt2"
android:defaultValue="false" />
<ListPreference
android:key="pk3"
android:title="#string/pt3"
android:dialogTitle="#string/pt3"
android:entries="#array/fontsi"
android:entryValues="#array/fontsiv"
android:defaultValue="0" />
<Preference
android:key="pkb"
android:title="#string/ptb" />
</PreferenceScreen>
And the settings activity:
public class SettingsActivity extends PreferenceActivity {
SharedPreferences.OnSharedPreferenceChangeListener lst;
SharedPreferences prf;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
prf = getPreferenceScreen().getSharedPreferences();
lst = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
Log.i("SettingsActivity","!any preference changen!");
if (key.equals("pk1")) { Log.i("SettingsActivity","!pref PK1 called!"); } }
else if (key.equals("pkb")) { Log.i("SettingsActivity","!pref PKB called!"); }
prf.registerOnSharedPreferenceChangeListener(lst);
}
#Override
protected void onResume() {
super.onResume();
prf.registerOnSharedPreferenceChangeListener(lst); }
#Override
protected void onPause() {
super.onPause();
prf.unregisterOnSharedPreferenceChangeListener(lst); }
...
}
The listener works with all the preferences but e custom preference (the last one, pkb as key)!
That i want to use as a back button.
Anybody knows why ?
Obviously your preference doesn't change any preferences.
Since it doesn't do anything, OnSharedPreferenceChangeListener ignores it.
A possible solution would be to set a clickListener to it like this:
findPreference("pkb").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Log.i("SettingsActivity", "!pref PKB called!");
return false;
}
});

PreferenceActivity Settings not Saved

EDIT: I tried this new code but it still seems they are reset. Can anyone tell me, and propose a solution to my settings being reset?
public class UserSettingActivity extends PreferenceActivity implements OnPreferenceChangeListener{
static SwitchPreference mucus_stamps;
static SwitchPreference fertile_infertil;
static SwitchPreference cervical_mucus;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* Populate the activity with the top-level headers.
*/
#Override
public void onBuildHeaders(List<Header> target) {
Log.i("PROJECTCARUSO","onBuildHeaders");
loadHeadersFromResource(R.xml.preference_headers, target);
}
/**
* This fragment shows the preferences for the first header.
*/
public static class Prefs1Fragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.notification_settings);
}
}
/**
* This fragment shows the preferences for the second header.
*/
public static class Prefs2Fragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.charting_settings);
//findPreference("cervical_mucus").setOnPreferenceChangeListener(
mucus_stamps = (SwitchPreference) findPreference("mucus_stamps");
fertile_infertil = (SwitchPreference) findPreference("fertile_infertil");
cervical_mucus = (SwitchPreference) findPreference("cervical_mucus");
cervical_mucus.setOnPreferenceChangeListener(
new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// string test w/o "==" usage.
if (newValue.equals(false)) {
Log.i("PROJECTCARUSO","false");
mucus_stamps.setChecked(false);
fertile_infertil.setChecked(false);
} else {
Log.i("PROJECTCARUSO","true");
mucus_stamps.setChecked(true);
fertile_infertil.setChecked(true);
}
// true instead of false so the new value gets kept
return true;
};
});
if(!cervical_mucus.isChecked()){
mucus_stamps.setSelectable(false);
mucus_stamps.setEnabled(false);
fertile_infertil.setSelectable(false);
fertile_infertil.setEnabled(false);
} else {
mucus_stamps.setSelectable(true);
mucus_stamps.setEnabled(true);
fertile_infertil.setSelectable(true);
fertile_infertil.setEnabled(true);
}
}
}
protected void onPause()
{
super.onPause();
}
protected void onResume()
{
super.onResume();
}
#Override
public boolean onPreferenceChange(Preference arg0, Object arg1) {
// TODO Auto-generated method stub
return true;
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="#string/pref_chart_profile"
android:textSize="20px">
<SwitchPreference
android:title="#+string/pref_symptothermal"
android:summary="#+string/pref_symptothermal_summary"
android:key="symptothermal"
android:defaultValue="true"
android:layout="#layout/pref_layout"/>
<SwitchPreference
android:id="#+id/cervical_mucus"
android:title="#+string/pref_cervical_mucus"
android:summary="#+string/pref_cervical_mucus_summary"
android:key="cervical_mucus"
android:defaultValue="true"
android:layout="#layout/pref_layout" />
<SwitchPreference
android:id="#+id/mucus_stamps"
android:title="#+string/pref_mucus_stamps"
android:summary="#+string/pref_mucus_stamps_summary"
android:key="mucus_stamps"
android:defaultValue="true"
android:layout="#layout/pref_layout" />
<SwitchPreference
android:id="#+id/fertile_infertil"
android:title="#+string/pref_fertile_infertile"
android:summary="#+string/pref_fertile_infertile_summary"
android:key="fertile_infertil"
android:defaultValue="true"
android:layout="#layout/pref_layout" />
</PreferenceCategory>
</PreferenceScreen>
Depending on what you want.
The value is saved(tested), but "selectable" is not a preference value. Therefore you have to set it when the preferencescreen is launched.
Do this:
Before your oncreate:
SwitchPreference mucus_stamps;
Then above your findPreference("mucus_stamps")
mucu_stamps = (SwitchPreference) findPreference("mucus_stamps");
Now, outside the onclicklistener, you can set it.
if(!mucus_stamps.isChecked()){
mucus_stamps.setSelectable(false);
mucus_stamps.setEnabled(false);
}
(I added "setEnablet" to show you that you can disable it aswell, not just make it "non-selectable". Selectable only says that you can't click anything outside the "off/on" area to change it to on/off.)
Personally I prefer to do it like this:
mucus_stamps = (SwitchPreference) findPreference("mucus_stamps");
mucus_stamps.setOnPreferenceChangeListener(
new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
// string test w/o "==" usage.
if (newValue.equals(false)) {
mucus_stamps.setChecked(false);
mucus_stamps.setSelectable(false);
} else {
mucus_stamps.setChecked(true);
}
// true instead of false so the new value gets kept
return true;
};
});
if(!mucus_stamps.isChecked()){
mucus_stamps.setSelectable(false);
mucus_stamps.setEnabled(false);
}
And, you don't need to implement OnPreferenceChangeListener when you do it the way you or I do. Not that it really matters.
:)

Categories

Resources