studio example configuracion archivo activity android sharedpreferences

android - example - SharedPreferences siempre obtiene un valor predeterminado en mi aplicación existente, pero cuando se crea una nueva, está bien.



settings activity android studio (11)

SharedPreferences no funciona correctamente en una aplicación existente. Probé de muchas maneras diferentes pero aún no funcionaba. Siempre obtenga los valores predeterminados de la aplicación comenzar de nuevo.

  • Funciona cuando uso el mismo código en la nueva aplicación creada.
  • Está funcionando todas las demás aplicaciones existentes.

¿Sabes por qué?

String default_user = "Default_User"; SharedPreferences pref = this.getSharedPreferences("TEST_SHAREDPREF", MODE_PRIVATE); String user = pref.getString("user", default_user); Log.d("SHARED CHECK", user); if (user.equals(default_user)) { SharedPreferences.Editor edit = pref.edit(); edit.putString("user", "new_user"); boolean ok = edit.commit(); user = pref.getString("user", default_user); Log.d("SHARED WRITE", user); Toast.makeText(this, user + " Save process: " + ok, Toast.LENGTH_LONG).show(); } else { Log.d("SHARED READ", user); Toast.makeText(this, "READ SharedPrefs: " + user, Toast.LENGTH_LONG).show(); }

EDIT: registro de resultados

ese bloque siempre devuelve esto, por lo que es una aplicación incorrecta y no sé por qué

//first run SHARED CHECK Default_User SHARED WRITE new_user //each time after first SHARED CHECK Default_User SHARED WRITE new_user

Ese bloque siempre devuelve esto para lo que son todas las aplicaciones.

//first run SHARED CHECK Default_User SHARED WRITE new_user //each time after first SHARED CHECK new_user SHARED READ new_user


En lugar de usar edit.commit(); , debes usar edit.apply(); . Aplicar actualizará el objeto de preferencia al instante y guardará los nuevos valores de forma asíncrona, lo que le permitirá leer los últimos valores.

Source : lea también la diferencia detallada entre commit() y apply() en esta publicación SO.

La publicación de "Fuente" a la que se hizo referencia anteriormente también indica casi el mismo problema y el cambio a apply() parece haber resuelto el problema allí.

Declaración de problemas en la publicación referenciada:

El problema es que cuando accedo a estos valores, no está devolviendo valores actualizados, me da un valor de SharedPreferences.

Pero cuando confirmo los datos en un archivo XML, los datos se actualizan en ese archivo.

PD: Y la razón por la que el mismo bloque de código no funciona en esta aplicación y en todas las demás aplicaciones también podría ser que esté utilizando el bloque en diferentes lugares o actualizando el valor en otro lugar también.


Cuando llama a apply() o commit() los cambios se guardan primero en la memoria caché de la aplicación y luego Android intenta escribir esos cambios en el disco. Lo que está sucediendo aquí es que su llamada a commit() está fallando en el disco, pero los cambios todavía se realizan en la memoria caché de la aplicación, como se puede ver en la source .

No es suficiente leer el valor de SharedPreferences, ya que ese valor podría no reflejar el verdadero valor que se encuentra en el disco, sino solo el almacenado en la memoria caché.

Lo que no está haciendo es verificar el valor booleano devuelto por la llamada a commit() , probablemente sea falso para su caso problemático. Podría volver a intentar la llamada a commit() un par de veces si se devuelve falso.


El código en sí se ve bien y dices que funciona en otras aplicaciones. Ya que ha confirmado que el archivo XML se creó correctamente, la única opción restante es que algo le pase al archivo antes de leerlo durante el inicio de la aplicación. Si no hay otro código en la aplicación que maneje las preferencias compartidas, entonces algo debe borrar el archivo durante el inicio.

