I'm trying to create a simple Settings Activity with a single setting to change the language of the App.
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="#string/locale">
<ListPreference
android:key="lang"
android:title="#string/language"
android:summary="#string/languageDesc"
android:entries="#array/languages"
android:entryValues="#array/languageValues"
android:defaultValue="#string/locale_en"/>
</PreferenceCategory>
public class TCPreferenceActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("lang")) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("lang", sharedPreferences.getString(key, "en_US"));
editor.commit();
settings();
}
}
public void settings() {
Intent intent = new Intent(this, TCPreferenceActivity.class);
intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT, TCPreferenceFragment.class.getName());
intent.putExtra(PreferenceActivity.EXTRA_NO_HEADERS, true);
startActivity(intent);
}
#Override
protected void attachBaseContext(Context newBase) {
SharedPreferences pref = newBase.getSharedPreferences("lang", MODE_PRIVATE);
String lang = pref.getString("lang", null);
Locale locale = new Locale(lang);
Context context = TCContextWrapper.wrap(newBase, locale);
super.attachBaseContext(newBase);
}
}
When I debug the activity, i see the updated value being received in the method onSharedPreferenceChanged.
However when i call the Intent to reload the activity, with the context wrapper in order to change the language, the value received from the call to newBase.getSharedPreferences("lang", MODE_PRIVATE) is still the original unchanged value.
When i click again on the preference in the interface, i see that the value hash changed.
Do I need to save the value?
Why doesn't it changed in the SharedPreferences class?
I'm trying to replicate what0s being done in the exemple here:
Android context.getResources.updateConfiguration() deprecated
Thanks in advance.
Try changing:
SharedPreferences pref = newBase.getSharedPreferences("lang", MODE_PRIVATE);
To:
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(TCPreferenceActivity.this);
For what ever reason, you are loading up private "lang" preferences, which im pretty sure you are not saving to. Use the default preferences instead which the activity should be by default using else where.
I would rather that you user apply() instead of commit().
Unlike commit(), which writes its preferences out to persistent storage synchronously, apply() commits its changes to the in-memory SharedPreferences immediately but starts an asynchronous commit to disk.
Do this;
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("lang", sharedPreferences.getString(key, "en_US"));
editor.apply();
Related
I have one activity that sets various variables to either true or false, to be used as settings for other activities. I need to be able to call the state of these variables in my other activities but I can't figure out how. I know for strings I can use
getApplicationContext().getResources().getString(R.string.stringName);
but the same thing won't work for Boolean. Someone suggested using
activityName.variableName
but that won't work either. Any suggestions?
Instead of static variable or application variable use SharedPreference to achieve this which also persist on application close.
SettingsActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
....
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("YOUR_KEY1", true);
editor.putBoolean("YOUR_KEY2", false);
editor.putBoolean("YOUR_KEY3", true);
editor.commit();
....
}
Then in other activity or fragment use getBoolean() to retrieve those data.
OthersActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
....
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
//here false is the default value if key is missing
boolean value1 = sharedPreferences.getBoolean("YOUR_KEY1", false);
boolean value2 = sharedPreferences.getBoolean("YOUR_KEY2", false);
boolean value3 = sharedPreferences.getBoolean("YOUR_KEY3", false);
....
}
you can make global variables using many ways most common two
1- use of Application class
public class MyApplication extends Application {
private String someVariable;
public String getSomeVariable() {
return someVariable;
}
public void setSomeVariable(String someVariable) {
this.someVariable = someVariable;
}
}
sure don't forgt to declare in manifest file
<application
android:name=".MyApplication"
android:icon="#drawable/icon"
android:label="#string/app_name">
How to use?
// set
((MyApplication) this.getApplication()).setSomeVariable("foo");
// get
String s = ((MyApplication) this.getApplication()).getSomeVariable();
2- by using Extra as a variable to be passed from activity to others with help of Intent
Intent intent = new Intent(getBaseContext(), SignoutActivity.class);
intent.putExtra("EXTRA_SESSION_ID", sessionId);
startActivity(intent);
to read it in second activity use
String sessionId = getIntent().getStringExtra("EXTRA_SESSION_ID");
for setting screens suggest to use SharedPreference you can learn how to use from here
I want to run a piece of code once only after the application is installed. After it has been executed, that particular piece of code should not be called again, even for an upgrade.
Check if boolean X is True in shared preferences
If not:
a. Run the special code
b. Save x as true in shared preferences
For example:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if(!prefs.getBoolean("firstTime", false)) {
// run your one time code
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstTime", true);
editor.commit();
}
I've used a shared preference in the past, but if you are wanting to do something onInstall you could also look at a install receiver. MyInstallReciever implements BroadcastReciever
<receiver
android:name="com.MyInstallReciever"
android:exported="true">
<intent-filter>
<action
android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
use this simple code
if (getPreferences(MODE_PRIVATE).getBoolean("is_first_run", true)) {
/*
* your code here
*/
getPreferences(MODE_PRIVATE).edit().putBoolean("is_first_run", false).commit();
}
Use a boolean value to check if its first execution of code or not.
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedpreferences.edit();
if(sharedpreferences.getBoolean("is_first_exec",false))
{
editor.putBoolean("is_first_exec",false);
//your code here ...
}
The getBoolean() like every other get method of SharedPreference, takes a second default parameter which will return null the first time (as there is nothing in the SharedPreference file). Thus, the code inside the if(){...} block will execute only once.
Footnotes: SharedPreferences
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// Initialize SharedPreferences
SharedPreferences getPrefs = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
// Create a new boolean and preference and set it to true
boolean isFirstStart = getPrefs.getBoolean("firstStart", true);
// If the activity has never started before...
if (isFirstStart) {
// Launch app intro
final Intent i = new Intent(MainActivity.this, DefaultIntro.class);
runOnUiThread(new Runnable() {
#Override public void run() {
startActivity(i);
}
});
// Make a new preferences editor
SharedPreferences.Editor e = getPrefs.edit();
// Edit preference to make it false because we don't want this to run again
e.putBoolean("firstStart", false);
// Apply changes
e.apply();
}
}
});
// Start the thread
t.start();
This is my MainActivity.java's onCreate method:
protected void onCreate(Bundle savedInstanceState) {
loadSavedPreferences();
savePreferences("storedAddress", userAddress.getText().toString());
}
These 2 are the methods inside the class
private void loadSavedPreferences() {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(this);
String address = sharedPreferences.getString("storedAddress", "YourAddress");
userAddress.setText(address);
}
private void savePreferences(String key, String value) {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
}
Here's the flow. First time user uses the app has to enter their address in the EditText field. I want the same address to be stored there when the user returns.
The problem with the code above: It always shows "YourAddress" in the EditText field. There's no login required for this application. Just a simple form.
Use your savePreferences() method in any action the user can do after typing his address,a button click or whatever.
The way it is now, it's saving only when the activity gets created and after you load the preferences with the default value YourAddress. That's why you always get the same value.
im building a app, found a java part that lets me show an activity only at first start.
this works but when i kill the app or reboot my phone it goes back, can anyone help me out with this?
im using this in my main activity (Toolz.java)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Prefs.firststart == false) {
setContentView(R.layout.toolz);
} else {
Intent i = new Intent(this, First.class);
startActivity(i);
finish();
}
}
#Override
protected void onResume() {
super.onResume();
}
and i added this to First.java
Prefs.firststart=false;
and i made the Prefs.java and added this
public class Prefs {
public static boolean firststart = true;
}
you will need to use SharedPreferences instead o static variable for saving data which also available when app killed or device reboot.
you can see following tutorial how we use SharedPreferences for saving and reading data from SharedPreferences
Shared Preferences
When the app restarts all your code will start from the starting point (i.e Prefs.firststart will be set to true). Instead, you need to make a persistent variable that is saved throughout sessions. If you're using a DB you could use that, or you could use the built-in SharedPreferences, as such:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences prefs = this.getPreferences(MODE_PRIVATE);
if (prefs.contains("started")) {
setContentView(R.layout.toolz);
} else {
//Add the preference:
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("started",true);
editor.apply();
Intent i = new Intent(this, First.class);
startActivity(i);
finish();
}
}
When you kill your app, the values are going to reset to their initial values. Your boolean will be equal to true. I suggest saving the state of the variable using SharedPreferences. Check out this other question someone asked about saving.
How to save a state of a variable in android app and use it
Try it like this
//**** First start *****
//you get the prefs for your app using a pref name
String PREFS_NAME = "myAppPrefs";
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
//persist the boolean value in preferences using a key-value approach
editor.putBoolean("pref_app_started", true);
//commit the changes
editor.commit();
and when you start the app you check for that pref
//**** next start *****
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
//now we get the saved boolean using the key we previously uesd when setting it
//the second parameter is the default value for the flag in case it was never set
boolean wasAppStarted = settings.getBoolean("pref_app_started", false);
//now you can use your wasAppStarted flag to decide what you do further
I need to have some information saved, what I have used in the past is sharedpreferences...
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("Data", (Data));
editor.commit();
So I would do something like this to save the Data, however for this project I am using the public class Tab3 extends View implements OnTouchListener type of class and Im not sure if thats why this isnt working but its not I cant use the Shared Prefences onTouch I get an error on getSharedPreferences saying "The method getSharedPreferences(String, int) is undefined for the type Tab3" what do I need to do in order to save this data in some way so I can use it later on in my app?
You need a context to get access to shared preferences. The best way is to create MyApplication as a descendant of Application class, instantiate there the preferences and use them in the rest of your application as MyApplication.preferences:
public class MyApplication extends Application {
public static SharedPreferences preferences;
#Override
public void onCreate() {
super.onCreate();
preferences = getSharedPreferences( getPackageName() + "_preferences", MODE_PRIVATE);
For example, if you need access to your preferences somewhere else, you may call this to read preferences:
String str = MyApplication.preferences.getString( KEY, DEFAULT );
Or you may call this to save something to the preferences:
MyApplication.preferences.edit().putString( KEY, VALUE ).commit();
(don't forget to call commit() after adding or changing preferences!)
I'd do what lenik says but don't make them static, lazy init them instead.
public class MyApplication extends Application {
public SharedPreferences preferences;
public SharedPreferences getSharedPrefs(){
if(preferences == null){
preferences = getSharedPreferences( getPackageName() + "_preferences", MODE_PRIVATE);
}
return preferences;
}
Then in your view:
MyApplication app = (MyApplication) getContext().getApplicationContext();
SharedPreferences settings = app.getSharedPrefs();
As eric says this Application class needs to be declared in your manifest:
<application android:name=".MyApplication"
android:icon="#drawable/icon"
android:label="#string/app_name">
Reference:
getApplicationContext()
Android Global Vars
edit
(From your comment) the issue is that you aren't actually saving any data, this line doesn't make sense you aren't actually saving a variable:
editor.putString("Data", (Data));
Here is an example of the above in use:
MyApplication app = (MyApplication) getContext().getApplicationContext();
SharedPreferences settings = app.getSharedPrefs();
String str = settings.getString("YourKey", null);
And to save something to the preferences:
settings.edit().putString("YourKey", "valueToSave").commit();
A more specific example of using in a custom View would be:
public class MyView extends View {
SharedPreferences settings;
// Other constructors that you may use also need the init() method
public MyView(Context context){
super(context);
init();
}
private void init(){
MyApplication app = (MyApplication) getContext().getApplicationContext();
settings = app.getSharedPrefs();
}
private void someMethod(){ // or onTouch() etc
settings.edit().putString("YourKey", "valueToSave").commit(); //Save your data
}
private void someOtherMethod(){
String str = settings.getString("YourKey", null); //Retrieve your data
}
}