Android - Access SharedPreferences once application is stopped/destroyed - android

I implementing notifications together with a periodical alarm and on IntentService i need to validate some values on SharedPreferences to decide if I will show a notifications or not.
When the application is on pause i have context, and everything goes ok, the problem comes when i destroy(remove from "recent apps" list) my application.
In this case, the alarm is still running (which is ok), but when it tries to load my shared preferences gives me NullPointerException.
IntentService:
public class MyIntentService extends IntentService {
private final PreferencesManager prefs;
public SchedulingService() {
super("MyIntentService");
prefs = PreferencesManager.getInstance(this); //Error here
}
#Override
protected void onHandleIntent(Intent intent) {
// Do some checking with prefs variable ...
}
}
SharedPreferences
public class PreferencesManager {
public static final String SHARED_PREFERENCES_NAME = "PREFERENCES_PROJECT";
private static PreferencesManager preferencesManager = null;
private SharedPreferences sharedPreferences;
private PreferencesManager(Context context) {
sharedPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
}
public static PreferencesManager getInstance(Context context) {
if (preferencesManager == null) {
preferencesManager = new PreferencesManager(context);
}
return preferencesManager;
}
//....
}
How can retrieve the values from my PreferencesManager when the application is not running?

Move your prefs = PreferencesManager.getInstance(this) line to onHandleIntent(), or into an onCreate() method after the super.onCreate() call.
why dont i have context on constructor?
You do have a Context. It is not fully initialized yet. Never attempt to use a Context before the inherited onCreate() of the relevant component has completed. In this case, the component is a Service, so once super.onCreate() is over, then it is safe to use the Service to retrieve a SharedPreferences object.

Related

DefaultSharedPreferences() does not clear() values

I am using defaultSharedPreferences() throughout my application. I define it once in my Application class and use it whenever needed:
public class Itu extends Application {
public static SharedPreferences sharedPreferencesFDefault;
#Override
public void onCreate() {
sharedPreferencesFDefault = PreferenceManager.getDefaultSharedPreferences(this);
}
public static SharedPreferences getSharedPreferencesItu(){
return sharedPreferencesFDefault;
}
public static int getStudentNameColor(SharedPreferences sharedPref){
int color = sharedPref.getInt("studentNameColor", -1);
if (color == -1) {
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("studentNameColor", 0);
editor.commit();
color = sharedPref.getInt("studentNameColor", 0);
}
....
return color;
}
I use it in this Activity:
public class StudentAddActivity extends ActionBarActivity {
...
private void attemptAdd() {
SharedPreferences sharedPref=((Itu)getApplication()).getSharedPreferencesItu();
int color=Itu.getStudentNameColor(sharedPref);
}
Now i want to delete all values from my another activity which does not work:
public class CourseListActivity extends ActionBarActivity{
public static SharedPreferences sharedPreferencesFDefault;
...
sharedPreferencesFDefault = ((Itu) getApplication()).getSharedPreferencesItu();
sharedPreferencesFDefault.edit().clear().commit();
}
After i call sharedPreferencesFDefault.edit().clear().commit();, i still see that my "studentNameColor" value exists in defaultSharedPreferences.
What might be problem? Using defaultSharedPreferences instead of sharedPreference? or passing Application context instead of each activity's context? or i call wrong function to delete?
UPDATE 1: i can delete it from my Application class, but not from my Activities. why?
UPDATE 2: i can delete now it from another activity by accessing variable directly:
((Itu) getApplication()).sharedPreferencesFDefault.edit().clear().commit();
But if i get sharedPreference variable through my static function, i can not clear it, why?
I have changed public static SharedPreferences sharedPreferencesFDefault; to public SharedPreferences sharedPreferencesFDefault; and now clear() works. The thing was getting static sharedPreference, from Application class, into static variable of Activity class.
I still don't know what happens when we initialize static variable with another static variable. You can follow that question here.

Why shared preferences has been reset up on app crash or force close Android

I have taken CSIPSIMPLE code and repackaged to com.mycompany.appname
The problem is, whenever app is crashed, All values are deleted from Shared preferences.
Why?
My Application is
public class BeemApplication extends Application {
static BeemApplication application = null;
public static SharedPreferences mPref;
public static Editor mEditor;
public BeemApplication() {
}
public static BeemApplication getInstance() {
if(application != null) {
return application;
} else {
return new BeemApplication();
}
}
#Override
public void onCreate() {
super.onCreate();
application = this;
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEditor = mPref.edit();
}
#Override
public void onTerminate() {
super.onTerminate();
}
}
In Activity I will get them like ,
BeemApplication.mEditor.putString(ctx.getString(R.string.pref_online_number), number).commit();
BeemApplication.mPref.getString(ctx.getString(R.string.pref_online_number), number).commit();
This is common issue that many have faced including myself.
Have a look at this post Android - Shared Preferences are lost sometimes which shares your findings.
I would recommend not storing persistent data across shared preferences and rather use something like a database table to store settings.

SharedPreferences produces force close in android program

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);
}
}

Static SharedPref gives uninitialized value in Broadcast Receiver

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

Android initialization with SharedPreferences

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

Categories

Resources