Android boolean preference problem - java

I want to have the status of a checkbox be saved into my prefs.
I set a listener on the checkbox, and if it is checked I do a prefs.putBoolean("cbstatus", true), and it is it unchecked i do a prefs.putBoolean("cbstatus", false);
Trouble is, in my onStart() when I get prefs, my Boolean getcbstatus = prefs.getBoolean("cbstatus", false); will always return a true, regardless of how my listener should have set that status previously.
What am I doing wrong? I have working prefs for other things like spinners, textviews, and edit texts, but what should be the simplest type (a boolean) is giving me a hard time.
I've even tried taking out all code related to listeners and pref setting for this checkbox, so that the only code in the entire activity that deals with the checkbox is in the line
Boolean getcbstat = prefs.getBoolean("cbon", false);
if (getcbstat = true) {
cb1.setChecked(true);
}
else {
cb1.setChecked(false);
format.setVisibility(View.VISIBLE);
}
Since there is no cbon preference (i deleted them all), it should return false by default and the box should be unchecked since. cb1, of course, is the name of my checkbox.
Any ideas?
Update on the code:
OnClickListener cb = new OnClickListener() {
public void onClick(View v) {
if (cb1.isChecked()) {
prefs.putBoolean("cbon", true);
}
else {
prefs.putBoolean("cbon", false);
}
}
};
And in the onStart():
Boolean getcbstat = prefs.getBoolean("cbon", false);
cb1.setChecked(getcbstat);

You've accidentally assigned it to true in your if statement.
Change it to this
if (getcbstat == true)
[Edit -- How to use shared preferences (instead of Java's preferences class)]
How to use SharedPreferences:
private SharedPreferences mPref;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
mPref = getSharedPreferences("my_prefs_file", MODE_PRIVATE);
//Other onCreate code goes here...
}
//Example of where you might want to save preferences
#Override
protected void onPause() {
super.onPause();
Editor prefEdit = pref.edit();
prefEdit.putBoolean("cbon", true);
prefEdit.commit();
}
When you need to read it later:
//Example of where you might want to save preferences
#Override
protected void onResume() {
super.onResume();
boolean getcbstat = pref.getBoolean("cbon", false);
}
It would probably be a good idea to make the pref variable class level and get the preferences object in the onCreate section. Change "my_prefs_file" to whatever you like, but remember that that string is what you will use to access that that particular set of preferences from within your application. I also recommend using constants instead of raw strings for the access keys (like "cbon").
Good luck:)

Related

Quit showing an Activity when CheckBox is checked

I have got a DialogActivity with a "do not show anymore" CheckBox.
What I need it to do is exactly like the CheckBox says. When the CheckBox is checked the Activity doesn't have to be displayed to the user anymore, no matter if the app is restarted or killed.
public class PopUpInfoActivity extends Activity {
static final String PREFS = "preference_file";
#Override
public void onCreate(Bundle state) {
setContentView(R.layout.popupinfo_layout);
CheckBox chk = (CheckBox) findViewById(R.id.dontshow_checkbox);
chk.setChecked(PreferenceManager.getDefaultSharedPreferences(this).getBoolean("value", false));
chk.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//store isChecked to Preferences
SharedPreferences settings = getSharedPreferences(PREFS, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("isChecked", false);
PreferenceManager.getDefaultSharedPreferences(PopUpInfoActivity.this).edit().putBoolean("value", isChecked).apply();
}
});
Intent intent = new Intent(PopUpInfoActivity.this, ChordsListActivity.class);
if (!chk.isChecked()) {
// run activity
super.onCreate(state);
} else {
startActivity(intent);
}
}
}
If I do it like this the App crashes.
If I replace the else with:
else {
onStop()
}
The code doesn't work as expected.
I would really appreciate if you could help me fix this problem!
EDIT:
This is what I have got in my ChordsListActivity, which is the activity that calls the PopUpInfoActivity but I do not get what I should put in my if() statement.
Intent legendaIntent = new Intent(ChordsListActivity.this, PopUpInfoActivity.class);
if(/*what's here?*/)
startActivity(legendaIntent);
In that MainActivity read your preference key (Show_Dialog), if it is true then launch PopUpInfoActivity otherwise launch ChordsListActivity.
The logic should be in the Mother Activity
In your PopUpInfoActivity you should only edit the preference key to false if the user checks out the ChekBox
To do so, please create a preferences.xml file under res/xml, inside this file you have to create a key (Boolean) that you will store inside the status of PopUpInfoActivity.Checkbox, the default will be (True).
here is an example
<CheckBoxPreference
android:key="Show_Dialog"
android:defaultValue="true" />
From your MainActivity you should read this value like this:
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
Boolean showDlg = sharedPref.getBoolean("Show_Dialog", true);
if the showDlg is true then you popup your dialog, otherwise continue what you want to do.
of course you need to change the value of Show_Dialog if the user checks the checkbox, you can do it like this:
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor preferencesEditor = sharedPref.edit();
preferencesEditor.putBoolean("Show_Dialog", false);
preferencesEditor.commit();
in this way, you can be sure that your main activity will read the Show_Dialog as false next time the user launches your application
Good luck
Firstly, super.onCreate() must be the first call in any Activity's onCreate().
Secondly, store the value of the SharedPrefence in a boolean instead of directly setting the CheckBox, and use that before setContentView() to finish your current Activity and launch the next one if true. If not, carry on with the UI stuff and anything else you need.

