My app uses SharedPreferences (with the help of a PreferenceActivity) to store all settings. But sometimes all settings are deleted and all values are set back to default. Mostly on Android 3.x tabs.
On normal smartphones there are no problems.
I have observed that all settings are deleted when the application process is killed by Android.
I noticed this because the notification icon is no longer displayed.
I also wonder why the process is killed on tablets and not on smartphones. On my smartphone the notification icon never disappears.
My app also has a service, the main process and the service both read and write settings to the SharedPreferences.
I've sometimes noticed that all settings are cleared once the service writes to the SharedPreferences. But it does not happen every time.
Any ideas?
I realize that the SharedPreferences should not be used by different processes, but it works on all smartphones without problems!
I found out the reason why the settings disappear:
If two processes write data to SharedPreferences, it can happen that all SharedPreferences are reset to default values.
In my case all settings are cleared when the service write the first data to SharedPreferences.
Now, the service provides only read access to the SharedPreferences. The settings that are accessed by both processes writing are stored in a database.
SharedPreferences usually work great and as you mentioned without any problem on smartphones. It should also work on tablets. However it would be best to use sqlite or backing your shared prefs on a server for each users id data loss is a problem.
I have had the same issue.
All values from shared preferences become default if one value occasionally written with key = null. This is possible when you creating new constants using Eclipse, which inits them with null by default, and then you forgot to go to the beginning of the class and change constant to some meaningful value.
If you continue using the app, read operation of shared preferences will return valid values.
But when context is changed(for example, when activity killed by android and recreated) all values from shared preferences will return default values(zeroes).
So check your shared preferences's keys!
I hope this answer will help someone.
Related
I have two apps which are sharing preferences, the problem I'm facing is if one app write some preferences and the other app reads them, them it is the old value that is fetched, unless the reading app is exited and then reopened i.e.:
If app A is running and reads a value from preferences:
...
prefs = m_context.getSharedPreferences (name, Context.MODE_PRIVATE);
m_retryCount = prefs.getInt(RETRY_COUNT, 0);
Lets say the value retrieved is 10.
Now if app B runs and writes to the preferences:
prefs = cityidCtx.getSharedPreferences (prefsName, Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences.Editor editor = prefs.edit ();
editor.putInt(CityIdHandsetState.RETRY_COUNT, this.m_retryCount);
editor.commit ();
Lets say the value being written is 20.
Now if app A reads the preferences again after the new value of 20 has been written by app B then the value that app A obtains is still 10. But if app A is exited and then re-opened then the value it reads now will be 20.
How can this be fixed such that app A always gets the updated values.
You are using the wrong FLAG, that flag isn't used there
Flag for use with createPackageContext(String, int): ignore any
security restrictions on the Context being requested, allowing it to
always be loaded. For use with CONTEXT_INCLUDE_CODE to allow code to
be loaded into a process even when it isn't safe to do so. Use with
extreme care!
You are using Context.getSharedPreferences(String name, int mode) which states
Operating mode. Use 0 or MODE_PRIVATE for the default operation,
MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions.
You just so happen to be getting lucky that they happen to have similar values. You need to use...
Context.MODE_WORLD_WRITEABLE
However... What you want is actually Context.MODE_MULTI_PROCESS But... it was deprecated in 23 and does NOT allow for concurrent access of data.
This constant was deprecated in API level 23. MODE_MULTI_PROCESS does
not work reliably in some versions of Android, and furthermore does
not provide any mechanism for reconciling concurrent modifications
across processes. Applications should not attempt to use it. Instead,
they should use an explicit cross-process data management approach
such as ContentProvider.
Therefore, you need to use a ContentProvider.
I am working with an android app and am looking for a way to establish some global preferences that will be later accessible to all all activities/classes in my app. This is similar to what i know some people end up using the AppDelegate in objective c programming. The answers i have seen on the net suggest that i either extend from Application or save the data to SharedPreferences. I would like to know if there is a way to combine the two approches so that in my app, i can keep calling properties of a Preferences object (such as Preferences.getName()) and also persist the data to SharedPreferences so that, in case Android decides to restart my application and i loose all the data in my Preferences object, i can still get it back from SharedPreferences and repopulate the Preferences object. Can anyone please let me know how this can be done and if it is viable?
See my answer at https://stackoverflow.com/a/13673178/338479
In short, I create a "singleton" class to hold my preferences, and the data persists as long as the application stays in memory. If the application is killed by the system, the singleton class silently reloads it later.
It's also possible to do this by extending Application class, but conventional wisdom holds that there's no real advantage to doing it this way.
I tried to find an explanation about this issue but I couldn't find anything.
I have a remote service that is working in the background. This service reads some preferences from a SharedPreference.
The problem I have happens when I change a preference from a PreferenceActivity (the activity and the service belong to the same application and the same package). I change the preference and it is saved correctly, but as soon as the service reads that preference (the service never modifies the preferences, it only modifies some internal preferences that cannot be modified from the PreferenceActivity) the preference is 'resetted' and the service gets the resetted value.
This is happening with CheckBoxPreference. I don't know if this would happen with other kind of preferences as I don't have any of them.
After I change the preference I should restart the service? Or I need to 'refresh' the preferences in the service? Maybe this is a problem related with using HoloEverywhere?
To get the SharedPreference object I use the following code:
PreferenceManager.wrap(context, getSharedPreferencesName(context), Context.MODE_MULTI_PROCESS);
This code is specific for HoloEverywhere and it equals this:
context.getSharedPreferences(getSharedPreferencesName(context), Context.MODE_MULTI_PROCESS);
'getSharedPreferencesName()' just returns a string composed by "package.name_preferences".
Thank you.
I have a remote service that is working in the background.
Why did you make your service be remote?
I change the preference and it is saved correctly, but as soon as the service reads that preference (the service never modifies the preferences, it only modifies some internal preferences that cannot be modified from the PreferenceActivity) the preference is 'resetted' and the service gets the resetted value.
That's because you made your service remote. Simply remove the android:process attribute from your manifest, to have all your components run in the same process, and this problem will go away. Along the way, you will make the user happier, because you won't be consuming as much RAM and battery.
After I change the preference I should restart the service? Or I need to 'refresh' the preferences in the service?
If you truly have a legitimate reason for having a remote service -- and IMHO there's a greater chance that I will spontaneously regrow my hair -- you will need to restart the service's process, AFAIK. SharedPreferences are cached per process, and I don't know of a way to force Android to reload SharedPreferences from disk except by restarting the process.
Or, you could not have a remote service. The choice is yours.
I'm trying to understand how the Application class.
I've noticed that need to declare it in <application> manifest within the tag and then can access the variables in other classes as they were global variables. And even out of the application the value of these varieties do not change.
However, if you unplug the phone, the next time you turn it on and start applying the value of the variables returned to its initial state.
I wonder if you can maintain the state of variables when we turned off the phone and reconnect it?
Application data is available as long as your application is "active". When the OS decides to terminate it to clear memory, so goes your application data (you typically don't control when this happens, as per the mobile development good practices: the OS decides on its own), and it's not persisted for the next time you start the app. So anything you store in the Application should be stored again each time the app is started.
It should be used to keep short-term data available to you. A good use case is when you need to access a complex data structure from multiple activities: it's not possible to use bundles for that. You can generate your complex data structure in your start activity, store it in the application, and then retrieve it in any other application that may need it.
But you should not use it for long-term persistent data. For that, the best is to use a SQLite database.
I'm not sure I fully understand what you mean, but it seems like you want to use Shared Preferences.
try this Question: Android - How Do I Set A Preference In Code
I would like to know if it is possible to for some application other my own to change a preference value of my application. Also are the preferences been kept by android when the phone is turned off?
Is it safe to store some data(flags) on sharedpreferences in order to notify an activity for something?
When user clears the application data what exactly is erased, shared preferences data?
Is it preferred to use an internal private file to store secure data? Such as passwords?
Also I would like to be able to show a dialog when I detect a certain behavior, for this I have a monitoring service that has to notify the main activity about that. currently this is done through a callback method but I would like to maintain that state even if the application is killed or the phone reboots.
So I thought of setting a sharedpreference value (flag) and then on the oncreate method check if that flag exists. Also should I also check on the resume method?
Preferences (including SharedPreferences) are stored in files under your application's private data directory. No other application can read or write there, unless the phone has been rooted. This internal storage is flash-based and survives the phone being turned off... not much would work if it didn't. :)
As a general security principle you should never store a password. Secure systems store and compare password hashes, not the passwords themselves.
It's fine to store application state in preference data... personally I'd read it in onCreate() and thereafter write the value back to preferences either at the point it changes or in onPause().