So I have a byte [] array
which I have created in my android app. I want to use SharedPreferences from android to store it and retrieve it back again when I start my app.
How can I do that ?

- 975
- 1
- 9
- 19
-
1Have you tried anything ? – Ye Lin Aung Oct 24 '13 at 03:45
5 Answers
You can save a byte array in SharedPreferences by using android.util.Base64.
For saving:
String saveThis = Base64.encodeToString(array, Base64.DEFAULT);
For loading:
byte[] array = Base64.decode(stringFromSharedPrefs, Base64.DEFAULT);

- 2,264
- 2
- 15
- 19
-
24Great copy&past solution however I use `Base64.NO_WRAP` instead of `Base64.DEFAULT` IMHO is there no reason for using line breaks in preferences. – rekire Nov 13 '14 at 09:51
You actually enlarge the size of a data when you convert it to a Base64 String.
the final size of Base64-encoded binary data is equal to 1.37 times the original data size + 814 bytes (for headers).
It's faster and memory efficient to save a byte[] in the SharedPreferences using Charsets.ISO_8859_1
private static final String PREF_NAME = "SharedPreferences_Name";
private static final String DATA_NAME = "BytesData_Name";
public static byte[] getBytes(Context ctx) {
SharedPreferences prefs = ctx.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
String str = prefs.getString(DATA_NAME, null);
if (str != null) {
return str.getBytes(Charsets.ISO_8859_1);
}
return null;
}
public static void setBytes(Context ctx, byte[] bytes) {
SharedPreferences prefs = ctx.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor e = prefs.edit();
e.putString(DATA_NAME, new String(bytes, Charsets.ISO_8859_1));
e.commit();
}
- ISO_8859_1 Preserves your data (unlike UTF-8 and UTF-16)
- If you are going to transfer these bytes outside the app, using a JSON for example, then you will have to convert the byte[] to Base64 before serializing them.
- JSON won't be able to understand the weird characters ISO_8859_1 will be using.
TIP : if you want to save on more space (in case your saving huge byte[]) compress the byte[] before you convert it to any format (ISO or Base64)

- 585
- 4
- 11
-
1If your array is huge, you shouldn't be using `SharedPreferences`. From [Saving Key-Value Sets](https://developer.android.com/training/basics/data-storage/shared-preferences.html): "If you have a **relatively small** collection of key-values that you'd like to save, you should use the SharedPreferences APIs." – Edward Brey Jan 26 '17 at 21:10
-
Is the behavior that ISO_8859_1 is 8-bit clean in Android documented anywhere? – Edward Brey Jan 26 '17 at 21:17
-
@EdwardBrey I have included a link about it, and implemented code that works on Android and iOS combo for a medical company - tested and works - try it ur self :) – Ariel Yust Jun 09 '17 at 12:42
You could try to save it has a String
:
Storing the array:
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("myByteArray", Arrays.toString(array));
Retrieving the array:
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String stringArray = settings.getString("myByteArray", null);
if (stringArray != null) {
String[] split = stringArray.substring(1, stringArray.length()-1).split(", ");
byte[] array = new byte[split.length];
for (int i = 0; i < split.length; i++) {
array[i] = Byte.parseByte(split[i]);
}
}
-
1Not working. Also why did you do 'String[] split = stringArray.substring(1, stringArray.length()-1).split(", ");' ? – user2453055 Oct 24 '13 at 04:08
-
1Can you give more details as to why it's not working? The code tests fine on my side. As for the substring, it is done because when you call `Arrays.toString(array)`, it creates a `String` of the form "[1, 2, 3, 4]". So the `substring()` is to remove the square brackets and the `split()` is to get an array of strings containing the individual numbers so we can then easily parse them into bytes. – Francis Oct 24 '13 at 04:17
-
When I'm saving byte[] of an image and after some time I want to retrieve it from sharedPreferences it freezes app 5-15 or 20 seconds based on image size. If it's big image, than it takes 25-30 seconds)) So I think the best way is to save it in file) – Hayk Mkrtchyan May 03 '19 at 17:03
-
SharedPreferences is not intended for large amount of data, it is backed by a simple xml file on the file system. Also, if your app is freezing, it may be because you are running the operation in the main UI thread? – Francis Aug 01 '19 at 16:59
I couldn't upvote Ariel Yust's answer but it worked perfectly.
Other answers (like Base64 encoder) were not available for my minimum API version or did not preserve the original value (that can be problematic when encrypting / decrypting data)
As an addition I advise to use extensions in kotlin :
val String.toPreservedByteArray: ByteArray
get() {
return this.toByteArray(Charsets.ISO_8859_1)
}
val ByteArray.toPreservedString: String
get() {
return String(this, Charsets.ISO_8859_1)
}
Then you simply call it on your string :
val string = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE).getString("string", "") ?: ""
val byteArray = string.toPreservedByteArray

- 41
- 4
Saving an Array in Shared Preferences:
public static boolean saveArray()
{
SharedPreferences sp = SharedPreferences.getDefaultSharedPreferences(this);
SharedPreferences.Editor mEdit1 = sp.edit();
mEdit1.putInt("Status_size", byteArr.size()); /* byteArr is an array */
for(int i=0;i<byteArr.size();i++)
{
mEdit1.remove("Status_" + i);
mEdit1.putString("Status_" + i, byteArr.get(i));
}
return mEdit1.commit();
}
Loading Array Data from Shared Preferences:
public static void loadArray(Context mContext)
{
Shared Preferences mSharedPreference1 = PreferenceManager.getDefaultSharedPreferences(mContext);
byteArr.clear();
int size = mSharedPreference1.getInt("Status_size", 0);
for(int i=0;i<size;i++)
{
byteArr.add(mSharedPreference1.getString("Status_" + i, null));
}
}
Implement and call the above 2 functions. I hope the above code helps

- 2,870
- 7
- 52
- 76