Hola amigos 馃憢 Bienvenidos a un nuevo tutorial de Universo Android. Hoy aprenderemos a usar SharedPreferences, el sistema de almacenamiento local m谩s simple y eficiente para guardar datos peque帽os en formato clave-valor.
Al finalizar este tutorial tendr谩s una aplicaci贸n que incluir谩:
- Guardar y leer datos simples
- Almacenar diferentes tipos de datos
- Preferencias de usuario
- Sistema de login persistente
- Configuraciones de la app
- Modo oscuro/claro
- Limpiar datos almacenados
馃煩 1. ¿Qu茅 es SharedPreferences?
SharedPreferences es un sistema de almacenamiento que guarda datos en formato clave-valor en archivos XML. Es ideal para configuraciones, preferencias de usuario y datos peque帽os que necesitan persistir.
馃煩 2. Tipos de Datos Soportados
- String
- int
- long
- float
- boolean
- Set<String>
馃煩 3. Crear el Proyecto
Creamos un nuevo proyecto en Android Studio con Empty Activity.
馃煩 4. Clase Helper para SharedPreferences
馃搫 SharedPreferencesManager.java
import android.content.Context;
import android.content.SharedPreferences;
public class SharedPreferencesManager {
private static final String PREF_NAME = "MyAppPreferences";
private static final String KEY_IS_LOGGED_IN = "isLoggedIn";
private static final String KEY_USER_NAME = "userName";
private static final String KEY_USER_EMAIL = "userEmail";
private static final String KEY_USER_ID = "userId";
private static final String KEY_DARK_MODE = "darkMode";
private static final String KEY_NOTIFICATIONS = "notifications";
private static final String KEY_LANGUAGE = "language";
private static final String KEY_FIRST_TIME = "firstTime";
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
public SharedPreferencesManager(Context context) {
prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
editor = prefs.edit();
}
// Guardar login
public void saveLoginData(String userName, String email, int userId) {
editor.putBoolean(KEY_IS_LOGGED_IN, true);
editor.putString(KEY_USER_NAME, userName);
editor.putString(KEY_USER_EMAIL, email);
editor.putInt(KEY_USER_ID, userId);
editor.apply();
}
// Verificar si est谩 logueado
public boolean isLoggedIn() {
return prefs.getBoolean(KEY_IS_LOGGED_IN, false);
}
// Obtener nombre de usuario
public String getUserName() {
return prefs.getString(KEY_USER_NAME, "");
}
// Obtener email
public String getUserEmail() {
return prefs.getString(KEY_USER_EMAIL, "");
}
// Obtener ID de usuario
public int getUserId() {
return prefs.getInt(KEY_USER_ID, -1);
}
// Guardar modo oscuro
public void setDarkMode(boolean enabled) {
editor.putBoolean(KEY_DARK_MODE, enabled);
editor.apply();
}
// Obtener estado modo oscuro
public boolean isDarkMode() {
return prefs.getBoolean(KEY_DARK_MODE, false);
}
// Guardar notificaciones
public void setNotifications(boolean enabled) {
editor.putBoolean(KEY_NOTIFICATIONS, enabled);
editor.apply();
}
// Obtener estado notificaciones
public boolean isNotificationsEnabled() {
return prefs.getBoolean(KEY_NOTIFICATIONS, true);
}
// Guardar idioma
public void setLanguage(String language) {
editor.putString(KEY_LANGUAGE, language);
editor.apply();
}
// Obtener idioma
public String getLanguage() {
return prefs.getString(KEY_LANGUAGE, "es");
}
// Primera vez
public boolean isFirstTime() {
return prefs.getBoolean(KEY_FIRST_TIME, true);
}
// Marcar como no primera vez
public void setFirstTime(boolean firstTime) {
editor.putBoolean(KEY_FIRST_TIME, firstTime);
editor.apply();
}
// Cerrar sesi贸n
public void logout() {
editor.putBoolean(KEY_IS_LOGGED_IN, false);
editor.remove(KEY_USER_NAME);
editor.remove(KEY_USER_EMAIL);
editor.remove(KEY_USER_ID);
editor.apply();
}
// Limpiar todas las preferencias
public void clearAll() {
editor.clear();
editor.apply();
}
}馃煩 5. Dise帽o XML Principal
馃搫 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SharedPreferences Demo"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="#2196F3"
android:layout_marginBottom="24dp" />
<!-- Secci贸n de Login -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Datos de Usuario"
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginBottom="16dp" />
<EditText
android:id="@+id/txtUserName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nombre de usuario"
android:padding="12dp"
android:background="@drawable/edittext_background" />
<EditText
android:id="@+id/txtEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email"
android:inputType="textEmailAddress"
android:padding="12dp"
android:background="@drawable/edittext_background"
android:layout_marginTop="12dp" />
<Button
android:id="@+id/btnSave"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Guardar Datos"
android:layout_marginTop="16dp" />
<Button
android:id="@+id/btnLoad"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Cargar Datos"
android:layout_marginTop="8dp" />
<!-- Separador -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp" />
<!-- Configuraciones -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Configuraciones"
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginBottom="16dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Modo Oscuro"
android:textSize="16sp" />
<Switch
android:id="@+id/switchDarkMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginTop="16dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Notificaciones"
android:textSize="16sp" />
<Switch
android:id="@+id/switchNotifications"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Idioma"
android:textSize="16sp"
android:layout_marginTop="24dp"
android:layout_marginBottom="8dp" />
<Spinner
android:id="@+id/spinnerLanguage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp" />
<!-- Separador -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp" />
<!-- Informaci贸n almacenada -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Datos Almacenados"
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginBottom="16dp" />
<TextView
android:id="@+id/txtStoredData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="No hay datos almacenados"
android:padding="16dp"
android:background="#F5F5F5"
android:textSize="14sp" />
<!-- Botones de acci贸n -->
<Button
android:id="@+id/btnLogout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Cerrar Sesi贸n"
android:backgroundTint="#FF9800"
android:layout_marginTop="24dp" />
<Button
android:id="@+id/btnClearAll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Limpiar Todo"
android:backgroundTint="#F44336"
android:layout_marginTop="8dp" />
</LinearLayout>
</ScrollView>馃煩 6. Crear Drawable para EditText
馃搫 res/drawable/edittext_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF" />
<corners android:radius="8dp" />
<stroke android:width="1dp" android:color="#CCCCCC" />
<padding android:left="12dp" android:top="12dp"
android:right="12dp" android:bottom="12dp" />
</shape>馃煩 7. MainActivity
馃搫 MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
EditText txtUserName, txtEmail;
Switch switchDarkMode, switchNotifications;
Spinner spinnerLanguage;
TextView txtStoredData;
Button btnSave, btnLoad, btnLogout, btnClearAll;
SharedPreferencesManager prefsManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefsManager = new SharedPreferencesManager(this);
initializeViews();
setupLanguageSpinner();
loadStoredData();
setupListeners();
}
private void initializeViews() {
txtUserName = findViewById(R.id.txtUserName);
txtEmail = findViewById(R.id.txtEmail);
switchDarkMode = findViewById(R.id.switchDarkMode);
switchNotifications = findViewById(R.id.switchNotifications);
spinnerLanguage = findViewById(R.id.spinnerLanguage);
txtStoredData = findViewById(R.id.txtStoredData);
btnSave = findViewById(R.id.btnSave);
btnLoad = findViewById(R.id.btnLoad);
btnLogout = findViewById(R.id.btnLogout);
btnClearAll = findViewById(R.id.btnClearAll);
}
private void setupLanguageSpinner() {
String[] languages = {"Espa帽ol", "English", "Portugu锚s", "Fran莽ais"};
ArrayAdapter<String> adapter = new ArrayAdapter<>(
this,
android.R.layout.simple_spinner_item,
languages
);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerLanguage.setAdapter(adapter);
// Cargar idioma guardado
String savedLanguage = prefsManager.getLanguage();
int position = getLanguagePosition(savedLanguage);
spinnerLanguage.setSelection(position);
}
private int getLanguagePosition(String language) {
switch (language) {
case "es": return 0;
case "en": return 1;
case "pt": return 2;
case "fr": return 3;
default: return 0;
}
}
private String getLanguageCode(int position) {
switch (position) {
case 0: return "es";
case 1: return "en";
case 2: return "pt";
case 3: return "fr";
default: return "es";
}
}
private void loadStoredData() {
// Cargar switches
switchDarkMode.setChecked(prefsManager.isDarkMode());
switchNotifications.setChecked(prefsManager.isNotificationsEnabled());
// Mostrar datos almacenados
displayStoredData();
}
private void setupListeners() {
// Bot贸n Guardar
btnSave.setOnClickListener(v -> saveUserData());
// Bot贸n Cargar
btnLoad.setOnClickListener(v -> loadUserData());
// Switch Modo Oscuro
switchDarkMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
prefsManager.setDarkMode(isChecked);
Toast.makeText(this,
"Modo oscuro: " + (isChecked ? "Activado" : "Desactivado"),
Toast.LENGTH_SHORT).show();
displayStoredData();
});
// Switch Notificaciones
switchNotifications.setOnCheckedChangeListener((buttonView, isChecked) -> {
prefsManager.setNotifications(isChecked);
Toast.makeText(this,
"Notificaciones: " + (isChecked ? "Activadas" : "Desactivadas"),
Toast.LENGTH_SHORT).show();
displayStoredData();
});
// Spinner Idioma
spinnerLanguage.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String languageCode = getLanguageCode(position);
prefsManager.setLanguage(languageCode);
displayStoredData();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
});
// Bot贸n Cerrar Sesi贸n
btnLogout.setOnClickListener(v -> logout());
// Bot贸n Limpiar Todo
btnClearAll.setOnClickListener(v -> clearAllData());
}
private void saveUserData() {
String userName = txtUserName.getText().toString().trim();
String email = txtEmail.getText().toString().trim();
if (userName.isEmpty() || email.isEmpty()) {
Toast.makeText(this, "Completa todos los campos", Toast.LENGTH_SHORT).show();
return;
}
// Guardar datos (simulando ID de usuario)
int userId = (int) (Math.random() * 1000);
prefsManager.saveLoginData(userName, email, userId);
Toast.makeText(this, "Datos guardados exitosamente", Toast.LENGTH_SHORT).show();
// Limpiar campos
txtUserName.setText("");
txtEmail.setText("");
displayStoredData();
}
private void loadUserData() {
if (!prefsManager.isLoggedIn()) {
Toast.makeText(this, "No hay datos de usuario guardados", Toast.LENGTH_SHORT).show();
return;
}
String userName = prefsManager.getUserName();
String email = prefsManager.getUserEmail();
txtUserName.setText(userName);
txtEmail.setText(email);
Toast.makeText(this, "Datos cargados", Toast.LENGTH_SHORT).show();
}
private void displayStoredData() {
StringBuilder data = new StringBuilder();
if (prefsManager.isLoggedIn()) {
data.append("馃懁 Usuario Logueado\n\n");
data.append("Nombre: ").append(prefsManager.getUserName()).append("\n");
data.append("Email: ").append(prefsManager.getUserEmail()).append("\n");
data.append("ID: ").append(prefsManager.getUserId()).append("\n\n");
} else {
data.append("❌ No hay sesi贸n activa\n\n");
}
data.append("⚙️ Configuraciones:\n\n");
data.append("Modo Oscuro: ").append(prefsManager.isDarkMode() ? "✓" : "✗").append("\n");
data.append("Notificaciones: ").append(prefsManager.isNotificationsEnabled() ? "✓" : "✗").append("\n");
data.append("Idioma: ").append(prefsManager.getLanguage()).append("\n");
data.append("Primera Vez: ").append(prefsManager.isFirstTime() ? "S铆" : "No").append("\n");
txtStoredData.setText(data.toString());
}
private void logout() {
prefsManager.logout();
txtUserName.setText("");
txtEmail.setText("");
displayStoredData();
Toast.makeText(this, "Sesi贸n cerrada", Toast.LENGTH_SHORT).show();
}
private void clearAllData() {
prefsManager.clearAll();
txtUserName.setText("");
txtEmail.setText("");
switchDarkMode.setChecked(false);
switchNotifications.setChecked(true);
spinnerLanguage.setSelection(0);
displayStoredData();
Toast.makeText(this, "Todos los datos eliminados", Toast.LENGTH_SHORT).show();
}
}馃煩 8. Ejemplo de Uso Directo
// Guardar datos
SharedPreferences prefs = getSharedPreferences("MiApp", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("nombre", "Juan");
editor.putInt("edad", 25);
editor.putBoolean("premium", true);
editor.apply(); // o editor.commit()
// Leer datos
String nombre = prefs.getString("nombre", "");
int edad = prefs.getInt("edad", 0);
boolean premium = prefs.getBoolean("premium", false);
// Eliminar un dato
editor.remove("nombre");
editor.apply();
// Limpiar todo
editor.clear();
editor.apply();馃煩 9. Diferencia entre apply() y commit()
| M茅todo | Descripci贸n |
|---|---|
apply() | As铆ncrono, m谩s r谩pido, no retorna valor |
commit() | S铆ncrono, bloquea thread, retorna boolean |
馃煩 10. M茅todos Principales
| M茅todo | Descripci贸n |
|---|---|
putString() | Guarda String |
putInt() | Guarda int |
putBoolean() | Guarda boolean |
getString() | Lee String |
getInt() | Lee int |
getBoolean() | Lee boolean |
remove() | Elimina clave |
clear() | Elimina todo |
contains() | Verifica si existe |
▶️ C贸mo Ejecutar
- Abre Android Studio
- Presiona Run
- Guarda datos y cierra la app
- 脕brela nuevamente y verifica que los datos persisten
馃И Resultado Final
Aplicaci贸n que guarda preferencias, configuraciones de usuario y mantiene sesi贸n activa incluso despu茅s de cerrar la app.
馃摜 Descargar Proyecto
馃憠
馃檶 Gracias por Visitar mi Blog
✔️ Comp谩rtelo
✔️ D茅jame un comentario
✔️ S铆gueme para m谩s contenido
❓ Preguntas Frecuentes
1. ¿Qu茅 es SharedPreferences?
Sistema de almacenamiento local en formato clave-valor para datos peque帽os y configuraciones.
2. ¿Es seguro para contrase帽as?
No. Para datos sensibles usa EncryptedSharedPreferences o Room Database.
3. ¿Cu谩ndo usar apply() o commit()?
Usa apply() generalmente (m谩s r谩pido). Usa commit() solo si necesitas el resultado booleano.
4. ¿D贸nde se guardan los datos?
En archivos XML en /data/data/paquete/shared_prefs/

No hay comentarios:
Publicar un comentario