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