I am working on shared Preferences. Basically, I am saving ArrayList to shared preferences which are working fine. Now I want to retrieve the ArrayList from Shared preferences but I am getting null. ArrayList is retrieving from preferences and also showing it's size. but data is not being set to string. How I retrieve the ArrayList from shared Preferences.
here is my code
public void saveRootCategory(List<Category> categories){
preferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, MODE_PRIVATE);
editor = preferences.edit();
editor.putInt("RootCategory",categories.size());
for (int i=0;i<categories.size();i++){
setData(categories.get(i));
}
editor.apply();
}
public void setData(final Category category){
categoryId = category.getId();
categoryName = category.getCategoryName();
editor.putInt("CategoryId",categoryId);
editor.putString("CategoryName",categoryName);
}
public ArrayList<String> getRootCategoy() {
preferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, MODE_PRIVATE);
ArrayList<String> rootCategories = new ArrayList<>();
rootCategories.clear();
int size = preferences.getInt("RootCategory", 0);
for(int i=0;i<size;i++) {
int Id = preferences.getInt("CategoryId" + i,0);
String name = preferences.getString("CategoryName" + i ,"");
rootCategories.add(String.valueOf(Id));
rootCategories.add(name);
}
return rootCategories;
}
I used to have the same null problem
Here's how I solved it
I have an arrayList named language
language = new ArrayList<String>
I had to add everything the user writes on the edittext on button click not repeating any redundant value
if(!language.contains(value)) {
language.add(value);
}
To save this arraylist I created a hashSet
Set<String> set = new HashSet<String>();
and save all of them onPause
set.addAll(language);
.putStringSet("yourKey", set);
.commit();
and retrive it back to language array list onCreate
prefs=this.getSharedPreferences("yourPrefsKey",Context.MODE_PRIVATE);
edit=prefs.edit();
set = prefs.getStringSet("yourKey", null);
language = new ArrayList<String>(set);
edit.remove("yourKey").commit();
remember to remove everytime or it will again create null
You are missing the index in setData. Change it to
public void setData(final Category category, int index){
categoryId = category.getId();
categoryName = category.getCategoryName();
editor.putInt("CategoryId" + index, categoryId);
editor.putString("CategoryName" + index, categoryName);
}
As you are trying to save the ArrayList into the share preference.
I Suggest you can use PaperDB Library.
Which is very fast and directly save your ArrayList same as preference doing.
You can also use it to store the Primitive datatypes and model class directly.
Note: It also reduces the code lines.
Add some breakpoints on setData() -> editor.putInt("CategoryId",categoryId); and debug your code are necessary.
BTW, it seems that there's no difference you call either editor.apply() or editor.commit() running on API 9 or above devices.
Replace your both methods with these:
public void saveRootCategory(List<Category> categories){
preferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, MODE_PRIVATE);
editor = preferences.edit();
editor.putString("RootCategory",new Gson().toJson(categories));
editor.apply();
}
public ArrayList<Category> getRootCategoy() {
preferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, MODE_PRIVATE);
String data = preferences.getString("RootCategory","");
return new Gson().fromJson(data, new TypeToken<List<Category>>(){}.getType());
}
No third party library needed use Gson(inbuilt) library which can easily do what you want to achieve.
public void setData(final Category category)
The method use the same key("CategoryId", "CategoryName") to save every item in the list.
However, you use "CategoryId" + index to get the value from SharedPreference.
Obviously, you can never get the right answer in this way...
#Murat's answer correct the method, and it can work well.
But I don't think it's a good way to save a List. If you do want to use SP to save Lists, I suggest Gson or any other way to translate your object into String first. It will work better.
Related
I'm saving an arraylist on shared preferences but when i add something new to this array it deletes the old one and displays only the new one.
Here is the save and load array from shared preferences
//SHARED PREFERENCES Save ArrayList
public boolean saveArrayList(SharedListFood list) {
SharedPreferences.Editor editor = prefs.edit();
Gson gson = new Gson();
String json = gson.toJson(list.getMlist()); //put in json the list from my model(SharedFoodList) which is the list i provide(itemsAdded)
editor.putString("testShared", json);
return editor.commit(); // This line is IMPORTANT !!!
}
//SHARED PREFERENCES Load ArrayList
public ArrayList<String> getArrayList() {
ArrayList<String> loadArrayList;
Gson gson = new Gson();
String json = prefs.getString("testShared", null);
Type type = new TypeToken<ArrayList<String>>() {
}.getType();
loadArrayList = gson.fromJson(json, type);
return loadArrayList;
}
I add the item here.
searchList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
searchMessage = searchList.getItemAtPosition(position).toString(); //searchMessage gets the value of the pressed item in list
if(searchMessage.contains("two")){
Log.d("alekos","tak"+searchMessage);
}
Toast.makeText(AddFood.this, "" + searchMessage, Toast.LENGTH_SHORT).show();
itemsAdded.add(searchMessage);// made it static so it is created here but displayed in the AddFoodBasket.java
sharedArray=new SharedListFood(itemsAdded);
boolean isSuccess= sharedArrayPreferencesHelper.saveArrayList(sharedArray); //sends itemsAdded to saveArrayList in shared preferences
if (isSuccess) {
Toast.makeText(getApplicationContext(),"Personal information saved", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),"Personal information NOT", Toast.LENGTH_LONG).show();
}
}
});
Where itemsAdded is the arraylist i want to add each time
As per my understanding,
1. you have written SharedPreferences.Editor inside saveArrayList().
2. On every single time this method called, you create a new Editor and it replaces the
previous one.
3. SharedPreferences stores in key-value pair and you are storing data in the same key
every time. (It Replaces previous values with new ones)
4. Your code might be correct for data but the flow is wrong. Try to work on your code-
flow.
Hope it helps. :)
I am trying to store and retrieve values in shared preferences but first time when I open the app, the shared preference value is NULL. From next time, it shows the values of previous key.
This is my code,
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
Set<String> set;
sharedPreferences = getApplicationContext().getSharedPreferences(mypreference, Context.MODE_PRIVATE);
databaseReferenceImages.child(postkey).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
SharedPreferences.Editor editor = sharedPreferences.edit();
Set<String> sharedlist = new HashSet<String>();
sharedlist.addAll(second);
editor.putStringSet("notifications", sharedlist);
editor.apply();
for (String a : sharedlist) {
Log.d("thesharedlist", a);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
set = sharedPreferences.getStringSet("notifications", null);
if (set != null) {
for (String a : set) {
Log.d("thesetis", a);
}
}
Here I want the values for a particular "POSTKEY"(Poskey will be different for each post)
I want to get the value of array list or "SET" outside of onDataChange method so I used shared Preferences. Its working fine for a String but not for Array list or Set. The following problem occurs,
When I open the app for the first time and click a particular post,
the value of the shared preference value which is returned is NULL.
When I open the same post for the second time, the values are
returning perfectly.
When I open second post ,the values of
previous post are returning.
When I open the first post again, the values of second post are returning.
I don't know where I am wrong. I tried clearing the values of shared preferences each time the app opens but the same problem occurs. I even followed this link but nothing worked. Any help would be great. Thanks in advance.
If you don't want to get null first time, you can do one of these 2 things:
1- call getStringSet differently
sharedPreferences.getStringSet("notifications", "it isn't saved yet!");
2- save default value to sharedpreference before getStringSet
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putStringSet("notifications", sharedlist);
editor.apply();
If you want to get current post not previous one, you should save it before. my guess is that you click on post number one and it's stored in sharedpreference and when you want to check the second one, it returns first one.
I have solved the issue by storing it in sharedpreference after 1500ms.
This is my code,
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
set = sharedPreferences.getStringSet("notifications", null);
if (set != null) {
for (String a : set) {
Log.d("thesetis", a);
}
}
}
}, 1500);
Every time my app starts an ID is generated by my program. Since each time it generates a different ID , I want to save the ID somewhere before exiting the program so I can use it again when the program runs later.
Sample ID : 125469
Note : I rather to not save it in file but some else.
Even a better solution would be to use GreenDAO here are some examples
https://github.com/greenrobot/greenDAO
https://github.com/octa-george/Android-GreenDao-Sample
GreenDAO is a light & fast ORM solution for Android that maps objects to SQLite databases. Being highly optimized for Android, greenDAO offers great performance and consumes minimal memory.
You only need the greendao jar
public class MyDaoGenerator {
public static void main(String args[]) throws Exception {
Schema schema = new Schema(1, "ro.octa.greendaosample.dao");
createSchema(schema);
new DaoGenerator().generateAll(schema, "C:/GreenDaoSchema");
}
private static void createSchema(Schema schema) {
Entity user = schema.addEntity("DBUser");
user.addIdProperty().primaryKey().autoincrement();
user.addStringProperty("email").notNull().unique();
user.addStringProperty("password").notNull();
}
After a few lines of code you have the model generated for autoincrement id, email and password.
You can use SharedPreferences or you can use SQLite database for storing purposes.
You can do it like that:
private SharedPreferences prefs;
...
...
private void initializeFromPreference() {
prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
myId = prefs.getInt("myId", myId );
}
...
...
public void onDestroy() {
SharedPreferences.Editor editor = prefs.edit();
editor.putInt("myId", myId );
editor.commit();
super.onDestroy();
}
i wouldnt use a database for a single value, Sharedpreferences is a good way to do so
You can Use SharedPreferences to store your id
SharedPreferences prefs=this.getSharedPreferences("yourPrefsKey", Context.MODE_PRIVATE);
Editor edit=prefs.edit();
//to store value
edit.putInt("Your Id Name", Id Value).commit();
//to get value
int id=prefs.getInt("Your Id Name", 0);
Here's the simple way, I can think of :)
public static SharedPreferences sharedpreferences;
sharedpreferences = getSharedPreferences("MyIds", Context.MODE_PRIVATE);
if (sharedpreferences.contains("id"))
{
String id = sharedpreferences.getString("id", "");
// *Use existing id and enjoy* ;)
}
else{
// *Generate New ID (yourID)*
Editor editor = sharedpreferences.edit();
editor.putString("id", yourID);
editor.commit();
}
A set of questions about SharedPreferences that I was looking for:
What, Why, When?
How does it work inside?
The Best Practice to use it?
Only some of those question were answered here. That's why I made some investigations, and tests.
As I've answered on my own question I've decided to share answer with other people.
I've wrote a little article that can also be found here.
Best Practice: SharedPreferences
Android provides many ways of storing application data. One of those ways leads us to the SharedPreferences object which is used to store private primitive data in key-value pairs.
All logic are based only on three simple classes:
SharedPreferences
SharedPreferences.Editor
SharedPreferences.OnSharedPreferenceChangeListener
SharedPreferences
SharedPreferences is main of them. It's responsible for getting (parsing) stored data, provides interface for getting Editor object and interfaces for adding and removing OnSharedPreferenceChangeListener
To create SharedPreferences you will need Context object (can be an application Context)
getSharedPreferences method parses Preference file and creates Map object for it
You can create it in few modes provided by Context, it's strongly recommended to use MODE_PRIVATE because creating world-readable/writable files is very dangerous, and likely to cause security holes in applications
// parse Preference file
SharedPreferences preferences = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// get values from Map
preferences.getBoolean("key", defaultValue)
preferences.get..("key", defaultValue)
// you can get all Map but be careful you must not modify the collection returned by this
// method, or alter any of its contents.
Map<String, ?> all = preferences.getAll();
// get Editor object
SharedPreferences.Editor editor = preferences.edit();
//add on Change Listener
preferences.registerOnSharedPreferenceChangeListener(mListener);
//remove on Change Listener
preferences.unregisterOnSharedPreferenceChangeListener(mListener);
// listener example
SharedPreferences.OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener
= new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
};
Editor
SharedPreferences.Editor is an Interface used for modifying values in a SharedPreferences object. All changes you make in an editor are batched, and not copied back to the original SharedPreferences until you call commit() or apply()
Use simple interface to put values in Editor
Save values synchronous with commit() or asynchronous with apply which is faster. In fact of using different threads using commit() is safer. Thats why I prefer to use commit().
Remove single value with remove() or clear all values with clear()
// get Editor object
SharedPreferences.Editor editor = preferences.edit();
// put values in editor
editor.putBoolean("key", value);
editor.put..("key", value);
// remove single value by key
editor.remove("key");
// remove all values
editor.clear();
// commit your putted values to the SharedPreferences object synchronously
// returns true if success
boolean result = editor.commit();
// do the same as commit() but asynchronously (faster but not safely)
// returns nothing
editor.apply();
Performance & Tips
SharedPreferences is a Singleton object so you can easily get as many references as you want, it opens file only when you call getSharedPreferences first time, or create only one reference for it.
// There are 1000 String values in preferences
SharedPreferences first = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 4 milliseconds
SharedPreferences second = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 0 milliseconds
SharedPreferences third = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 0 milliseconds
As SharedPreferences is a Singleton object you can change any of It's instances and not be scared that their data will be different
first.edit().putInt("key",15).commit();
int firstValue = first.getInt("key",0)); // firstValue is 15
int secondValue = second.getInt("key",0)); // secondValue is also 15
When you call get method first time it parses value by key and adds this value to the map. So for second call it just gets it from map, without parsing.
first.getString("key", null)
// call time = 147 milliseconds
first.getString("key", null)
// call time = 0 milliseconds
second.getString("key", null)
// call time = 0 milliseconds
third.getString("key", null)
// call time = 0 milliseconds
Remember the larger the Preference object is the longer get, commit, apply, remove and clear operations will be. So it's highly recommended to separate your data in different small objects.
Your Preferences will not be removed after Application update. So there are cases when you need to create some migration scheme. For example you have Application that parse local JSON in start of application, to do this only after first start you decided to save boolean flag wasLocalDataLoaded. After some time you updated that JSON and released new application version. Users will update their applications but they will not load new JSON because they already done it in first application version.
public class MigrationManager {
private final static String KEY_PREFERENCES_VERSION = "key_preferences_version";
private final static int PREFERENCES_VERSION = 2;
public static void migrate(Context context) {
SharedPreferences preferences = context.getSharedPreferences("pref", Context.MODE_PRIVATE);
checkPreferences(preferences);
}
private static void checkPreferences(SharedPreferences thePreferences) {
final double oldVersion = thePreferences.getInt(KEY_PREFERENCES_VERSION, 1);
if (oldVersion < PREFERENCES_VERSION) {
final SharedPreferences.Editor edit = thePreferences.edit();
edit.clear();
edit.putInt(KEY_PREFERENCES_VERSION, currentVersion);
edit.commit();
}
}
}
SharedPreferences are stored in an xml file in the app data folder
// yours preferences
/data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PREFS_NAME.xml
// default preferences
/data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PACKAGE_NAME_preferences.xml
Android guide.
Sample Code
public class PreferencesManager {
private static final String PREF_NAME = "com.example.app.PREF_NAME";
private static final String KEY_VALUE = "com.example.app.KEY_VALUE";
private static PreferencesManager sInstance;
private final SharedPreferences mPref;
private PreferencesManager(Context context) {
mPref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}
public static synchronized void initializeInstance(Context context) {
if (sInstance == null) {
sInstance = new PreferencesManager(context);
}
}
public static synchronized PreferencesManager getInstance() {
if (sInstance == null) {
throw new IllegalStateException(PreferencesManager.class.getSimpleName() +
" is not initialized, call initializeInstance(..) method first.");
}
return sInstance;
}
public void setValue(long value) {
mPref.edit()
.putLong(KEY_VALUE, value)
.commit();
}
public long getValue() {
return mPref.getLong(KEY_VALUE, 0);
}
public void remove(String key) {
mPref.edit()
.remove(key)
.commit();
}
public boolean clear() {
return mPref.edit()
.clear()
.commit();
}
}
Yakiv has mentioned everything about preferences so neatly and nicely. I just want to add one more point. While editing data in shared preferences we usually do
mPref.edit()
which creates a new object of SharedPreferences.Editor type every time which can result in unnecessary objects in memory. So you can maintain a reference to editor object too and save memory and object creation time and corresponding garbage collection time.
I have a strange problem. I have never had it before. When I try to save int value to my SharedPreference and then restore in other Activity. Value is always 0 even if I save there other value (for example: 1);
private String Number;
private String Profile;
and then saving values (in this case "1") to SharedPreferences in first Activity:
SharedPreferences a = FirstActivity.this.getSharedPreferences("a", MODE_PRIVATE);
SharedPreferences.Editor prefsEditorProfiles = a.edit();
prefsEditorProfiles.putInt(Profile, 1);
prefsEditorProfiles.putInt(Number, 1);
prefsEditorProfiles.commit();
then restore SharedPreferences in other Activity:
SharedPreferences a = SecondActivity.this.getSharedPreferences("a", MODE_PRIVATE);
int ab = a.getInt(Number, 0);
And application shows me 0 instead of 1. My other SharedPreferences works great. I don't know where is the problem.
I'd check what's the value of the Number and Profile variables you declared... you are using their values as keys, so if they have conflicting names, you might be overwriting one setting with the other even though the code looks right.
I'd recommend replacing this:
private String Number;
private String Profile;
With this:
private final String NUMBER = "Number";
private final String PROFILE = "Profile";
And then using those constants when setting/getting your preference value.
Do you ever set a value for
"Number" and "Profile"?
If not then that is your problem -those strings are null.
Please try to use
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
rather than using
SharedPreferences prefs = getActivity().getSharedPreferences ("PREFS_KEY", 0);
when Storing int in shared preference
I've been trying for a while to use putInt like you but it always give an error.
prefsEditorProfiles.putInt(Number, 1);
by just changing a.putInt to a.putString and retrieving it with a.getString I was able to have the correct value.
so, I guess there should be something wrong with putInt and getInt.
Anyway, try that also to have the correct value you need to continue for application.