Is there a way to hold up onSharedPreferenceChangeListener until last change?

In settings activity, I have multiple fields, once the user press save all these fields will be stored separately as key-value in sharedPreference.
The problem is every editor change e.g.
editor.putString(SERVER, server.toString());
will fire onSharedPreferenceChangeListener
While I only need to fire it after update all values..
Is there any way to achieve this requirement?
Many thanks
There's only a way to do that. You can put editor.putString(SERVER, server.toString()); in runtime code, such as you pressing a button. Once the activity gets destroyed call editor.commit(); within onDestroy() method, it will saves the value and fires onSharedPreferenceChangeListener. Simply, waiting for the user to close the activity first which means that users already changed all of their settings.
Note: please make sure that editor is an instance variable or make a field for it.
EDIT
Here's an example for you:
public class SettingsActivity extends Activity {
// a field for preference
private SharedPreferences.Editor editor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences sharedpreferences = getSharedPreferences("MyPreference", Context.MODE_PRIVATE);
editor = sharedpreferences.edit();
// for example, edit the value using a button at runtime
Button button = (Button)findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editor.putString(SERVER, server.toString());
}
});
...
}
#Override
protected void onDestroy(){
// call commit to save all changes
editor.commit();
super.onDestroy();
}
}

How to know if android application was crashed last time

I have an android application and i want to know on the startup of this application whether my application crashed previously or not. This crash may be crash enforced by OS on app for saving memory or any other reason. It may not be caught in UnhandledExceptionHandler. What i have handled so far is given below and it is not caching those native os related and memory enforced cases
UncaughtExceptionHandler handler = new UncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(handler);
EDIT:
Please don't suggest 3rd party libraries.
This would be happen via SharedPreferences, first of all when you just enter your app in the MainActivity create a boolean variable called crash and save it to your SharedPreferences with a value of false, then when catching a crash, just resave this variable with the value true and this will automatically override the crash value stored before.
To save the value:
private void savePreferences(String key, String value) {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(this);
Editor editor = sharedPreferences.edit();
editor.putBoolean("crash", false);
editor.commit();
}
To load the saved value:
private void loadSavedPreferences() {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(this);
boolean crash = sharedPreferences.getBoolean("crash", false);
if(crash){
// then your app crashed the last time
}else{
// then your app worked perfectly the last time
}
}
So, in your crash handler class, just save the value to true:
p.s. this must run for all unHandled Exceptions whatever from the app of from the OS.
public class CrashHandler extends Application{
public static Context context;
public void onCreate(){
super.onCreate();
CrashHandler.context = getApplicationContext();
// Setup handler for uncaught exceptions.
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
#Override
public void uncaughtException (Thread thread, Throwable e)
{
handleUncaughtException (thread, e);
}
});
}
public void handleUncaughtException (Thread thread, Throwable e)
{
e.printStackTrace(); // not all Android versions will print the stack trace automatically
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(context);
Editor editor = sharedPreferences.edit();
editor.putBoolean("crash", true);
editor.commit();
}
}
I have found a hack and it worked for me. One can check if its app was crashed if one knows whether user left the app or shut down the system or did any such thing or the app itself got closed. If the app itself got closed it means that it was crashed otherwise it wasn't (in cases such as user closing app or shutting down system).
With help of shared preferences one can store and get a variable which will tell if app was crashed or not the code is given below
public class Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
boolean appcrashed=false;
super.onCreate(savedInstanceState);
boolean didUserLeft=loadSavedPreferences();
appcrashed=!didUserLeft;
if(appcrashed)
Toast.makeText(this, "App Crashed!", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "App OK!", Toast.LENGTH_LONG).show();
savePreferences(false);
UnhandledExceptionHandler handler = new UnhandledExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(handler);
}
public boolean loadSavedPreferences() {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(this);
boolean didUserLeft = sharedPreferences.getBoolean("didUserLeft", true);
return didUserLeft;
}
public void savePreferences(boolean value) {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(this);
Editor editor = sharedPreferences.edit();
editor.putBoolean("didUserLeft", value);
editor.commit();
}
#Override
public void onResume(){
super.onResume();
savePreferences(false);
}
#Override
public void onDestroy(){
savePreferences(true);
}
#Override
public void onPause() {
super.onPause(); // Always call the superclass method first
savePreferences(true);
}
#Override
public void onUserLeaveHint(){
savePreferences(true);
}
1) When Android kills and restarts your app, static variables are set to null (more precisely, initially set to null and a bit later, very soon, set to their initial values; a static initializer may see null in variables that has not yet been initialized). So if some static variable is set to null whereas the data in a Bundle say the user has been doing something, there was a process restart (I assume you know what Bundle is for in onCreate(Bundle)).
2) You may have a flag in persistent storage; the flag will be, say, set to true when the application has started and set to false before it finishes normally. If that flag is true when the application starts, there was a crash.
(There is still a small possibility that the app crashes after it has closed normally... But is it important for you?)
3) You may save the app's pid in persistent memory (see myPid()).

