Save SparseBooleanArray to SharedPreferences - android

For my app, I need to save a simple SparseBooleanArray to memory and read it later.
Is there any way to save it using SharedPreferences?
I considered using an SQLite database but it seemed overkill for something as simple as this. Some other answers I found on StackOverflow suggested using GSON for saving it as a String but I need to keep this app very light and fast in file size. Is there any way of achieving this without relying on a third party library and while maintaining good performance?

You can use the power of JSON to save in the shared preferences for any type of object
For example SparseIntArray
Save items like Json string
public static void saveArrayPref(Context context, String prefKey, SparseIntArray intDict) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = prefs.edit();
JSONArray json = new JSONArray();
StringBuffer data = new StringBuffer().append("[");
for(int i = 0; i < intDict.size(); i++) {
data.append("{")
.append("\"key\": ")
.append(intDict.keyAt(i)).append(",")
.append("\"order\": ")
.append(intDict.valueAt(i))
.append("},");
json.put(data);
}
data.append("]");
editor.putString(prefKey, intDict.size() == 0 ? null : data.toString());
editor.commit();
}
and read json string
public static SparseIntArray getArrayPref(Context context, String prefKey) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String json = prefs.getString(prefKey, null);
SparseIntArray intDict = new SparseIntArray();
if (json != null) {
try {
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
intDict.put(item.getInt("key"), item.getInt("order"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return intDict;
}
and use like this:
SparseIntArray myKeyList = new SparseIntArray();
...
//write list
saveArrayPref(getApplicationContext(),"MyList", myKeyList);
...
//read list
myKeyList = getArrayPref(getApplicationContext(), "MyList");

Write the values separately, and keep a list of the names of the values you write:
SparseBooleanArray array = //your array;
SharedPreferences prefs = //your preferences
//write
SharedPreferences.Editor edit = prefs.edit();
Set<String> keys = new HashSet<String>(array.size());
for(int i = 0, z = array.size(); i < z; ++i) {
int key = array.keyAt(i);
keys.add(String.valueOf(key));
edit.putBoolean("key_" + key, array.valueAt(i));
}
edit.putStringSet("keys", keys);
edit.commit();
//read
Set<String> set = prefs.getStringSet("keys", null);
if(set != null && !set.isEmpty()) {
for (String key : set) {
int k = Integer.parseInt(key);
array.put(k, prefs.getBoolean("key_"+key, false));
}
}
String sets are supported since API 11.
You could instead build a single csv string and split that rather than storing the set.

You can serialize the object to a byte array and then probably base64 the byte array before saving to SharedPreferences. Object serialization is really easy, you don't need a third party library for that.
public static byte[] serialize(Object obj) {
ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
ObjectOutputStream objectOS = new ObjectOutputStream(byteArrayOS);
objectOS.writeObject(obj);
objectOS.flush();
return byteArrayOS.toByteArray();
}
public static Object deserialize(byte[] data) {
ByteArrayInputStream byteArrayIS = new ByteArrayInputStream(data);
ObjectInputStream objectIS = new ObjectInputStream(byteArrayIS);
return objectIS.readObject();
}
The code above doesn't have try catch block for simplicity. You can add it on your own.

I have been doing this as the following by using Gson
To save sparseboolean array in SharedPreference:
public void SaveSparseBoolean() {
SparseBooleanArray booleanArray = new SparseBooleanArray();
SharedPreferences sP;
sP=context.getSharedPreferences("MY_APPS_PREF",Context.MODE_PRIVATE)
SharedPreferences.Editor editor=sP.edit();
Gson gson=new Gson();
editor.putString("Sparse_Array",gson.toJson(booleanArray));
editor.commit();
}
To get the SparsebooleanArray from SharedPreferences
public SparseBooleanArray getSparseArray() {
SparseBooleanArray booleanArray;
SharedPreferences sP;
sP = context.getSharedPreferences("MY_APPS_PREF", Context.MODE_PRIVATE);
Gson gson=new Gson();
booleanArray=gson.fromJson(sP.getString("Sparse_Array",""),SparseBooleanArray.class);
return booleanArray;
}

Related

save data from arraylist to shared preferences not working

i want to add the data from arraylist to sharedpreferences and retrieve the same.
but it is not working. i am getting only one value which is the last value
not all values are retrieved from shared preferences. i am getting the values from
JSONArray first the added in the arraylist.
below is my code to save the data.
JSONArray arr = new JSONArray(strServerResponse);
JSONObject jsonObj = arr.getJSONObject(0);
for (int i = 0; i < arr.length(); i++) {
pojo = new Pojo();
JSONObject jobj2 = arr.getJSONObject(i);
String tipoftheday = jobj2.optString("tipsoftheday");
ArrayList<String> tii = new ArrayList<String>();
tii.add(tipoftheday);
SharedPreferences.Editor editor = getSharedPreferences("MyPref", MODE_PRIVATE).edit();
for (int i1 = 0; i1 < tii.size(); i1++) {
editor.putString("tipoftheday", TextUtils.join(",", tii));
editor.commit();
}
}
below is the code to retrieve data from shared preferences and using setter to set the d
ata retrieved from shared preferences and adding it to list view adapter. i am not getting what is the mistake.
SharedPreferences prefs=getSharedPreferences("MyPref", MODE_PRIVATE);
String serialized = prefs.getString("tipoftheday", null);
List<String> list = Arrays.asList(TextUtils.split(serialized,","));
for(int i=0; i < list.size(); i++){
String ttt = list.get(i);
pojo.setTip(ttt);
tipsAdapter = new TipsAdapter(TipsActivity.this, tips);
tips.add(pojo);
listTips.setAdapter(tipsAdapter);
}
How to save data in shared preferences? I am getting only one value.
how to save data in shared prefernces. i am getting only one value.
Problem is not related to SharedPreferences it is related to data-source which is currently setting inside for-loop.
Set Adapter as:
for(int i=0; i < list.size(); i++){
String ttt = list.get(i);
pojo.setTip(ttt);
tips.add(pojo);
}
tipsAdapter = new TipsAdapter(TipsActivity.this, tips);
listTips.setAdapter(tipsAdapter);
Try this:
It will work:
To store data:
StringBuilder sb = new StringBuilder();
JSONArray arr = new JSONArray(strServerResponse);
JSONObject jsonObj = arr.getJSONObject(0);
for (int i = 0; i < arr.length(); i++)
{
pojo = new Pojo();
JSONObject jobj2 = arr.getJSONObject(i);
String tipoftheday = jobj2.optString("tipsoftheday");
sb.append(tipoftheday).append(",");
}
SharedPreferences.Editor editor = getSharedPreferences("MyPref", MODE_PRIVATE).edit();
editor.putString("tipoftheday", sb).commit();
To retrieve data:
String[] strArr = getSharedPreferences("MyPref", MODE_PRIVATE).getString("tipsoftheday").split(",");
You are using two for loop when you are adding values to SharedPreference. Move out the inner loop and your code will be good to get you all values of list. Add some more line to it like below code:
for (int i = 0; i < arr.length(); i++) {
pojo = new Pojo();
JSONObject jobj2 = arr.getJSONObject(i);
String tipoftheday = jobj2.optString("tipsoftheday");
ArrayList<String> tii = new ArrayList<String>();
tii.add(tipoftheday);
}
for (int i1 = 0; i1 < tii.size(); i1++) {
SharedPreferences.Editor editor = getSharedPreferences("MyPref", MODE_PRIVATE).edit();
SharedPreferences prefs=getSharedPreferences("MyPref", MODE_PRIVATE);
StringBuffer stringBuffer = new StringBuffer();
stringBuffer = prefs.getString("tipoftheday", null).toString();
editor.putString("tipoftheday", stringBuffer.append(stringBuffer +",", tii.get(i1).toString()));
editor.commit();
}
You are losing your previous values because you are updating the same key inside your SharedPreferences.Editor. What you have to do in order to add more information afterwards is to first retreive your String value, then add your information and finally store all the info inside your SharedPreferences.Editor.
EDIT
I think it should be something like this, I have done it without any IDE or compiler, so it may have some syntax mistakes :)
SharedPreferences prefs=getSharedPreferences("MyPref", MODE_PRIVATE);
String serialized = prefs.getString("tipoftheday", null);
List<String> list;
if(serialized != null)
list = Arrays.asList(TextUtils.split(serialized,","));
list .add(tipoftheday);
SharedPreferences.Editor editor = prefs.edit();
for (int i1 = 0; i1 < tii.size(); i1++) {
editor.putString("tipoftheday", TextUtils.join(",", list));
editor.apply(); // if you do not need the return value, apply is faster than commit
}
Hope it helps
EDIT 2
Check also ρяσѕρєя K answer, he has spotted a different mistake you are making :)

How to save string array in preference while iteration is going on

Is it possible to save string array in preference while iterating its values in loop? Say for example :
String[] arrayvalue = new String[5];
for (int i = 0; i <= number; i++) {
Log.d(TAG, "ArrayValue" == " + arrayvalue[i]);
String abcd = arrayvalue[i].toString();
prefs.setData(context, abcd);
Log.d("Prefs", "Saving in Preference");
}
There are actually 5 values, so while saving I will see "Log" is executed 5 times, but while retrieving I am only seeing the last 5th value in preference, why is that so ?
//Retrieving
String converteddata = prefs.getData(context);
Log.d("Prefs", "Retreiving from Preference : " + converteddata);
Save
public synchronized String getData(Context context) {
Log.d(TAG, "getData");
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
return prefs.getString(DATA, DEFAULT_DATA);
}
//Retrieve
public synchronized void setData(Context context, String data) {
Log.d(TAG, "setData");
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
prefs.edit().putString(DATA, data).commit();
}
You can create your own String representation of the array like this:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < playlists.length; i++) {
sb.append(playlists[i]).append(",");
//here you save the string each eteration
prefsEditor.putString(PLAYLISTS, sb.toString());
}
Then when you get the String from SharedPreferences simply parse it like this:
String[] playlists = playlist.split(",");
I hope its the answer you look for.

Save the LinkedHashMap variables in to shared preferences in android

I was struck up with an issue, I would like to save the linkedhashmap variables in the shared preferences and my code is here..
public static LinkedHashMap<String, AppVariable> GlobalAppVariables;
if (Constants.DEVICE_ID == 0) {
String accounts_service = serverSync.getCentralServer(this,serial_number);
if (accounts_service != null){
Constants.MACHINE_CENTRAL_SERVER = accounts_service;
}
Constants.REGISTER_DEVICE_SERVICE = String.format("%sCommon/RegisterMachine", Constants.MACHINE_CENTRAL_SERVER);
GlobalAppVariables = serverSync.registerDevice(this, serial_number);
}
SharedPreferences sharedPref= getSharedPreferences("mypref", 0);
SharedPreferences.Editor editor= sharedPref.edit();
editor.putString("name", GlobalAppVariables.toString());
editor.commit();
SharedPreferences sharedPref1= getSharedPreferences("mypref", 0);
LinkedHashMap<String, AppVariable> reqVariables= sharedPref1.getString("name", "");
Now my issue is I would like to save the globalappvariables in shared preferences and use the same variables i.e reqVariables when wifi is not available because globalappvariables will be available only when net is available i.e from
GlobalAppVariables = serverSync.registerDevice(this, serial_number);
When I build the code like above, i am getting the issue
The method putString(String, String) in the type SharedPreferences.Editor is not applicable for the arguments (String, LinkedHashMap<String,AppVariable>)
So please suggest me how to save the appvariables. Hoping the issue is understandable . Thanks in advance.
You can not save a HashMap in to SharedPrefernces in android.
So i think you can do this via a trick,example: you will save all keys of hashmap as String[] & all value as String[]
// Try this way,hope this will help you to solve your problem...
HashMap<String,String> map = new HashMap<String, String>();
map.put("name","ANC");
map.put("address","XYZ");
map.put("age","20");
map.put("phone","123456");
// Set SharedPreferences
SharedPreferences sharedPref= getSharedPreferences("mypref", 0);
String keys="";
Iterator<String> itr = map.keySet().iterator();
while (itr.hasNext()) {
String key = itr.next();
SharedPreferences.Editor editor= sharedPref.edit();
editor.putString(key,map.get(key));
editor.commit();
keys += itr.next()+",";
}
keys = keys.substring(0,keys.length()-1);
SharedPreferences.Editor editor= sharedPref.edit();
editor.putString("keys",keys);
editor.commit();
// Get SharedPreferences
SharedPreferences sharedPref= getSharedPreferences("mypref", 0);
String[] keysArray = sharedPref.getString("keys","").split(",");
for (int i=0;i<keysArray.length;i++){
System.out.println("Key : "+keysArray[i]+" Value : "+sharedPref.getString(keysArray[i],""));
}
Put ur map into list :
for example :
LinkedHashMap < String, String > map
List < String > keyList;
List < String > valueList;
map.keySet();
map.values();
List<String> keyList = new ArrayList<String>(map.keySet());
List<String> valueList = new ArrayList<String>(map.values());
get array from ur list :
String[] MyArr = new String[My_list.size()];
MyArr = My_list.toArray(MyArr);
and then save array into ur sharedpreferences.
Save Array:
public boolean saveArray(String[] array, String arrayName, Context mContext) {
SharedPreferences prefs = mContext.getSharedPreferences("preferencename", 0);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(arrayName +"_size", array.length);
for(int i=0;i<array.length;i++)
editor.putString(arrayName + "_" + i, array[i]);
return editor.commit();
}
Load array :
public String[] loadArray(String arrayName, Context mContext) {
SharedPreferences prefs = mContext.getSharedPreferences("preferencename", 0);
int size = prefs.getInt(arrayName + "_size", 0);
String array[] = new String[size];
for(int i=0;i<size;i++)
array[i] = prefs.getString(arrayName + "_" + i, null);
return array;
}
If you don't want to code a lot, then just download Gson.
Here is the sketch:
private Type entityType = new TypeToken<LinkedHashMap<String, AppVariable>>(){}.getType();
private void save(LinkedHashMap<String, AppVariable> map){
Gson gson = new Gson();
String data = gson.toJson(map, entityType);
getSharedPreferences("mypref", 0)
.edit()
.putString("name", data)
.commit();
}
private LinkedHashMap<String, AppVariable> load(){
Gson gson = new Gson();
String data = getSharedPreferences("mypref", 0).getString("name", "");
return gson.fromJson(data, entityType);
}

how to get value from sharedpreferences and save it arraylist

how to get value from shared preferences and save it array list
I want to get the string from shared preferences so that i want save that string to array list
SharedPreferences keyValues = context.getSharedPreferences("name_icons_list", context.MODE_PRIVATE);
if(keyValues.getString(""+str,"").equals("true"))
{
holder.tb1.setChecked(true);
onApps.add(str);
System.out.println("Block appp+++++"+onApps);
System.out.println("******************************************");
System.out.println("data retrive from database"+ position);
System.out.println("******************************************");
}
You may use this code to save preference in arraylist and vice versa
public String[] getApplicationList() { Log.i("test","prefrence getapplist");
return mApplicationList;
}
public void saveApplicationList(String[] applicationList) { Log.i("test","prefrence saveapplist");
mApplicationList = applicationList;
String combined = "";
for (int i=0; i<mApplicationList.length; i++){
combined = combined + mApplicationList[i] + ";";
}
mPref.edit().putString(PREF_APPLICATION_LIST, combined).commit();
}
I believe this should do the trick:
String savedString = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
.getString("name_icons_list", "");
StringTokenizer st = new StringTokenizer(savedString, ",");
int numberOfToken = st.countTokens();
ArrayList<String> arraylist = new ArrayList<String>();
for (int i = 0; i < numberOfToken; i++) {
arraylist.add(st.nextToken());
}

How can I store an integer array in SharedPreferences?

I want to save/recall an integer array using SharedPreferences. Is this possible?
You can try to do it this way:
Put your integers into a string, delimiting every int by a character, for example a comma, and then save them as a string:
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
int[] list = new int[10];
StringBuilder str = new StringBuilder();
for (int i = 0; i < list.length; i++) {
str.append(list[i]).append(",");
}
prefs.edit().putString("string", str.toString());
Get the string and parse it using StringTokenizer:
String savedString = prefs.getString("string", "");
StringTokenizer st = new StringTokenizer(savedString, ",");
int[] savedList = new int[10];
for (int i = 0; i < 10; i++) {
savedList[i] = Integer.parseInt(st.nextToken());
}
You can't put Arrays in SharedPreferences, but you can workaround:
private static final String LEN_PREFIX = "Count_";
private static final String VAL_PREFIX = "IntValue_";
public void storeIntArray(String name, int[] array){
SharedPreferences.Editor edit= mContext.getSharedPreferences("NAME", Context.MODE_PRIVATE).edit();
edit.putInt(LEN_PREFIX + name, array.length);
int count = 0;
for (int i: array){
edit.putInt(VAL_PREFIX + name + count++, i);
}
edit.commit();
}
public int[] getFromPrefs(String name){
int[] ret;
SharedPreferences prefs = mContext.getSharedPreferences("NAME", Context.MODE_PRIVATE);
int count = prefs.getInt(LEN_PREFIX + name, 0);
ret = new int[count];
for (int i = 0; i < count; i++){
ret[i] = prefs.getInt(VAL_PREFIX+ name + i, i);
}
return ret;
}
Here's my version, based on Egor's answer. I prefer not to use StringBuilder unless I'm building an enourmous string, but thanks to Egor for using StringTokenizer -- haven't made much use of this in the past, but it's very handy! FYI, this went in my Utility class:
public static void saveIntListPrefs(
String name, Activity activity, List<Integer> list)
{
String s = "";
for (Integer i : list) {
s += i + ",";
}
Editor editor = activity.getPreferences(Context.MODE_PRIVATE).edit();
editor.putString(name, s);
editor.commit();
}
public static ArrayList<Integer> readIntArrayPrefs(String name, Activity activity)
{
SharedPreferences prefs = activity.getPreferences(Context.MODE_PRIVATE);
String s = prefs.getString(name, "");
StringTokenizer st = new StringTokenizer(s, ",");
ArrayList<Integer> result = new ArrayList<Integer>();
while (st.hasMoreTokens()) {
result.add(Integer.parseInt(st.nextToken()));
}
return result;
}
I like to use JSON, which can be stored and retrieved as a string, to represent any complex data in SharedPreferences.
So, in the case of an int array:
public void setPrefIntArray(String tag, int[] value)
{
SharedPreferences.Editor prefEditor = PreferenceManager.getDefaultSharedPreferences(context)
.edit();
String s;
try
{
JSONArray jsonArr = new JSONArray();
for (int i : value)
jsonArr.put(i);
JSONObject json = new JSONObject();
json.put(tag, jsonArr);
s = json.toString();
}
catch(JSONException excp)
{
s = "";
}
prefEditor.putString(tag, s);
prefEditor.commit();
}
public int[] getPrefIntArray(String tag, int[] defaultValue)
{
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
String s = pref.getString(tag, "");
try
{
JSONObject json = new JSONObject(new JSONTokener(s));
JSONArray jsonArr = json.getJSONArray(tag);
int[] result = new int[jsonArr.length()];
for (int i = 0; i < jsonArr.length(); i++)
result[i] = jsonArr.getInt(i);
return result;
}
catch(JSONException excp)
{
return defaultValue;
}
}
The beauty is that the same idea can be applied to any other complex data representable as a JSON.
Two solutions:
(1) Use http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html
It has split/join functions that let you join and split the integers in one liners:
StringUtils.join([1, 2, 3], ';') = "1;2;3"
StringUtils.split("1;2;3", ';') = ["1", "2", "3"]
You'd still have to convert the strings back to integers, though.
Actually, for splitting java.lang.String.split() will work just as fine:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)
(2) Use the SharedPreferences.putStringSet() (API 11):
SharedPreferences.Editor editor = preferences.edit();
int count = this.intSet.size();
if (count > 0) {
Set<String> theSet = new HashSet<String>();
for (Long l : this.intSet) {
theSet.add(String.valueOf(l));
}
editor.putStringSet(PREFS_KEY, theSet);
} else {
editor.remove(PREFS_KEY);
}
editor.commit();
And to get it back:
Set<String> theSet = this.preferences.getStringSet(PREFS_KEY, null);
if (theSet != null && !theSet.isEmpty()) {
this.intSet.clear();
for (String s : theSet) {
this.intSet.add(Integer.valueOf(s));
}
}
This code does not catch the NPEs or NumberFormatExceptions because the intSet is otherwise assured to not contain any nulls. But of course, if you cannot assure that in your code you should surround this with a try/catch.
Here is how the "convert to comma-separated String" solution could look in Kotlin, implemented as extension functions:
fun SharedPreferences.Editor.putIntArray(key: String, value: IntArray): SharedPreferences.Editor {
return putString(key, value.joinToString(
separator = ",",
transform = { it.toString() }))
}
fun SharedPreferences.getIntArray(key: String): IntArray {
with(getString(key, "")) {
with(if(isNotEmpty()) split(',') else return intArrayOf()) {
return IntArray(count(), { this[it].toInt() })
}
}
}
That way you can use putIntArray(String, IntArray) and getIntArray(String) just like the other put and set methods:
val prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
prefs.edit().putIntArray(INT_ARRAY_TEST_KEY, intArrayOf(1, 2, 3)).apply()
val intArray = prefs.getIntArray(INT_ARRAY_TEST_KEY)
I went for the below solution, it's the least verbose of what I could see in this thread (in my case I wanted to have a set as a collection). "value" is the of type Set<Int>.
Save:
sharedPreferences.edit {
if (value.isNotEmpty()) {
putStringSet(key, hashSetOf(*value.map { it.toString() }.toTypedArray()))
} else {
remove(key)
}
}
Retrieve:
val stringSet = sharedPreferences.getStringSet(key, null)
if (stringSet.isNullOrEmpty()) return emptySet()
return setOf<Int>(*stringSet.map { Integer.valueOf(it) }.toTypedArray())
You can only save primitive values in sharedPreference. Use Sqlite instead.

Categories

Resources