I have this class where I save the data and where the method loadUsername() is.
public class Settings extends AppCompatActivity {
EditText username;
static String string_username;
static SharedPreferences string_savepoint;
SharedPreferences.Editor string_editor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
username = (EditText) this.findViewById(R.id.username);
//Speicher und Savepoint initialisieren
string_savepoint = getSharedPreferences("Data", Context.MODE_PRIVATE);
string_editor = string_savepoint.edit();
//Username laden
username.setText(loadUsername());
}
#Override
protected void onPause() {
super.onPause();
// Username speichern
string_editor.putString("username", username.getText().toString());
string_editor.commit();
}
protected static String loadUsername() {
// Aus dem Speicher
string_username = string_savepoint.getString("username", "Spieler");
return string_username;
}
Then I want to load the username in a another class.
Settings.loadUsername();
Actually this works but only if I have been in this class. If I start the app and go directly to the Activty where I wanna load the username I get this error:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String android.content.SharedPreferences.getString(java.lang.String, java.lang.String)' on a null object reference
at com.example.stefano.mathgame.Settings.loadUsername(Settings.java:43)
at com.example.stefano.mathgame.Game.gameSuccess(Game.java:151)
at com.example.stefano.mathgame.Game.onClick(Game.java:102)
Do you have any ideas?
I think that the best way to avoid those kind of problem in future is to use this library.
compile 'com.pixplicity.easyprefs:library:1.4'
All you need to do is to add a class to your project which extends Applications like this one below:
public class PrefsApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// Initialize the Prefs class
new Prefs.Builder()
.setContext(this)
.setMode(ContextWrapper.MODE_PRIVATE)
.setPrefsName(getPackageName())
.setUseDefaultSharedPreference(true)
.build();
}
}
and then you can simply read and write any value from the shared preferences without taking care of initialise it at the right moment (which caused your null point exception).
For read value from the shared preferences just do this:
Prefs.getString(key, default value)
and for saving values:
Prefs.putString(key, string)
You can not use this static method like this. Your string_savepoint will be initialized only when your activity Settings starts. If you try to use this static method without starting your activity you will get this Null pointer exception.
If you need to load the username from other code sections it will be best practice to create a some helper class to work with shared preferences, initialize it by passing it application context and than call its methods to save and load the username. This way the functionality of handling the persistence of the username will not be bind to an activity, which should be responsible for UI.
Add these two lines
static SharedPreferences string_savepoint;
string_savepoint = getSharedPreferences("Data", Context.MODE_PRIVATE);
in those activities from where you wish to call Settings.loadUsername();
Related
public class ustawienia extends MainActivity {
EditText kryptonim;
public String test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ustawienia);
kryptonim = (EditText) findViewById(R.id.edit_kryptonim);
test = kryptonim.getText().toString();
}
public String call_back(){
return test;
}
}
When call call_back() from another class I've got error: Unable to start activity ComponentInfo. What's wrong with that?
When you close an activity all data from it is lost, so unless both activities are runing at the same time you can't retrieve data. You could use shared prefrences instead.
// IN ORDER TO WRITE TO A FILE
SharedPreferences.Editor prefs = getSharedPreferences("PrefsName", MODE_PRIVATE).edit();
prefs.putString("test", kryptonim.getText().toString());
prefs.apply(); // use prefs.commit(); if this doesn't work
In order to read data
SharedPreferences prefsR = getSharedPreferences("PrefsName", MODE_PRIVATE); // you could also write 0 instead MODE_PRIVATE
String restoredText = prefsR.getString("test", null);
Ofcourse you need to import SharedPrefs , and put this in oncreate or wherever you want... let me now if it works :)
I have an application where I'm setting roughly around 200 shared preferences when the application is run for the first time. I was initially loading all the preferences by calling it from my onCreate method
SharedPreferences pref = getSharedPreferences(CALC_PREFS, MODE_PRIVATE);
settingsEditor = prefs.edit();
settingsEditor.putString("Something", "");
....
settingsEditor.commit();
and it would work well and rather quickly. I then redesigned my application to have an abstract activity class to handle all the work with the shared preferences becacuse I have 4 different activities accessing these preferences.
public abstract class AnActivity extends Activity{
// Shared Preference string
private static final String CALC_PREFS = "CalculatorPrefs";
// Editor to customize preferences
private Editor settingsEditor;
// Shared preference
private SharedPreferences prefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
prefs = getSharedPreferences(CALC_PREFS, MODE_PRIVATE);
settingsEditor = prefs.edit();
}
protected void addPref(String key, String value){
settingsEditor.putString(key, value).commit();
}
protected void addPref(String key, int value){
settingsEditor.putInt(key, value).commit();
}
//other methods were not posted
}
My main activity not extends the "AnActivity" class. However, when I run my application on a fresh install or attemp to access any shared preference, it takes upwards of 10 seconds to instantiate everything.
How can I set the default values in a clean and efficient manner? Does creating an Abstract class to handle the preferences create more overhead than just calling getSharedPreferences manually?
Are you commiting each time you add a preference? This is probably your issue, commiting for each entry could be quite expensive, batch together your put's and commit once.
If you don't need to specify the default value, you could always use clear() instead
http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#clear%28%29
I have application with an activity and a service, I need to save some value in the activity and retrieve in the service.
i could save the value using SharedPreferences in the activity, however, when I try to retrieve the value in the BroadcastReceiver, it says getPreferences is undefined for service.
how could I retrieve my value in BroadcastReceiver?
EDITED to reflect change of the original question from Service to BroadcastReceiver.
Instead of using getPreferences(int mode) in the Activity use...
getSharedPreferences(String name, int mode).
The getPreferences(int mode) method is a convenience method for the above and simply passes the Activity class name as the name parameter. This implies it should really only be used for a given Activity to store its own internal preferences and not preferences that need to be global to other app components.
In the case of a BroadcastReceiver the onReceive(...) method is passed a Context parameter so you can use context.getSharePreferences(<some_name>, <mode>) to get the SharedPreferences saved by the Activity.
public class AndroidWalkthroughApp4 extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public void onResume() {
// get EditText object
EditText editText = (EditText)this.findViewById(R.id.edit_text);
// get preferences object
SharedPreferences prefs = this.getPreferences(MODE_PRIVATE);
// set text to our saved value
editText.setText(String.valueOf(prefs.getInt("chars", 0)));
// don't forget to do this, or your app will crash!
super.onResume();
}
#Override
public void onPause() {
// get EditText object
EditText editText = (EditText)this.findViewById(R.id.edit_text);
// get preferences object
SharedPreferences prefs = this.getPreferences(MODE_PRIVATE);
// create editor from preferences object
SharedPreferences.Editor editor = prefs.edit();
// save and write length of EditText
editor.putInt("chars", editText.getText().length());
editor.commit();
// don't forget this either!
super.onPause();
}
}
In my Android application I have to use common string value for all activities. "commonValue" is the common string value that I want to use in all activities. Relevant code of the main activity like this :
public class TestActivity extends Activity {
public String commonValue;//THE COMMON STRING FOR ALL ACTIVITIES
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
commonValue = "DemoValue";
}
}
In my next activity I created an object of "TestActivity" class and tried to assign "testValue" string to another string named "str"
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testlist);
TestActivity obj = new TestActivity();//OBJECT OF MAIN ACTIVITY
String str = obj.commonValue;
}
but the "str" value in second activity does not equal to the value assigned in my first activity. Why is that & How can I do this?
Thanks!
Put your value in string.xml
<string name="common_value">DemoValue</string>
and use in any activity like this..
String common_value = getApplicationContext().getString(R.string.common_value);
Start using SharedPreferences in your app.
In your first activity you would do
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("commonValue", "DemoValue");
editor.commit();
In your second activity
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String str = settings.getString("commonValue", null);
Try this -
TestActivity.java
public class TestActivity extends Activity {
public static String commonValue;//THE COMMON STRING FOR ALL ACTIVITIES
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
commonValue = "DemoValue";
}
}
another activity
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.testlist);
String str = TestActivity.commonValue;
}
If the value is always the same you can create a public static final variable and access it via TestActivity.COMMON_VALUE.
If you want to pass around a value between to Activities you should use Intents and add an extra with the value you want to pass.
As Sana has suggested, use SharedPreferences.
Alternatively, use a global constant class. If you want to stick with what you have, then you could try:
String str = TestActivity.this.commonValue;
Your existing code is creating a new instance of the activity, so it's not going to have the value you had set.
To pass data between activities use Bundle. and methods,
intent.putExtra()
and If you want to set data to be global to your app, then create an application class, and save the data there.
We have an Application file for each app you can declare the variable there and as the Application file can get from any activity so using the public getter setter and can get/set that
there are vaious oter metjod you can sue as mention on developer.android http://developer.android.com/resources/faq/framework.html
Singleton class
A public static field/method
A HashMap of WeakReferences to Objects (almost same as my above solution )
Persistent Objects
take a look on them as well
The reason why commonValue doesn't equal what you set in TestActivity onCreate method is because that function hasn't been called yet.
The solution for this is already mentioned by others. Like putting the value in a bundle.
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