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();
}
}
Related
I have two activities. In the first activity, I have a SharedPreferences with a TextView, which displays the amount of data in the SharedPreferences. These codes are written in the onCreate()
SharedPreferences coin = getSharedPreferences("saved", MODE_PRIVATE);
SharedPreferences.Editors editor2 = coin.edit();
editor2.putInt("t", 0).apply();
editor.commit();
TextView name = (TextView) findViewById(R.id.textview);
Integer a = coin.getInt("t", 0);
name.setText(a.toString());
In the second activity, I wanna add 10 points to the data and update the SharedPreferences. These codes are not inside onCreate().
SharedPreferences coin = getSharedPreferences("saved", MODE_PRIVATE);
SharedPreferences.Editors editor2 = coin.edit();
int a = coin.getInt("t", 0);
int b = a + 10;
editor2.putInt("t", Integer.valueOf(b));
The problem is, after adding 10 units there is no update in the TextView so I don't even know if the 10 units have been added correctly to SharedPreferences or not.
Please help
If I understand, you would like reflect the final value of t in SharedPreference in your first activity after its updated in second activity?
To do that, create a function updateNameTV() which would contain logic to update the TextView with the value of t from SharedPreference
and call that function in onResume() of the FIRST activity like:
#Override
protected void onResume() {
// TODO Auto-generated method stub
updateNameTV();
super.onResume();
}
So when Activity 2 is launched, Activity 1 goes in back of the stack and onPause() gets called.. when we return to Activity 1 this activity is pop back and onStart() followed by onResume() is called.
These are the lifecycle events more here
So the plan is, when onResume() is called we update the TextView value with the latest SharedPreference
And we do that before calling super.onResume() such that update is performed before handing over the control to next lifecycle event. Hope this gives more clarity.
You have to register OnSharedPreferenceChangeListener in your first activity in order to listen to the changes and then update your TextView with the updated value.
Implement OnSharedPreferenceChangeListener in your FirstActivity:
public class FirstActivity extends AppCompatActivity implements
SharedPreferences.OnSharedPreferenceChangeListener {
...
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
// This method will be called when there is a change in SharedPreference
// Update your textview here
if(s.equals("t")) {
Integer a = sharedPreferences.getInt("t", 0);
name.setText(a.toString());
}
}
}
In your FirstActivity's onStart() and onStop() method, manage the listener:
#Override
protected void onStart() {
super.onStart();
getSharedPreferences("saved", MODE_PRIVATE).registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onStop() {
getSharedPreferences("saved", MODE_PRIVATE).unregisterOnSharedPreferenceChangeListener(this);
super.onStop();
}
But remember, once you leave your FirstActivity, the listener gets unregistered and you will no longer receive updates. To reflect the updates even after the activity go background, you can just update your textview in your onStart() so that when the FirstActivity starts, the textview gets updated with the latest value from SharedPreferences:
#Override
protected void onStart() {
super.onStart();
SharedPreferences coin = getSharedPreferences("saved", MODE_PRIVATE);
coin.registerOnSharedPreferenceChangeListener(this);
// Also Update the textview here
Integer a = coin.getInt("t", 0);
name.setText(a.toString());
}
Now, any update to the preference from anywhere will also change the textview text as soon as the FirstActivity comes into foreground or launches.
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();
I have a PreferenceActivity P that stores values to SharedPreferences. This is working--I am able to make selections from the lists and the summary values are displayed correctly.
The problem is when I attempt to access the SharedPreference values within Activity A. The default values are loaded instead of the stored values. Only after I access the PreferenceActivity from Activity A do the up-to-date SharedPreference values become available to Activity A. Any suggestions on how to resolve this? Is there any option to using PreferenceManager.getDefaultSharedPreferences?
Here is the bulk of the PreferenceActivity code (I omitted the onSharedPreferenceChanged listener for brevity):
public class P extends PreferenceActivity {
public static String KEY_PREF_show_watch_areas, KEY_PREF_time_format, KEY_PREF_date_format;
String PREF_show_watch_areas, PREF_time_format, PREF_date_format;
static SharedPreferences sharedPrefs;
Preference pref_show_watch_areas=null;
ListPreference pref_time_format=null, pref_date_format=null;
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedPrefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext() );
KEY_PREF_show_watch_areas = getString(R.string.key_pref_show_watch_areas);
KEY_PREF_time_format = getString(R.string.key_pref_time_format);
KEY_PREF_date_format = getString(R.string.key_pref_date_format);
PREF_show_watch_areas = getString(R.string.pref_show_watch_areas);
PREF_time_format = getString(R.string.pref_time_format);
PREF_date_format = getString(R.string.pref_date_format);
//Load up the preference items (from XML)
addPreferencesFromResource(R.xml.preferences);
//DATE pref
pref_date_format = (ListPreference) findPreference(KEY_PREF_date_format); //Set summary to user selected value
pref_date_format.setSummary(pref_date_format.getEntry() );
//TIME pref
pref_time_format = (ListPreference) findPreference(KEY_PREF_time_format); //Set summary to show user selected value
pref_time_format.setSummary(pref_time_format.getEntry());
}
} // [END P]
Here is the onResume in Activity A:
#Override
protected void onResume() {
super.onResume();
SharedPreferences sharedPrefsResume = PreferenceManager.getDefaultSharedPreferences(getApplicationContext() );
dateFormatPref = sharedPrefsResume.getString(P.KEY_PREF_date_format, "d-MMM-yy");
timeFormatPref = sharedPrefsResume.getString(P.KEY_PREF_time_format, "h");
} // [END onResume]
I've discovered and resolved the problem. I was trying to access the SharedPrefs values with uninitialized variables (e.g., P.KEY_PREF_date_format). That's the reason the default values were being returned. I've now moved the static variables to my MainActivity to ensure they are initialized. Voila. SharePreferences are working as expected now.
I use some CheckBoxPreferences, but they are not indepentent. That means, wenn I change one CheckBoxPreference, others are fixed. I use the following code:
public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
Context context = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPrefs, String key) {
SharedPreferences.Editor editor = sharedPrefs.edit();
if ((key.equals("A")) & (key.equals("B"))) {
editor.putBoolean("C", true);
editor.commit();
}
}
}
After this the CheckBoxPreference "C" has a new value, but I can't see it. How can I update the screen with the new values?
By using a subclass of PreferenceActivity you do not have to handle the updating of the preferences UI. You define the preferences in the resource file loaded by addPreferencesFromResource() and the Activity will be rendered accordingly. Changes will be persisted automatically and should be visible immediately. You do not have to register your preferences Activity as a SharedPreferences.OnSharedPreferenceChangeListener.
When onSharedPreferenceChanged() is called the new value is already saved to the preferences.
This notification is for other Activities than the subclasses of PreferenceActivity. To know how to access the saved preferences you need to look at the file in res/xml/settings.xml it should contain android:key attributes. The attribute values give you the key to the preference.
You can retrieve the value via the following:
PreferenceManager.getDefaultSharedPreferences(aContext).getString(key, "");
So I have two activities: main with all data and secondary with Preferences. There are two arrays in main activity that I want to have access to from Preferences activity and work with this two arrays. In fact, I need to reset all data in arrays to default. Is there any way to do it?
I've tried to use SharedPreferences because I store all this data in it. I changed values in it from Preferences activity, but data in main activity haven't changed, I guess, because it's not being restarted, just paused.
You can use SharedPreferences and register a OnSharedPreferenceChangeListener and/or update the data in the onResume() method of your Activity.
Here's some basic example:
public class MainActivity extends Activity implements OnSharedPreferenceChangeListener {
private SharedPreferences prefs;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get your SharedPreferences objects
prefs = ...;
}
// This method will be called every time your activty comes to the front
#Override
protected void onResume() {
super.onResume();
// register a listener to get notified when the preferences change
prefs.registerOnSharedPreferenceChangeListener(this);
// do whatever you need to do to update the data
updateData();
}
#Override
protected void onPause() {
super.onPause();
// unregister listener if another activity comes to the front to save battery
prefs.unregisterOnSharedPreferenceChangeListener(this);
}
// this method will be called when some preference changes
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// do whatever you need to do to update the data
updateData();
}
}