can't attach an OnPreferenceChangeListener to my preferences

First of all - I have tried almoust EVERY post I could find here on stackoverflow, but none solved it for me.
I am using a begginners guide to create a simple app - hence all of the comments.
my problem is that whenever I try attaching a preference to "this" the listener (i have implemented my class as a listener: settings activity implements Preference.OnPreferenceChangeListener) my app will crash!
I'm trying to make the key of each preference it's summary.
Please help me - I've tried every relavent result and did not help. thanks alot!
This is my Settings Activity class
public class SettingsActivity extends PreferenceActivity
implements Preference.OnPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add 'general' preferences, defined in the XML file
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment1 fragment1 = new Fragment1();
ft.replace(android.R.id.content, fragment1);
ft.commit();
// For all preferences, attach an OnPreferenceChangeListener so the UI summary can be
// updated when the preference changes.
**Here I need to somehow attach the preferences to the listener - but I can't seem to do it without the app crashing**
}
/**
* Attaches a listener so the summary is always updated with the preference value.
* Also fires the listener once, to initialize the summary (so it shows up before the value
* is changed.)
*/
private void bindPreferenceSummaryToValue(Preference preference) {
// Set the listener to watch for value changes.
//preference.setOnPreferenceChangeListener(this);
// Trigger the listener immediately with the preference's
// current value.
onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.getContext())
.getString(preference.getKey(), ""));
}
#Override
public boolean onPreferenceChange(Preference preference, Object value) {
String stringValue = value.toString();
if (preference instanceof ListPreference) {
// For list preferences, look up the correct display value in
// the preference's 'entries' list (since they have separate labels/values).
ListPreference listPreference = (ListPreference) preference;
int prefIndex = listPreference.findIndexOfValue(stringValue);
if (prefIndex >= 0) {
preference.setSummary(listPreference.getEntries()[prefIndex]);
}
} else {
// For other preferences, set the summary to the value's simple string representation.
preference.setSummary(stringValue);
}
return true;
}
}
If you want to set the current preference value to it's summary, just add in your preference.xml
android:summary="%s"
now you dont nead the listener
You have to do that in onResume() and onPause() as described in this document: http://developer.android.com/guide/topics/ui/settings.html
Just search for onResume in it.
I use this in my App and its works without Problem
Have a try, maybe it works
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
//....... Code
}
Android Settings Guide

How to reflect changes in preferences to class?

I created a simple class "User" that has an attribute String username. I'm assuming that since Android uses Java, I can create custom classes and it'll use them accordingly. In my SettingsActivity.java, I have:
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_general);
SharedPreferences sharedPref = getPreferenceScreen().getSharedPreferences();
EditTextPreference editTextPref = (EditTextPreference) findPreference("username");
editTextPref.setSummary(sharedPref.getString("username", "Default"));
//sharedPref.registerOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences arg0, String arg1) {
// Get current summary
Preference pref = findPreference(arg1);
if(pref instanceof EditTextPreference){
EditTextPreference etp = (EditTextPreference) pref;
pref.setSummary(etp.getText());
MainMenu.user.setName(etp.getText()); //This is where I try to update my class
}
}
As of right now, whenever I change the value of my EditTextPreference widget, it doesn't update the public static user object located in MainMenu. Also, a followup question - since Android saves the preferences with each instance of app launch, how would I update my User.username String on startup?
In onPostCreate remove the comment //
sharedPref.registerOnSharedPreferenceChangeListener(this);

Categories