I am attempting to do something I'm unsure of, and need someone to provide feedback.
I have 2 preferences. One of them, I want dependent on the other one's value.
Example: My "Notification Mode" Preference has 2 options: "Timer", and "Reminder"
If the User chooses the "Timer" option, I want my other Preference available to set time.
Otherwise, I want the Preference for setting the Timer to be disabled.
Here's what I've come up with inside my pref changed listener:
if (key.equals(PREF_NOTIFICATION_MODE)) {
Preference notifModePref = findPreference(key);
notifModePref.setSummary(sharedPreferences.getString(key, ""));
if(!notifModePref.equals("Timer Mode")) {
Preference timerDurationPref = findPreference(PREF_TIMER_DURATION);
timerDurationPref.onDependencyChanged(notifModePref, true);
} else if(notifModePref.equals("Timer Mode")) {
Preference timerDurationPref = findPreference(PREF_TIMER_DURATION);
timerDurationPref.onDependencyChanged(notifModePref, false);
}
}
I'm not sure if I'm doing this correctly, or if onDependencyChanged is proper.
I accomplished the Goal inside of if(key.equals) by referencing the Preference in question and using if statements and a combination of using onDependencyChanged(), and setting .isEnabled(boolean) as required.
Related
I am making one android app where one setting is must every user need to update that which is pincode.
So after successful login, if the user has not updated pincode yet, it needs to be updated mandatory before navigating to any other screen.
What is the best way to implement this? Any Ideas?
Update:
After answer, I meant to say that setting I will be fetching from firebase database as boolean flag. So my actual query is how to show that as a mandatory to get the user update? (i.e) either navigating to different activity or showing popup and getting the setting etc. I need UI design ideas.
What is the best practice?
It is not clear what is the point of this, and if you have a server side that controls that stuff, but I'll try to give a help.
If you have a Server controlling authentication:
On login, call the API of your service to check if has happened or not. You could save the answer in a "shared preference" (Android Documentation), so you don't call your API every time.
If you only want to have the application on a client side:
Use 1 to store values that indicate if the desired action was performed or not, which is verified right after the login.
EDIT:
If the action is mandatory, you could send the user to an activity to update the pin, this will happen until the action is performed.
Client side approach:
You can use SharedPreferences to persist a value, like a simple boolean, that will inform you if that the user already updated the pincode or not.
I would recommend you to perform the check in the onResume() of your Launcher Activity.
Putting it simple and explicit:
public static final String PREF_FILE_NAME = "PrefFileName";
public static final String PREF_IS_PIN_CODE_UPDATED = "PREF_IS_PIN_CODE_UPDATED";
#Override
protected void onResume() {
super.onResume();
SharedPreferences prefs = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
Boolean isPinCodeUpdated = prefs.getBoolean(PREF_IS_PIN_CODE_UPDATED, false);
if (isPinCodeUpdated) {
// You can proceed
} else {
// Force the user to update the pin code, by prompting for instance a dialog where he can change the pin with setCancelable(false)
}
}
After you know that your user already updated the pin code you just need to set the preference to true.
SharedPreferences.Editor editor = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE).edit();
editor.putBoolean(PREF_IS_PIN_CODE_UPDATED, true);
editor.apply();
After this every time the user opens the app it will pass in the onResume() method and your isPinCodeUpdated var will be true and the app should proceed as usual.
From you question I am assuming that you didn't want a response in terms of UI but how could you have the information persisted.
Note: This implementation fails for multiple users in the same device. With few tweaks you can make it work for multiple users in the same device but in my opinion this verification should be done server side.
I have a little doubt about the SharedPreferences in Android.
To delete a preference, we mainly have two options:
First:
SharedPreferences.Editor edit = (Editor) getSharedPreferences(Constants.APP_DEFAULT_PREF, MODE_PRIVATE).edit();
edit.putString(Constants.PREF_ACC, null);
edit.commit();
Second:
SharedPreferences.Editor edit = (Editor) getSharedPreferences(Constants.APP_DEFAULT_PREF, MODE_PRIVATE).edit();
edit.remove(Constants.PREF_ACC);
edit.commit();
In either case, fetching Constants.PREF_ACC value from SharedPreferences will return null.
I was wondering which one should I prefer. Is there any memory related issues in either of them? What will the System.gc behavior be with them?
Theoretically remove is better than put(null), because it removes both the key and value (once committed) instead of mapping (and keeping) the key to a null value.
But judging by the Android 5.1.1 implementation, they are equivalent :
...
String k = e.getKey();
Object v = e.getValue();
// "this" is the magic value for a removal mutation. In addition,
// setting a value to "null" for a given key is specified to be
// equivalent to calling remove on that key.
if (v == this || v == null) {
if (!mMap.containsKey(k)) {
continue;
}
mMap.remove(k);
} else {
...
That is also what one of the putXXX methods (putStringSet) documentation says :
Passing null for this argument is equivalent to calling remove(String)
with this key.
I would recommend using remove.
When we putString or remove nothing is done, it is just marked in the Editor as TO BE DONE and gets done only when commit is called
And when the commit is called all the remove calls are executed before the put calls. So it is better to use the remove calls to remove something from the Editor.
Judging by the docs of the interface SharedPreferences.Editor for remove(String) :
Mark in the editor that a preference value should be removed, which
will be done in the actual preferences once commit() is called.
Note that when committing back to the preferences, all removals are
done first, regardless of whether you called remove before or after
put methods on this editor.
… and for putInt(int) :
Set an int value in the preferences editor, to be written back once
commit() or apply() are called.
… there seem to be only one striking difference: remove(String) calls will be "done first, regardless of whether you called remove before or after put methods".
That said, I really doubt the actual order of execution won't matter much to average use-cases, so you could just choose either one of those methods and be completely fine.
p.s., I'm still looking for the concrete class of SharedPreferences.Editor which might provide more clues about this. Will update as soon as I found one.
I am trying to develop an app that requires certain values to be set by the users at the app's first startup only, because i don't wanna bother them frequently inputting the values everytime they launch the app. My app has a single activity main and uses certain values that are inputted by the users at first startup. How can I make this possible.
Please explain me elaborately . :-)
You should use SharedPreferences to keep a track of the first use.
In the onCreate Method of your Activity (Startup activity), you could do something like this,
SharedPreferences userPrefs = getSharedPreferences("UserPrefs", 0);
Boolean firstUse = userPrefs.getBoolean("firstUse", true);
if(firstUse){
//this implies it is the first use of the app
//also once you are done implementing the logic for first use you need to put firstUse as true
SharedPreferences.Editor editor = userPrefs.edit();
editor.putBoolean("firstUse", false);
editor.commit();
}
else{
//take the user directly inside the app
}
Also, if you plan to save user information in the first use, look at different ways of storing data here.
show the alert initially and after getting the input values keep it in preference and next time check whether the required values existing or not. If it is already there avoid popup
For getting more information about shared preference check this link http://www.vogella.com/tutorials/AndroidFileBasedPersistence/article.html
preferences_statusFirst.getString("boot", "");
if (status.length() <= 0)
{
showDialog(DIALOG_birth);
editor_boot.putString("boot", "1");
editor_boot.commit();
}
else
{
}
}
When the user updates a shared preference through a subclass of PreferenceActivity I check whether or not the new value is valid at the given time. If not the value should be changed back in the onSharedPreferenceChanged method.
This works so far. I set an OnSharedPreferenceChangedListener, the method gets called. The user-set value will be overwritten and the new value will be used in the app, however when I open this specific preferences value (in this case a ListPreference) again the wrong list item will be selected (the one the user selected, not the one set in the Listener). I tried overwriting the value with both:
mPrefs.edit().putString("answers", value.toString()).commit();
mPrefs.edit().putString("answers", value.toString()).apply();
Are there additional steps I need to take to update the ListPreference? After restarting the PreferenceActivity the value will be displayed correctly.
try to use Override method SharedPreferenceChanged
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key.equals(KEY)) {
Preference ServicePref = findPreference(key);
// Set summary to be the user-description for the selected value
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
}
}
I found a way to solve this issue by setting the value manually as described here:
http://liquidlabs.ca/2011/08/25/update-preference-value-without-reloading-preferenceactivity/
OK, so I'm playing around with an android app.
The 90% use case is that users want to go straight to the primary list screen to find what they're looking for. That's what I want as my default screen.
The first time a user loads the app however, some configuration is required before their list screen is of any value to them.
So my question, is how I can go about displaying the configuration activity the first time the app is opened up, and then the list screen for future openings.
I also want to put a demo button on the configuration screen, so I suppose more than just detecting that it's the first time, I specifically want to detect whether the user has performed certain configurations within the first screen.
After the first time the user has loaded the app you could store the details of whether user has performed the configurations in SharedPreferences.
protected void storeSharedPrefs(String value) {
/*
* Storing in Shared Preferences
*/
editor.putString("first", value);
editor.commit(); //Commiting changes
}
Check each on time application is loaded, whether its the first time and configuration details has been entered correctly by checking SharedPreferences
private boolean first_time_check() {
/*
* Checking Shared Preferences if the user had pressed
* the remember me button last time he logged in
* */
String first = uPreferences.getString("first", null);
if((first == null)){
return false;
}
else
return true;
}
i like dweebsonduty's method. a similar way to do this is to save their configuration information in files on the SD card. your app could start out by checking for those files and loading the information. if the load is successful, it moves on to the next activity, if not it starts the appropriate activity to prompt the user for input.
I have done this same thing, but instead of swiching activities i just switch views until i have all the info i need, and then move on.
Many applications actually store the current version in SharedPreferences, and check against it for if an update has been installed. Its a clever way of achieving a "what's changed" popup, or making sure that some settings get set (I would be wary of just having a boolean flag because if you ever want to add an additional setting, you will need a second flag and it gets messy after the third, etc.).
String VersionValue = "v.1.0";
final String PREFS_NAME = "MyPrefsFile";
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
if (settings.getBoolean(VersionValue, true)) {
//the app is being launched for first time, do something
NewDialogFragment newFragment = new NewDialogFragment();
newFragment.show(getFragmentManager(), "New");
// record the fact that the app has been started at least once
settings.edit().putBoolean(VersionValue, false).commit();
}
You could do it this way and still get the same result I tried it its a small workaround if u do not fully understand how to check if the app is updated. Instead with this code you can just simply change the String VersoinValue to your current app version and android will think the app is a new first time app and will only display the code u wrote once until you change VersionValue on your next update. (:
How will you be storing the configuration?
If it is in SQLlite you could just create a table called firstuse and put a field in there called hasbeenused and make it null. Then when the app is used you can put a 1 in there. Then you can read it each time your app loads and if that field = 1 then go to your next activity.