Debería observar detenidamente la configuración de inicio de esta aplicación en particular y compararla con otras aplicaciones en las que esto funciona. Tal vez hay alguna opción que borra los datos del usuario cuando se inicia la aplicación. Sé que hay una opción al menos para el emulador (en Eclipse), pero no estoy seguro de si está ejecutando esto en el emulador o dispositivo.

También debe intentar iniciar la aplicación directamente desde el dispositivo en lugar de IDE. Esto indica si el problema está en la propia aplicación o en la configuración de IDE. Y trate de mover esto de onCreate (donde supongo que esto es) a onResume y compare si funciona cuando reanuda la aplicación y cuando la reinicia completamente.


Finalmente resolví ese problema. Un método fue agregado por uno de los otros desarrolladores. Todos los archivos en la carpeta data / data / packageName excepto la carpeta libs fueron eliminados por este método. Creo que intentaron eliminar la carpeta de caché.

Se quitó este método y se resolvió.


No sé si esto es correcto o no, pero puede implementar una escucha de cambio de preferencia compartida y puede iniciar sesión y verificar si no se vuelve a llamar a la preferencia compartida en otra clase, lo que nuevamente establece el valor como Usuario predeterminado .

Quiero decir que debe asegurarse de que no haya otro código que restablezca el valor del usuario.


Para guardar y recuperar datos de SharedPrefrence, cree un método de tipo de utilidad en su clase de utilidad:

A continuación, he proporcionado un fragmento de código para ambos métodos, es decir, para guardar y recuperar datos de SharedPrefrence:

public class Utility { public static void putStringValueInSharedPreference(Context context, String key, String value) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor editor = preferences.edit(); editor.putString(key, value); editor.commit(); } public static String getStringSharedPreference(Context context, String param) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); return preferences.getString(param, ""); } }

Ahora solo necesita llamar a Utility.putStringValueInSharedPreference (Activity_Context, KEY, VALUE); para poner los datos en prefrence y Utility.getStringSharedPreference (Activity_Context, KEY); para obtener valor de la preferencia. Esta metodología reduce las posibilidades de error; Que esto te sea de ayuda.


Recomiendo controlar su cheque de preferencia con otro valor de preferencia.

String user = pref.getString("user", default_user);

En su preferencia revise:

