Tengo una ArrayList
de objetos que tienen un nombre y un puntero de icono y quiero guardarla en SharedPreferences
. ¿Como lo puedo hacer?
NOTA: no quiero usar la base de datos
Respuestas:
Entonces, desde el sitio para desarrolladores de Android en Almacenamiento de datos :
Preferencias del usuario
Las preferencias compartidas no son estrictamente para guardar "preferencias de usuario" , como el tono de llamada que ha elegido un usuario. Si está interesado en crear preferencias de usuario para su aplicación, consulte PreferenceActivity, que proporciona un marco de actividad para que pueda crear preferencias de usuario, que se mantendrán automáticamente (utilizando preferencias compartidas).
Entonces creo que está bien, ya que son simplemente pares clave-valor los que persisten.
Para el cartel original, esto no es tan difícil. Simplemente repita la lista de matrices y agregue los elementos. En este ejemplo, utilizo un mapa por simplicidad, pero puede usar una lista de matrices y cambiarla adecuadamente:
// my list of names, icon locations
Map<String, String> nameIcons = new HashMap<String, String>();
nameIcons.put("Noel", "/location/to/noel/icon.png");
nameIcons.put("Bob", "another/location/to/bob/icon.png");
nameIcons.put("another name", "last/location/icon.png");
SharedPreferences keyValues = getContext().getSharedPreferences("name_icons_list", Context.MODE_PRIVATE);
SharedPreferences.Editor keyValuesEditor = keyValues.edit();
for (String s : nameIcons.keySet()) {
// use the name as the key, and the icon as the value
keyValuesEditor.putString(s, nameIcons.get(s));
}
keyValuesEditor.commit()
Haría algo similar para volver a leer los pares clave-valor. Hazme saber si esto funciona.
Actualización: si está utilizando API nivel 11 o posterior, existe un método para escribir un conjunto de cadenas
Independientemente del nivel de API, compruebe las matrices de cadenas y las matrices de objetos en SharedPreferences
GUARDAR 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();
}
ARRAY DE CARGA
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;
}
Escribir,
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
JSONArray jsonArray = new JSONArray();
jsonArray.put(1);
jsonArray.put(2);
Editor editor = prefs.edit();
editor.putString("key", jsonArray.toString());
System.out.println(jsonArray.toString());
editor.commit();
Leer,
try {
JSONArray jsonArray2 = new JSONArray(prefs.getString("key", "[]"));
for (int i = 0; i < jsonArray2.length(); i++) {
Log.d("your JSON Array", jsonArray2.getInt(i)+"");
}
} catch (Exception e) {
e.printStackTrace();
}
Las preferencias compartidas introdujeron métodos getStringSet
y putStringSet
en el nivel de API 11, pero eso no es compatible con versiones anteriores de Android (que aún son populares) y también se limita a conjuntos de cadenas.
Android no proporciona mejores métodos, y recorrer mapas y arreglos para guardarlos y cargarlos no es muy fácil y limpio, especialmente para los arreglos. Pero una mejor implementación no es tan difícil:
package com.example.utils;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;
import android.content.Context;
import android.content.SharedPreferences;
public class JSONSharedPreferences {
private static final String PREFIX = "json";
public static void saveJSONObject(Context c, String prefName, String key, JSONObject object) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString(JSONSharedPreferences.PREFIX+key, object.toString());
editor.commit();
}
public static void saveJSONArray(Context c, String prefName, String key, JSONArray array) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString(JSONSharedPreferences.PREFIX+key, array.toString());
editor.commit();
}
public static JSONObject loadJSONObject(Context c, String prefName, String key) throws JSONException {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
return new JSONObject(settings.getString(JSONSharedPreferences.PREFIX+key, "{}"));
}
public static JSONArray loadJSONArray(Context c, String prefName, String key) throws JSONException {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
return new JSONArray(settings.getString(JSONSharedPreferences.PREFIX+key, "[]"));
}
public static void remove(Context c, String prefName, String key) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
if (settings.contains(JSONSharedPreferences.PREFIX+key)) {
SharedPreferences.Editor editor = settings.edit();
editor.remove(JSONSharedPreferences.PREFIX+key);
editor.commit();
}
}
}
Ahora puede guardar cualquier colección en preferencias compartidas con estos cinco métodos. Trabajar con JSONObject
y JSONArray
es muy fácil. Puede usar JSONArray (Collection copyFrom)
el constructor público para hacer una JSONArray
colección de Java y usar JSONArray
los get
métodos para acceder a los elementos.
No hay límite de tamaño para las preferencias compartidas (además de los límites de almacenamiento del dispositivo), por lo que estos métodos pueden funcionar para la mayoría de los casos habituales en los que desea un almacenamiento rápido y fácil para alguna colección en su aplicación. Pero el análisis de JSON ocurre aquí, y las preferencias en Android se almacenan como XML internamente, por lo que recomiendo usar otros mecanismos de almacenamiento de datos persistentes cuando se trata de megabytes de datos.
Modo fácil para el almacenamiento de objetos complejos con el uso de la biblioteca de Google Gson [1]
public static void setComplexObject(Context ctx, ComplexObject obj){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("COMPLEX_OBJECT",new Gson().toJson(obj));
editor.commit();
}
public static ComplexObject getComplexObject (Context ctx){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
String sobj = preferences.getString("COMPLEX_OBJECT", "");
if(sobj.equals(""))return null;
else return new Gson().fromJson(sobj, ComplexObject.class);
}
Cargué una matriz de tamaños de cintura (ya creada en mi array.xml) en mi archivoferences.xml con el siguiente código. @ array / pant_inch_size es la identificación de toda la matriz.
<ListPreference
android:title="choosepantsize"
android:summary="Choose Pant Size"
android:key="pantSizePref"
android:defaultValue="34"
android:entries="@array/pant_inch_size"
android:entryValues="@array/pant_inch_size" />
Esto llenó el menú con opciones de la matriz. Establecí el tamaño predeterminado en 34, por lo que cuando aparece el menú, ven que el tamaño 34 está preseleccionado.
La forma simple es convertirlo a JSON String como el siguiente ejemplo:
Gson gson = new Gson();
String json = gson.toJson(myObj);
Luego, guarde la cadena en las preferencias compartidas. Una vez que lo necesite, simplemente obtenga la cadena de las preferencias compartidas y conviértala de nuevo a JSONArray o JSONObject (según sus requisitos).
Para la escritura:
private <T> void storeData(String key, T data) {
ByteArrayOutputStream serializedData = new ByteArrayOutputStream();
try {
ObjectOutputStream serializer = new ObjectOutputStream(serializedData);
serializer.writeObject(data);
} catch (IOException e) {
e.printStackTrace();
}
SharedPreferences sharedPreferences = getSharedPreferences(TAG, 0);
SharedPreferences.Editor edit = sharedPreferences.edit();
edit.putString(key, Base64.encodeToString(serializedData.toByteArray(), Base64.DEFAULT));
edit.commit();
}
Para leer:
private <T> T getStoredData(String key) {
SharedPreferences sharedPreferences = getSharedPreferences(TAG, 0);
String serializedData = sharedPreferences.getString(key, null);
T storedData = null;
try {
ByteArrayInputStream input = new ByteArrayInputStream(Base64.decode(serializedData, Base64.DEFAULT));
ObjectInputStream inputStream = new ObjectInputStream(input);
storedData = (T)inputStream.readObject();
} catch (IOException|ClassNotFoundException|java.lang.IllegalArgumentException e) {
e.printStackTrace();
}
return storedData;
}
Este es el código de preferencias compartidas que utilizo con éxito, consulte este enlace :
public class MainActivity extends Activity {
private static final int RESULT_SETTINGS = 1;
Button button;
public String a="dd";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button = (Button) findViewById(R.id.btnoptions);
setContentView(R.layout.activity_main);
// showUserSettings();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.settings, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_settings:
Intent i = new Intent(this, UserSettingActivity.class);
startActivityForResult(i, RESULT_SETTINGS);
break;
}
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RESULT_SETTINGS:
showUserSettings();
break;
}
}
private void showUserSettings() {
SharedPreferences sharedPrefs = PreferenceManager
.getDefaultSharedPreferences(this);
StringBuilder builder = new StringBuilder();
builder.append("\n Pet: "
+ sharedPrefs.getString("prefpetname", "NULL"));
builder.append("\n Address:"
+ sharedPrefs.getString("prefaddress","NULL" ));
builder.append("\n Your name: "
+ sharedPrefs.getString("prefname", "NULL"));
TextView settingsTextView = (TextView) findViewById(R.id.textUserSettings);
settingsTextView.setText(builder.toString());
}
}
¡FELIZ CODIFICACIÓN!
Puede usar putStringSet
Esto le permite guardar un HashSet en sus preferencias, así:
Salvar
Set<String> values;
SharedPreferences sharedPref =
mContext.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
Editor editor = sharedPref.edit();
editor.putStringSet("YOUR_KEY", values);
editor.apply();
Recuperar
SharedPreferences sharedPref =
mContext.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
Editor editor = sharedPref.edit();
Set<String> newList = editor.getStringSet("YOUR_KEY", null);
PutStringSet permite solo un Set y esta es una lista desordenada .
Cuando me molestaron con esto, obtuve la solución de serialización donde puedes serializar tu cadena, pero también se me ocurrió un truco.
Lea esto solo si no ha leído sobre la serialización, de lo contrario, baje y lea mi truco
Para almacenar los elementos de la matriz en orden, podemos serializar la matriz en una sola cadena (creando una nueva clase ObjectSerializer (copie el código de - www.androiddevcourse.com/objectserializer.html, reemplace todo excepto el nombre del paquete))
Ingresando datos en preferencia compartida:
el resto del código en la línea 38 -
Coloque el siguiente argumento como este, de modo que si los datos no se recuperan, devolverán una matriz vacía (no podemos poner una cadena vacía porque el contenedor / variable es una matriz, no una cadena)
Viniendo a mi Hack: -
Combine el contenido de la matriz en una sola cadena colocando algún símbolo entre cada elemento y luego divídalo usando ese símbolo cuando lo recupere. Porque agregar y recuperar String es fácil con preferencias compartidas. Si le preocupa dividir, busque "dividir una cadena en Java".
[Nota: Esto funciona bien si el contenido de su matriz es de tipo primitivo como string, int, float, etc. Funcionará para matrices complejas que tienen su propia estructura, suponga una guía telefónica, pero la fusión y división se convertiría en una poco complejo. ]
PD: Soy nuevo en Android, así que no sé si es un buen truco, así que déjame saber si encuentras mejores trucos.