I have three button in my activity when I click any of two both will get disable but when I went back to my activity they won't restore the previous state.I have tried to achieve this using shared preference but Couldn't hold button state .Can anyone tell me about the mistake that I'm doing in shared preference.
Here I'm sharing my code with you.
on create method
spStateButton= getApplicationContext().getSharedPreferences("Button_State", 0);
spEditor = spStateButton.edit();
In Activity
public void setButtonState(boolean enabled) {
spEditor.putBoolean("btn_state", enabled);
spEditor.commit();
}
public boolean getButtonState(){
return spStateButton.getBoolean("btn_state", true);
}
button place in my activity
holder.btn_Fwd.setEnabled(getButtonState());
setButtonState(false);
holder.btn_Rec.setEnabled(getButtonState());
setButtonState(false);
You used method setButtonState(boolean enabled) for saving value to shared preference and you always call that method with parameter as false. So in shared preference the key "btn_state" having value always false.
So if you want to enable button for next time activity starts, call something like
setButtonState(true);
You can also use Singleton class to save a status value across app. Create class as below
public class SingleTon {
private static final SingleTon instance = new SingleTon();
private Boolean buttonState = true //initially visible
private SingleTon(){}
public static Boolean getButtonState(){
return buttonState;
}
public void setButtonState(Boolean buttonState){
return instance;
}
public SingleTon getInstance(){
return instance;
}
}
Related
I need that when calling the onBackPressed method, the activity is not destroyed but pauses and stops.
My idea is that it works like when the Home button of the mobile is pressed, which calls onPause and onStop because that way, the activity is not destroyed and when the activity is reopened, onResume is called so that the variables remain the value that when the activity was closed.
Is there any way to do this? If not, is there a way to keep the state of the variables once the activity is closed? I have tried to use SharedPreference but I cannot use them because my variables are of different types than those offered.
If you want to customize the behaviour of your buttons, you have to use in your activity ...
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK){
return true; //To assess you have handled the event.
}
//If you want the normal behaviour to go on after your code.
return super.onKeyDown(keyCode, event);
}
Here is some more information about handling key event.
Although it seems what you want to do is just retain the state of your activity. The best way is to store your data before quitting and call it back when you recreate your activity.
If you want to store temporary data (I mean not save it between 2 boots), one way to do it would be to use sharedPreferences.
//Before your activity closes
private val PREFS_NAME = "kotlincodes"
private val SAVE_VALUE = "valueToSave"
val sharedPref: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
val editor: SharedPreferences.Editor = sharedPref.edit()
editor.putInt(SAVE_VALUE, value)
editor.commit()
//When you reopen your activity
private val PREFS_NAME = "kotlincodes"
val sharedPref: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
sharedPref.getString(SAVE_VALUE, null)
Another way to do it since you cannot use sharedPreferences (because you don't use primitive types), is to use a global singleton.
Here is a Java implementation ...
public class StorageClass{
private Object data1 = null;
private StorageClass instance;
private StorageClass(){};
public static final StorageClass getInstance(){
if(instance == null){
synchronized(StorageClass.class){
if(instance==null) instance = new StorageClass();
}
}
return instance;
}
public void setData1(Object newData) { data1 = newData; }
public Object getData1() { return data1; }
}
Then just use ...
StorageClass.getInstance().setData1(someValue);
... and ...
StorageClass.getInstance().getData1(someValue);
In Kotlin ...
object Singleton{
var data1
}
Which you use with ...
Singleton.data1 = someValue //Before closing.
someValue = Singleton.data1 //When restarting the activity.
I've read a few questions about this, but I wasn't happy with the answers, so I decided do ask about my particular example.
I'm developing and Android App that has a Settings screen with a few configurable integer parameters. All these parameters have a maximum and minimum value. Therefore, everytime the user sets a new value for those parameters, I want to validate them. If the new value is out of the defined bounds, I want to show a Toast informing the user of what went wrong.
On the other hand, because in some situations in my App the user can "spam" a button that may show a Toast, in order to avoid having Toast showing repetedly for a while, I created an Application class with a static Toast that is shown everytime I want to show a toast:
public class MyApplication extends Application {
private static Toast toast;
public static void showToast(Context context, String string){
//(...)
}
}
Back to the Settings page, here's how I implemented it:
public class SettingsActivity extends PreferenceActivity {
private Context context;
static SharedPreferences sharedPreferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
}
public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
setListeners();
}
public void setListeners() {
setListenerA();
//(other listeners to other settings)
}
private void setListenerA() {
findPreference(KEY_PREF_A).setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean isEmpty = newValue.toString().isEmpty();
//(other validations)
boolean isValid = !isEmpty; //&& (other validations)
if(!isValid){
if(isEmpty){
MyApplication.showToast(context, MyApplication.getResources().getString(R.string.toastPreferenceNullValue));
} else if(isAnotherReasonToFail1){
// another Toast
} // else if(other reasons to fail)
}
return isValid;
}
}
);
}
}
}
And here are my problems: MyApplication.getResources() is a non-static method and cannot be called from the static context of class SettingsFragment. Also context is not static (as it should not be) and can't also be referenced there.
I need to show that Toast because otherwise the user wouldn't have a clue why his settings weren't being applied. On the other hand, I need the error message to be stored in the strings.xml file, not only because that's how you do it, but also for future multi-language purposes.
I am not familiar with how Fragments work, and I made the Settings screen like this after reading a few articles (like this one) and some questions here. There might be a different way to make a Settings screen that allows me to do what I want, I just don't know any.
Can someone suggest an approach that fits my problem?
Thanks
EDIT: emerssso solved the resources part. Now the problem is only how to call the Toast without having a context.
Fragment has a getResources() method that is equivalent to calling Application::getResources(). The only caveat is that you have to make sure that the fragment is attached to an activity (i.e. getActivity() != null) or you risk throwing an exception.
See: https://developer.android.com/reference/android/app/Fragment.html#getResources()
More generally, getActivity() can be used to get a valid context whenever the fragment is attached to the activity, as Activity is an implementation of Context.
If you want to have a context reference even after a fragment has detached, you can store a reference to getActivity().getApplicationContext() safely in the fragment for later use, but this is probably not ideal.
I made a class for handling important data changes such as App Purchase Status and other stuff .
For this goal I have created a class which does the setting and reading of the values. but the problem is whenever I call the appIsPurchased() method, the result is true while it hasen't been changed since app installation and its first initial launch.
This is my code:
/**
* Created by neemasa on 5/29/14.
* This class handles more crucial data values within app.
*/
public class AppCore {
private SharedPreferences settings;
private String keyPurchase = "app_purchased";
private Context context;
public AppCore(Context context){
this.context = context;
settings = PreferenceManager.getDefaultSharedPreferences(context);
}
public void setAppInPurchasedMode(String status){
if (status.equals("successful")){
settings.edit().putBoolean(keyPurchase, true).commit();
}else if (status.equals("failed")){
settings.edit().putBoolean(keyPurchase, false).commit();
}
}
public boolean appIsPurchased(){
boolean purchased = false;
if (settings.getBoolean(keyPurchase,true)){
purchased = true;
}
return purchased;
}
}
Question 1st: is there something wrong with my code? if there is then why appIsPurchased() always return true?
Question 2nd: do all values in the shared preferences are true by default?
Meanwhile when I use this class in my code the toast "Purchased!" runs even when app is running for the first time.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AppCore appCore = new AppCore(getApplicationContext());
if (appCore.appIsPurchased()){
Toast.makeText(getApplicationContext(),"Purchased!",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getApplicationContext(),"Not Purchased!",Toast.LENGTH_SHORT).show();
}
}
Actually there is a problem in your code!! thats why its always showing purchased!!
if (settings.getBoolean(keyPurchase,true)){
purchased = true;
}
in this lines if the keyPurchased tag if not used , u are passing true value by default
so when u call
if (appCore.appIsPurchased()){
it always return a true value.. The solution is that make sure that the preference values are set before u call them.. hope this helps
Found It, the problem is that I was thinking
settings.getBoolean(keyPurchase,false)
returns the value of keyPurchased variable but the fact is it only returns the variable itself not its value so I fixed the problem by changing the method of my class to this:
public boolean appIsPurchased(){
return settings.getBoolean(keyPurchase,false);
}
you are setting the default value to true, so either your sharedpreference does not contains an entry for key_purchased or setAppInPurchasedMode is never called or is called wit status successful. On the minor side, your
public boolean appIsPurchased(){
boolean purchased = false;
if (settings.getBoolean(keyPurchase,true)){
purchased = true;
}
return purchased;
}
can be implemented like:
public boolean appIsPurchased(){
return settings.getBoolean(keyPurchase, false);
}
about setAppInPurchasedMode, if I were in you I would change the way you compare status, this way:
public void setAppInPurchasedMode(String status){
if ("successful".equals(status)){
settings.edit().putBoolean(keyPurchase, true).commit();
} else if ("failed".equals(status)){
settings.edit().putBoolean(keyPurchase, false).commit();
}
}
the difference is that if status is null, the way you implemented will crash your application with NPE. With my implementation you'll get false, because "successful" instanceof null is always false, and instanceof is the first check for equals
For those still having a problem, remember to apply the changes to your preferences.
private SharedPreferences sharedPreferences ;
private SharedPreferences.Editor sharedPreferencesEditor;
sharedPreferencesEditor.putBoolean("myVariable", false);
sharedPreferencesEditor.apply();
I need some help with an android project I am working on. I am trying to use switch preferences to send a certain text. Basically, it the user switches the switch from off to on, I want the phone to send a text saying "on". Then when the user turns the switch from on to off, it sends a text saying "off". All I need is to be able to see what the current state of the switch is and then if it's off, call a "turn on" method and vice-versa.
I've never asked a question like this, so I don't really know what part of my code to post.(If asked, I can post most of my code.) I think it has something to do with the onPreferenceChangeListener, but I'm not sure how to implement it. Any ideas?
Edit: Here is the main activity class:
public class MainActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
public static final String KEY_ROOM1_SWITCH = "switch_room_1";
private SwitchPreference mSwitchPreference1;
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
//This is a sample of one of 4 switches that are being used. They are all basically the same, but with different variables
if (key.equals(KEY_ROOM1_SWITCH)) {
boolean checkedornot1;
SharedPreferences myPreference=PreferenceManager.getDefaultSharedPreferences(this);
checkedornot1 = myPreference.getBoolean("switch_room_1", false);
if (checkedornot1 = true)
mSwitchPreference1.setChecked(true);
else
mSwitchPreference1.setChecked(false);
}
}
}
Do I need to grab the value that is stored in the shared preferences and make my choice based on that? or is there something else I am missing?
Edit your class that extends PreferenceActivity and add the private variable: private OnSharedPreferenceChangeListener listener;
Create and register your listener within the onResume method:
public void onResume() {
super.onResume();
listener = new OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
if (key.contains("your switchpreference key name")
if (sp.getBoolean("your switchpreference key name",false) {
sendOnSMS();
} else {
sendOffSMS();
}
}
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(listener);
}
Unregister your listener within the onPause method:
public void onPause() {
super.onPause();
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(listener);
}
Implement the sendOnSMS and sendOffSMS methods.
I have a problem with SharedPrefences and initializations.
My application has a login where you insert an user, and for that user, you have a specific preferences... so, I need to save preferences according to the user to load it later.
I though that SharedPrefences would be the solution, and it really is I think, but I have a problem to initialize they: I have an Activity class called Options. It has static functions that returns the value of the options... but I have a problem, I call that functions before I have create that activity (intent), so I think that the functions are returning the last value that the last user has selected on the options...
How can I load the options before that calls?
I though to use first of all an Intent sending extra data with the user and in onCreate() of the Options, initialize they, but if I make an intent, then the Options will appear (xml will load).
Any help pls?
Try something like this.... adding methods for each variable you want to save.
public class PreferenceManager {
private static PreferenceManager self;
private SharedPreferences preferences = null;
private SharedPreferences.Editor editor = null;
private boolean isInitialised = false;
private static final String MY_PREFERENCE = "mypreferencekey";
private String myPreference = null;
public void initialise(Context context) {
if (!isInitialised) {
preferences = context.getSharedPreferences("MyPreferencePlace", Context.MODE_PRIVATE);
editor = preferences.edit();
loadPreferences();
isInitialised = true;
}
}
public static PreferenceManager getInstance() {
if (self == null) {
self = new PreferenceManager();
}
return self;
}
private PreferenceManager() {
}
public void setPreference(String newPreferenceValue) {
this.myPreference = newPreferenceValue;
savePreferences();
}
public String getPreference(){
return myPreference;
}
private void savePreferences() {
editor.putString(MY_PREFERENCE, myPreference);
editor.commit();
}
private void loadPreferences() {
myPreference = preferences.getString(MY_PREFERENCE, null);
}
}
All the SharedPreferences need is a context and it can be initialized. As your application always opens an Activity to start with, you always have a context to work with.
I would advise you to wrap the SharedPreferences in a Singleton class and just pass a context as parameter at the getInstance method. You should be able to access your shared preferences at all Activities this way.
I work on the dependency injector for android, and content of shared preferences is already injectable into annotated fields ( see: https://github.com/ko5tik/andject , PreferenceInjector). Patches and improvements are welcome. Saving of preferences comes soon