web-dev-qa-db-fra.com

Enregistrement d'un tableau d'octets à l'aide de SharedPreferences

J'ai donc un byte [] array que j'ai créé dans mon Android. Je souhaite utiliser SharedPreferences à partir de Android pour le stocker et le récupérer à nouveau lorsque je démarre mon application). Comment puis je faire ça ?

41
user2453055

Vous pouvez essayer de l'enregistrer avec un String:

Storring le tableau:

SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("myByteArray", Arrays.toString(array));

Récupération du tableau:

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

Vous pouvez enregistrer un tableau d'octets dans SharedPreferences à l'aide d'Android.util.Base64.

Pour économiser:

String saveThis = Base64.encodeToString(array, Base64.DEFAULT);

Pour le chargement:

byte[] array = Base64.decode(stringFromSharedPrefs, Base64.DEFAULT);
95
Daniel Landau

En fait, vous agrandissez la taille d'une donnée lorsque vous la convertissez en une chaîne Base64.

la taille finale des données binaires encodées en Base64 est égale à 1,37 fois la taille des données d'origine + 814 octets (pour les en-têtes).

Il est plus rapide et efficace en mémoire d'enregistrer un octet [] dans les préférences partagées à l'aide de 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 préserve vos données (contrairement à UTF-8 et UTF-16)
  • Si vous allez transférer ces octets en dehors de l'application, en utilisant un JSON par exemple, vous devrez convertir l'octet [] en Base64 avant de les sérialiser.
  • JSON ne pourra pas comprendre les caractères étranges qu'ISO_8859_1 utilisera.

[~ # ~] astuce [~ # ~] : si vous voulez économiser plus d'espace (au cas où votre énorme octet de sauvegarde []) compresse le octet [] avant de le convertir dans n'importe quel format (ISO ou Base64)

15
Ariel Yust

Enregistrement d'un tableau dans les préférences partagées:

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

Chargement des données de la baie à partir des préférences partagées:

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

Implémentez et appelez les 2 fonctions ci-dessus. J'espère que le code ci-dessus aide

0
Zax

Je n'ai pas pu voter pour la réponse d'Ariel Yust, mais cela a parfaitement fonctionné.

D'autres réponses (comme l'encodeur Base64) n'étaient pas disponibles pour ma version d'API minimale ou n'ont pas conservé la valeur d'origine (cela peut être problématique lors du cryptage/décryptage des données)

En complément, je conseille d'utiliser des extensions dans 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)
}

Ensuite, vous l'appelez simplement sur votre chaîne:

val string = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE).getString("string", "") ?: ""
val byteArray = string.toPreservedByteArray
0
meechum