Ingeniería de Software y Sistemas Computacionales | La Salle Nezahualcóyotl
Objetivo: Implementar persistencia de datos para que la aplicación "recuerde" al usuario después de cerrarse.
Añadiremos un botón en la parte superior de nuestra lista actual.
Sustituye todo el código por este bloque:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btnCerrarSesion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Cerrar Sesión"
android:backgroundTint="#e31b23"
android:textColor="#ffffff" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvUsuarios"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
Actualizaremos la lógica del botón de ingreso para grabar el nombre en el dispositivo.
Localiza tu boton.setOnClickListener e integra las líneas de persistencia:
boton.setOnClickListener {
val nombreUsuario = cuadroTexto.text.toString()
if (nombreUsuario.trim().isNotEmpty()) {
// --- PERSISTENCIA ---
val preferencias = getSharedPreferences("PREFS_SESION", MODE_PRIVATE)
val editor = preferencias.edit()
editor.putString("USER_NAME", nombreUsuario)
editor.apply()
// --------------------
val pasarPantalla = Intent(this, HomeActivity::class.java)
pasarPantalla.putExtra("USER_NAME", nombreUsuario)
startActivity(pasarPantalla)
} else {
Toast.makeText(this, "Por favor, ingresa un nombre", Toast.LENGTH_SHORT).show()
}
}
Haremos que la app revise si ya hay una sesión activa antes de mostrar el Login.
// 1. Intentar leer el archivo de preferencias val prefs = getSharedPreferences("PREFS_SESION", MODE_PRIVATE) val usuarioGuardado = prefs.getString("USER_NAME", null) // 2. Si existe un dato, saltar directo a HomeActivity if (usuarioGuardado != null) { val intent = Intent(this, HomeActivity::class.java) intent.putExtra("USER_NAME", usuarioGuardado) startActivity(intent) finish() // Destruye MainActivity de la pila }
Programaremos el botón para limpiar el almacenamiento local.
// Al final del método onCreate
val botonLogout = findViewById<Button>(R.id.btnCerrarSesion)
botonLogout.setOnClickListener {
val editor = getSharedPreferences("PREFS_SESION", MODE_PRIVATE).edit()
editor.clear()
editor.apply()
Toast.makeText(this, "Sesión finalizada", Toast.LENGTH_SHORT).show()
finish()
}
Responde las siguientes preguntas basándote en la implementación técnica realizada en el laboratorio.
1. Análisis de Persistencia:
Al usar getSharedPreferences("PREFS_SESION", MODE_PRIVATE), ¿qué sucede con los datos si el usuario fuerza el cierre de la aplicación desde el administrador de tareas? Justifica tu respuesta basándote en el método .apply().
2. Gestión de la Pila de Actividades (Backstack):
En el Paso 3, implementamos finish() después de iniciar la HomeActivity. ¿Qué problema de seguridad o de experiencia de usuario (UX) ocurriría si omitiéramos esta instrucción?
3. Seguridad y Encapsulamiento:
El parámetro MODE_PRIVATE es fundamental en la creación del archivo de preferencias. Desde la perspectiva de seguridad en Android, ¿qué impide este modo de operación respecto a otras aplicaciones instaladas en el mismo dispositivo?
4. Ciclo de Vida y Estados:
Si un alumno coloca la validación de la sesión (Paso 3) en el método onResume() en lugar del onCreate(), ¿qué diferencia de comportamiento notaría el usuario al navegar entre actividades?
💡 Nota para el reporte: Incluye capturas de pantalla de tu emulador mostrando el ingreso automático después de reiniciar la app y el regreso al login tras presionar "Cerrar Sesión".