String getStatus = pref.getString("register", "nil"); if (getStatus.equals("true")) { // move on code stuff } else{ // ask for preferences }

En la parte donde se agrega la preferencia.

edit.putString("user", "new_user"); editor.putString("register", "true"); edit.commit;


Sólo tiene que utilizar el método de abajo y comprobar.

Crea una clase Java AppTypeDetails.java

import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; public class AppTypeDetails { private SharedPreferences sh; private AppTypeDetails() { } private AppTypeDetails(Context mContext) { sh = PreferenceManager.getDefaultSharedPreferences(mContext); } private static AppTypeDetails instance = null; public synchronized static AppTypeDetails getInstance(Context mContext) { if (instance == null) { instance = new AppTypeDetails(mContext); } return instance; } // get user status public String getUser() { return sh.getString("user", ""); } public void setUser(String user) { sh.edit().putString("user", user).commit(); } // Clear All Data public void clear() { sh.edit().clear().commit(); } }

Ahora SharedPreferences valor en SharedPreferences .

AppTypeDetails.getInstance(MainActivity.this).setUser(<user name>);

Obtener el formulario de valor SharedPreferences .

String userName = AppTypeDetails.getInstance(MainActivity.this).getUser();

Ahora haz cualquier cosa con el nombre de usuario.

Siempre comprobar

if(userName.trim().isEmpty()) { // Do anything here. }

porque en SharedPreferences ponemos el nombre de usuario en blanco ("")

o

puede establecer el nombre de usuario nulo en SharedPreferences entonces necesita verificar

if(userName != null){ //do anything here }

Para datos claros de SharedPreferences .

AppTypeDetails.getInstance(MainActivity.this).setUser("");

o

AppTypeDetails.getInstance(MainActivity.this).clear();


Su código es correcto, el código funciona muy bien en cualquier aplicación, parece que en alguna parte de su aplicación se modificaron las preferencias compartidas, la única forma de encontrar una solución es revisar todo su código, porque si este problema solo ocurre en una aplicación, en alguna parte de su aplicación se modifican las preferencias compartidas, para las buenas prácticas, debe tener solo una clase de archivo para la gestión de sus preferencias de esa manera, puede comentar o encontrar uso para un método y puede encontrar dónde Las preferencias compartidas han sido modificadas.

Por cierto, la mejor manera de almacenar un usuario, contraseña o cualquier información de cuenta es usar el Administrador de cuentas .

Para buenas prácticas puede ver este ejemplo de clase PreferenceHelper.

public class PreferencesHelper { public static final String DEFAULT_STRING_VALUE = "default_value"; /** * Returns Editor to modify values of SharedPreferences * @param context Application context * @return editor instance */ private static Editor getEditor(Context context){ return getPreferences(context).edit(); } /** * Returns SharedPreferences object * @param context Application context * @return shared preferences instance */ private static SharedPreferences getPreferences(Context context){ String name = "YourAppPreferences"; return context.getSharedPreferences(name, Context.MODE_PRIVATE); } /** * Save a string on SharedPreferences * @param tag tag * @param value value * @param context Application context */ public static void putString(String tag, String value, Context context) { Editor editor = getEditor(context); editor.putString(tag, value); editor.commit(); } /** * Get a string value from SharedPreferences * @param tag tag * @param context Application context * @return String value */ public static String getString(String tag, Context context) { SharedPreferences sharedPreferences = getPreferences(context); return sharedPreferences.getString(tag, DEFAULT_STRING_VALUE); }}


Una cosa que podría intentar es obtener una nueva instancia de SharedPreference después de SharedPreference y ver qué sucede:

SharedPreferences pref = this.getSharedPreferences("test", MODE_PRIVATE); String user = pref.getString("user", default_user); if (user.equals(default_user)) { pref.edit().putString("user", "new_user").commit(); SharedPreferences newPref = this.getSharedPreferences("test", MODE_PRIVATE); user = newPref.getString("user", default_user); }

Su editor está confirmando un nuevo mapa de preferencias en el disco, pero es posible que la antigua instancia de SharedPreference no sea notificada del cambio.


Utilicé el siguiente patrón de código en una de mis aplicaciones y siempre obtengo el último valor almacenado en SharedPreferences. A continuación se muestra la versión editada para su problema:

public class AppPreference implements OnSharedPreferenceChangeListener { private static final String USER = "User"; private static final String DEFAULT_USER = "Default_User"; private Context mContext; private String mDefaultUser; private SharedPreferences mPref; private static AppPreference mInstance; /** * hide it. */ private AppPreference(Context context) { mContext = context; mPref = PreferenceManager.getDefaultSharedPreferences(context); mPref.registerOnSharedPreferenceChangeListener(this); reloadPreferences(); } /** * @param context * @return single instance of shared preferences. */ public static AppPreference getInstance(Context context) { return mInstance == null ? (mInstance = new AppPreference(context)) : mInstance; } /** * @return value of default user */ public String getDefaultUser() { return mDefaultUser; } /** * Set value for default user */ public void setDefaultUser(String user) { mDefaultUser = user; mPref.edit().putString(USER, mDefaultUser).apply(); } /** * Reloads all values if preference values are changed. */ private void reloadPreferences() { mDefaultUser = mPref.getString(USER, DEFAULT_USER); // reload all your preferences value here } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { reloadPreferences(); } }

Puede establecer el valor de la siguiente manera en su actividad:

AppPreference.getInstance(this).setDefaultUser("user_value");

Para obtener el valor actualizado para el usuario guardado, use el siguiente código:

String user = AppPreference.getInstance(this).getDefaultUser();

Espero que esta solución solucione el problema que está enfrentando.