I've kept a static shared preference to access the values from multiple activities.
Now, I've set an alarm to go off at a certain time. Now in that Broadcast Receiver, I'm trying to access the shared pref variable.
It has already been initialized in another activity and returns the proper value there.
But in this Broadcast Receiver it doesn't give the actual value. It gives the uninitialized value.
Since it is static shouldn't the value remain same?
Here is the shared preference class.
package com.footballalarm.invincibles;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Log;
public class SessionManagement {
// Shared Preferences
public static SharedPreferences pref;
// Editor for Shared preferences
public static Editor editor;
// Context
Context _context;
// Shared pref mode
int PRIVATE_MODE = 0;
// Shared pref file name
private static final String PREF_NAME = "invincibles_alarm";
// All Shared Preferences Key
public static final String PREF_MATCH = "match";
// Constructor
public SessionManagement(Context context){
this._context = context;
pref = _context.getSharedPreferences(getPrefName(), PRIVATE_MODE);
editor = pref.edit();
editor.commit();
Log.e("Pref Match Value-constructor for pref", getValueMatch());
}
public static void fillValues(String match){
try{// Storing login value as TRUE
editor.putString(PREF_MATCH, match);
// commit changes
editor.commit();
Log.e("Pref Match Value-in fill values", getValueMatch());
}
catch(Exception e)
{Log.e("fillValues", e.toString());}
}
public static String getValueMatch(){
return pref.getString(PREF_MATCH, "Loading Match");
}
public static String getPrefName() {
return PREF_NAME;
}
}
I tried to log the output in other activities and it returns properly.
When I run the app and then close it before the alarm takes place, the program crashes with null-pointer exception since the Broadcast Receiver cannot access the shared pref.
I have tried this solution - SharedPreferences in BroadcastReceiver seems to not update? but I'm only using name in the manifest for the recievers.
This only happens if I close my app in ICS via the minimize menu.
Check this link:
Static variable loses value
Maybe static variables are loosing its value in your case .
static variables can loose value in the following cases:
1) Class is unloaded.
2) JVM shuts down.
3) The process dies.
Instead of using static variables and functions , try using a public class instead.
Hope it helps
EDIT 1:
Example code of using a public class for preferences instead of static methods
public class PreferenceForApp {
Context context;
SharedPreferences prefs;
public PreferenceForApp(Context context) {
this.context = context;
prefs = context.getSharedPreferences(AllConstants.PREFS_NAME, 0);
}
public Boolean getIsDeviceValidated() {
return prefs.getBoolean("Validated", false);
}
public void setIsDeviceValidated(Boolean value) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("Validated", value);
editor.commit();
}
}
In your code add:
PreferenceForApp myPref = new PreferenceForApp(contxt);
myPref.getIsDeviceValidated();
Useful related links:
Android static object lifecycle
Why are static variables considered evil?
Android : Static variable null on low memory
EDIT 2
TEST when is your static variable loosing value :
You can test this with a few lines of code:
print the uninitialized static in onCreate of your activity -> should print null
initialize the static. print it -> value would be non null
Hit the back button and go to home screen. Note: Home screen is another activity.
Launch your activity again -> the static variable will be non-null
Kill your application process from DDMS(stop button in the devices window).
Restart your activity -> the static will have null value.
I referred to this link Android static object lifecycle
Related
How to create a preference screen which can save values in two different shared preferences ?
For example, in my PreferenceActivity my first preference is a CheckBoxPreference. The state of the checkbox is saved in "user_86_Prefs" sharedPreferences and the second preference is a ListPreference, and the state of the selected item is saved in "devicePrefs" sharedPreference.
in my PreferenceFragment I can only do
getPreferenceManager().setSharedPreferencesName("user_86_Prefs");
Actually the sharedPreference named "user_86_Prefs" is specific to the user connected on the app, and the "devicePrefs" is specific to the device.
Should I create another class which extends PreferenceFragment, and put the preferences specific to the device inside ? If yes, how can I have my two preferencesFragments in the same Activity ?
Thanks
One way of doing it would be to create one class in wich you handle all your preferences.
public class MySharedPreferences{
private static final String USER_PREF = "user_shared_pref";
private static final String DEVICE_PREF = "device_shared_pref";
private static SharedPreferences getSharedPreferences(Context ctx){
return PreferenceManager.getDefaultSharedPreferences(ctx);
}
public static void setUserPref(Context ctx,String user_pref){
Editor editor = getSharedPreferences(ctx).edit();
editor.putString(USER_PREF,user_pref);
editor.apply();
}
public static String getUserPref(Context ctx){
return getSharedPreferences(ctx).getString(USER_PREF,"");
}
}
Same thing for your device preferences ! And you juste need to do something like that to access it from other class/activity/fragment :
MySharedPreferences.setUserPref(this /* or whatever your context is*/,yourValue);
In one of my views the user makes a selection. I want to store that selection in a variable I can use across all views so it can be used for further database queries such as "bookId".
How can I make "bookId" a global variable that is set on one view and can be accessed across the other views when needed?
----- Edit: What I'm attempting to do based on comments and answers -----
On my main activity where the SharedPreference is stored I have this before the onCreate:
public static final String PREFS_NAME = "myPrefs";
SharedPreferences settings;
Integer bookId;
In my onCreate I've done this:
settings = getSharedPreferences(PREFS_NAME, 0);
bookId = settings.getInt("bookId", 0);
After the button press I'm storing a custom attribute and attempting to set bookId in the SharedPreference:
SharedPreferences.Editor editor = settings.edit();
editor.putInt("bookId",bookKey);
editor.commit();
In another view I'm attempting to get the bookId from the SharedPreference and, for testing purposes, I'm trying to set the stored value to a textView just to make sure it stored and carried over correctly.
Before the onCreate on the second view:
public static final String PREFS_NAME = "myPrefs";
SharedPreferences settings;
Inside the onCreate:
settings = getSharedPreferences(PREFS_NAME, 0);
Integer bookId = settings.getInt("bookId", (Integer) null);
tempBookTextView = (TextView) findViewById(R.id.tempBookTextView);
tempBookTextView.setText(bookId);
I have a two questions, how does this look so far? Any ideas why the app crashes when I use
Integer bookId = settings.getInt("bookId", (Integer) null);
Instead of using global variable to access variable value through out the app try using SharedPreferences.
sample activity:
public class Book extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
String mBookId = null;
#Override
protected void onCreate(Bundle state){
super.onCreate(state);
. . .
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
mBookId = settings.getString("book_id", null);
// use book_id;
}
#Override
protected void onStop(){
super.onStop();
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("book_id", mBookId);
// Commit the edits!
editor.commit();
}
}
Preferences are typically created private and can be accessed via all over the application components. Sharing data with other application with world readable or writable preference file is rarely used, as the external component would need to know the exact filename and location of the file.
To kill the spirit of encapsulation,
public class Globals {
public static int x;
public static int y;
}
and later
if (Globals.x == 0) { ... }
But please don't do exactly that, any class can contain static variables, find a class responsible for the value you want to store.
OTOH, android processes may be restarted when you don't expect it, in which case all the variables will be reset. So it's better to use shared preferences and if they don't work as expected (which I have seen in at least one release of Android), store the instance of shared preferences in a static variable.
You can use Shared Preferences
Saved at once !
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(ProjectAct.this).edit();
editor.putInteger(StaticVariable.BOOKID, "1");
p.get("contract_no"));
editor.commit();
Then call from anywhere like that
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
int book_id = prefs.getInteger(StaticVariable.BOOKID,null);
See more at How to use SharedPreferences in Android to store, fetch and edit values
I'm building an android project that contains SharedPreferences.
My SharedPreferences works fine and I tested it in mutiple activity. but in a class that I defined for global variables, defining that SharedPreferences will cause force close (eclipse didn't show any error in codes).
public class Globals extends Application {
final SharedPreferences s = getSharedPreferences("Prefs", MODE_PRIVATE);
}
What is the problem ?
You should pass the Context and use
SharedPreferences prefs = Context.getSharedPreferences(
"Prefs", Context.MODE_PRIVATE);
Create a constructor and pass a Context variable as a parameter. Any activity that want to use this preference then you have to pass the activity. Here's the code given below:
public class Globals extends Application {
private Context context;
public Globals (Context context) {
this.context = context;
}
SharedPreferences myPref = context.getSharedPreferences("Prefs", Context.MODE_PRIVATE);
}
You can't run getSharedPreferences() in the actual class. Everything you do must be in the Application's onCreate method. If you try to run this in the class, it will fail since it has not been initialized yet. Think of it almost as an activity, since both the activity and the application have a lifecycle.
Try the following:
public class Globals extends Application {
#Override
public void onCreate() {
super.onCreate();
final SharedPreferences s = getSharedPreferences("Prefs", MODE_PRIVATE);
}
}
The app I am developing has an activity that extends SherlockFragmentActivity. I would like to use the preferences api in order to easily add preferences to the activity. Since I would like to support api level 8 and above, I have to extend the activity from the class SherlockPreferenceActivity.
The problem is that the activity needs to show a dialog. The dialog extends SherlockDialogFragment. The show() method of the dialog needs two parameters: a FragmentManager object and a String tag.
In order to get the FragmentManager object, i used to call the getSupportFragmentManager() method of the activity. This method is missing from SherlockPreferenceActivity. I tried to use getFragmentManager() but Eclipse says that
The method show(FragmentManager, String) in the type DialogFragment is
not applicable for the arguments (FragmentManager, String)
How can I show the dialog fragment from SherlockPreferenceActivity?
You should use Shared Preferences rather than using the PreferenceActivity. Declare these references in a separate helper class rather than extending it to an Activity.This gives you the flexibility of creating a custom layout.
Example:
public class SharePrefManager {
// Shared Preferences
SharedPreferences pref;
// Editor for Shared preferences
Editor editor;
// Context
Context _context;
// Shared pref mode
int PRIVATE_MODE = 0;
// Sharedpref file name
private static final String PREF_NAME = "selfhelppref";
//Your configurable fields
public static final String KEY_PREF1 = "pref1";
public static final String KEY_PREF2 = "pref2";
public static final String KEY_PREF3 = "pref3";
public SharePrefManager(Context context){
this._context = context;
pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
editor = pref.edit();
}
//Setter function for configurable field
public void setPref(String key, String value){
editor.putString(key, value);
}
//Getter function for configurable field
public String getPref(String key){
return editor.getString(key);
}
}
Referencing on your activity
SharePrefManager SM = new SharePrefManager(this);
SM.setPref(SM.KEY_PREF1, "name");
String value = SM.getPref(SM.KEY_PREF1);
Try using SherlockDialogFragment.getSherlockActivity().getSupportFragmentManager().
Example:
mySherlockDialogFragment.show(mySherlockDialogFragment.getSherlockActivity().getSupportFragmentManager(), "my_tag");
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