Saving byte array using SharedPreferences

Solution 1:

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

Solution 2:

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)

Solution 3:

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