I have a shared preference with no default value defined in the xml because I would like to set the default value programmatically when the main activity is created. The preference in question should either be the device language (if that language is available), otherwise the first available language, where the languages are defined in the appropriate xml as a string array.
I currently have, inside the main activity's onCreate method, the following
SharedPreferences preferences = getSharedPreferences(
getString(R.string.shared_prefs_key),
MODE_PRIVATE
);
String detailLanguage = preferences.getString(
getResources().getString(R.string.detail_display_language),
""
);
if (detailLanguage.isEmpty()) {
String deviceLanguage = Locale.getDefault().getLanguage();
String[] availableLanguages = getResources().getStringArray(R.array.pref_entry_values_detail_display_language);
boolean deviceLanguageSupported = false;
for (String availableLanguage : availableLanguages) {
if (deviceLanguage.equals(availableLanguage)) {
deviceLanguageSupported = true;
break;
}
}
preferences.edit()
.putString(
getResources()
.getString(R.string.detail_display_language),
deviceLanguageSupported ? deviceLanguage : availableLanguages[0]
).commit();
Debugging this code on the first run it enters the above if statement and sets the preference but the preference doesn't show as selected in the preference activity first time around (if I then select it myself, from then onward it appears selected as something).
Am I missing something? I am fairly new to Android. I tried the above based on some other similar SO questions.
PreferenceActivity and PreferenceFragment read preferences from a default preference file. To get access to those preferences you should use PreferenceManager.getDefaultSharedPreferences(context) method.
I am guessing that this is the reason you aren't seeing your changes: you write them to getString(R.string.shared_prefs_key) rather than to the default one.
Try changing your first line to this:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
Related
I am working with a service class that needs to know if the application is running in background or not. To do so, I created a boolean variable called activityVisible in my service. I need to update it constantly to know wether the app is in background or active.
I do this by sending true on the onResume() method in my activity like this:
intent.putExtra("Activity Visible", true)
and false on the onPause() method like this:
intent.putExtra("Activity Visible", false)
However, I print the extra in my service and it is always getting true. What I think it is happening is that once you put an extra, you cannot update its value, and that may be the reason it is not working.
Any way I can do the same in a different way? Or a solution to the way I am implementing this?
You can use SharedPreference to store the current state of the app.
to reference to the SharedPreference
SharedPreferences sp = getSharedPreferences("prefs", Context.MODE_PRIVATE);
to set a boolean in the shared preference, you need to use its editor, so apply this code in onPause, and onResume, while changing the "isVisible" value based on your need
boolean isVisible = true;
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("activity_visible", isVisible);
editor.apply(); // use apply to confirm the edit
and in order to get the value stored, you can simply refer to it using
boolean valueStored = sp.getBoolean("activity_visible", false /* Default value if not existed */);
Log.d("Activity State: ", "Boolean: " + valueStored);
and do whatever you want with that valueStored.
I am working on android project built partially in kotlin and partially in java. I am trying to pass information from a kotlin fragment class to a java class. I have come to see that there is a problem with the passing of information as I do not receive the needed value. After some debugging I have seen that the information is successfully stored, however when the information from shared preferences is accessed, only the default value is returned.
This is the code in the kotlin class. When a button is clicked it changes the value of a boolean variable to the opposite one, sets the text of a button to true/false and saves the value of the variable in shared preferences.
btnStyle.setOnClickListener() {
styleHasChanged = !styleHasChanged;
if(styleHasChanged == true){
btnStyle.setText("true")
}else{
btnStyle.setText("false")
}
val sharedPref : SharedPreferences?= activity?.getPreferences(MODE_PRIVATE);
sharedPref?.edit()?.putBoolean("bla", styleHasChanged)?.apply()
}
This is the java class. Shared preferences is called inside a function which chooses a filepath based on the received value.
public static String getHtmlContent(Context context, String htmlContent, Config config) {
SharedPreferences sharedPreferences = context.getSharedPreferences("bla",MODE_PRIVATE);
boolean hasStyleChanged = sharedPreferences.getBoolean("bla", false);
//moj
String cssPath;
if (!hasStyleChanged) {
cssPath = String.format(context.getString(R.string.css_tag), "file:///android_asset/css/Style.css");
} else {
cssPath = String.format(context.getString(R.string.css_tag), "file:///android_asset/css/Style2.css");
}
This is where the problem arises. Shared preferences in the java class always fetches the default value, no matter if the button is clicked or not.
The getPreferences method implicitly uses the class name of the Activity as the preference file name. By passing "bla" as the file name to getSharedPreferences you're trying to fetch the saved value from a different file.
If you would like to access the same preferences accross your application, then either use getSharedPreferences (for both writing and reading the preference) with the same file name, or use the getDefaultSharedPreferences static method of PreferenceManager to obtain the default SharedPreferences instance.
You should change your code to something like this:
val sharedPref : SharedPreferences? = activity?
.getSharedPreferences("someFileName", MODE_PRIVATE)
sharedPref?.edit()?.putBoolean("bla", styleHasChanged)?.apply()
And the Java part:
SharedPreferences sharedPreferences = context
.getSharedPreferences("someFileName", MODE_PRIVATE);
boolean hasStyleChanged = sharedPreferences.getBoolean("bla", false);
Your context.getSharedPreferences("PreferencesFileName",MODE_PRIVATE) should be the same even when using the activity?.getPreferences("PreferencesFileName",MODE_PRIVATE). In you code it's not like that.
Plus a simple suggestion, because I'm not sure if you're clear on that. The bla is the key for your boolean value not your Preferences file name. I mean it could be, but it's better to separate.
In MainActivity.java I write
SharedPreferences pref = getApplicationContext().getSharedPreferences("My_Pref" , 0);
Then I create object of Editor to put data in it
Editor edit = pref.edit();
Then I put data
edit.putString("1","Hello");
edit.commit(); / edit.apply();
In Second.java, I get preferences:
SharedPreferences pref = getPreferences(0);
then I try to receive data like
pref.getString("1",null);
and set it to text of textview. But this does not work.
Also, how do I access Preferences and editor in other java classes properly? I cannot understand the concept.
You are writing to and reading from different preference files. Use the same file and it should work.
To get an instance of SharedPreferences you do this:
1) In activity MainActivity:
SharedPreferences pref =
getApplicationContext().getSharedPreferences("My_Pref" , 0);
2) In activitySecond:
SharedPreferences pref =
getPreferences(0);
The first form opens preference file "My_Pref", the second form opens a file named after your activity class, i.e.: "Second". So they are reading and writing in different files.
I always use this form to open a preferences file:
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(this);
Try this way
public void saveToSharedPrefrence(Context context, String word) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = sharedPreferences.edit();
if (sharedPreferences.contains("history")) {
preExistRemove(word, context);
} else {
editor.putString("history", word.trim());
editor.commit();
}
}
Check this for more details
Get the context of your activity
Context shrdContext= ActivityClass.getContextOfApplication();
Now pass the context to get your shared preferences in your another class
SharedPreferences myPrefs= PreferenceManager.getDefaultSharedPreferences(shrdContext);
You have 3 ways to access preferences for a Android application.
The first you used is
SharedPreferences pref = getApplicationContext().getSharedPreferences("My_Pref" , 0); is the first one. With this you can read and write to a custom-named shared preference file. In your case the name of your file would be My_Pref.
This one is useful if you want to have differents preferences differents domain as it allow you to create many shared preferences with differents names. (ex : preferences for timezone, preference for your user).
The second getPreferences(int) allow to access preferences for an Activity and is bind closely to the activity calling it. The file created is named using the Activity name. In your case Second.
The third method PreferenceManager.getDefaultSharedPreferences(Context) create a shared preference file like the first method, but this time the file is named using your application package name. This is the best methods to use shared preferences, if you intend to have only one shared preference file.
In your initial question you wrote a data in one file and tried to read in an other file, which result in an error. That's why like Rob Meeuwisse write you must use PreferenceManager.getDefaultSharedPreferences(Context)
I have a blank-ish Android Project and what I want to do is take the user to a different "page/screen" if it is their first time only.
I know the logic for this but since I'm new to Android, I'm unsure of how to code this.
Below are the steps I believe I need to take in order to accomplish this:
App loads. If Local storage contains setting "FirstTimeUser", then it is not their first time using the app. Show the MainActivity page. If FirstTimeUser setting does not exist, it is their first time using the app (or they have uninstalled and reinstalled it), so instead, show WelcomeActivity page.
After viewing Welcome activity page, create FirstTimeUser setting and set to False.
But how do I code this for an Android app?
Use shared preferences as shown:
//declare as global
SharedPreferences prefs = null;
//and in your onCreate method:
prefs = getSharedPreferences("packageNameHere", MODE_PRIVATE);
if (prefs.getBoolean("firstrun", true)) {
//do stuff here if first run
//make sure to flag the boolean as false
prefs.edit().putBoolean("firstrun", false).commit();
}
else{
//if not first run, do something else
}
There is something called "SharedPreferences" that i believe your looking for.
http://developer.android.com/reference/android/content/SharedPreferences.Editor.html
I am trying to detect if my app has been run before, by using this code:
(This is in my default Android activity)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Log.w("activity", "first time");
setContentView(R.layout.activity_clean_weather);
} else {
Log.w("activity", "second time");
setContentView(R.layout.activity_clean_weather);
}
}
When I first run the app it says first time, when I run it a second time, first time, and a third, first time....
I am using an actual Android device and I am not using the run button each time. I run the app once with the Eclipse run button, then I close the app and press on its icon on my phone.
Is there something wrong with my code?
savedInstanceState is more for switching between states, like pausing/resuming, that kind of thing. It must always be created by you, also.
What you want in this case is SharedPreferences.
Something like this:
public static final String PREFS_NAME = "MyPrefsFile"; // Name of prefs file; don't change this after it's saved something
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); // Get preferences file (0 = no option flags set)
boolean firstRun = settings.getBoolean("firstRun", true); // Is it first run? If not specified, use "true"
if (firstRun) {
Log.w("activity", "first time");
setContentView(R.layout.activity_clean_weather);
SharedPreferences.Editor editor = settings.edit(); // Open the editor for our settings
editor.putBoolean("firstRun", false); // It is no longer the first run
editor.commit(); // Save all changed settings
} else {
Log.w("activity", "second time");
setContentView(R.layout.activity_clean_weather);
}
}
I basically took this code directly from the documentation for Storage Options and applied it to your situation. It's a good concept to learn early.
You may use a self-defined shared preference to archive your goal.
The fact is that savedInstanceState holds persistent data across activities. As such if you restart the app, savedInstanceState will be null across runs. You should either use a Preference or some data base entry to keep track of your first run. I myself use a SharedPreference for this purpose.
savedInstanceState will be null if the app is not already loaded in memory. If you want to detect whether the app has run for the very first time, you have to apply different technique, such as using sharedPrefs / DB to store a property for the first run.
i.e. Check sharedPrefs for property "firstRun"
if exists, then it is not a first run
else it is the first run
set the firstRun property to true