Android 7.0 se ejecuta en un modo de inicio directo seguro cuando el dispositivo se enciende y el usuario no lo desbloqueó. A fin de permitir esto, el sistema brinda dos ubicaciones de almacenamiento para los datos:
- Almacenamiento encriptado por credenciales, que es la ubicación de almacenamiento predeterminada y solo está disponible después de que el usuario desbloquea el dispositivo.
- Almacenamiento encriptado por dispositivo, que es una ubicación de almacenamiento disponible tanto durante el modo de inicio directo como después de que el usuario desbloquea el dispositivo.
De forma predeterminada, las apps no se ejecutan durante el modo de inicio directo. Si necesitas que tu app se ejecute durante ese modo, registra los componentes que deberían hacerlo. Entre algunos de los casos comunes de apps que necesitan ejecutarse durante el modo de inicio directo se incluyen los siguientes:
- Apps que tienen notificaciones programadas, como las de alarma
- Apps que proporcionan notificaciones de usuario importantes, como las de mensajes SMS
- Apps que brindan servicios de accesibilidad, como TalkBack
Si necesitas que tu app acceda a datos mientras se ejecuta el modo de inicio directo, usa el almacenamiento que encripta dispositivo. Este tipo de almacenamiento contiene datos protegidos con una clave que solo está disponible luego de que el dispositivo realiza un inicio verificado.
En el caso de los datos que se deben encriptar mediante una clave asociada con las credenciales del usuario, como un PIN o una contraseña, usa el almacenamiento encriptado con credenciales. El almacenamiento encriptado con credenciales solo está disponible después de que el usuario desbloquea correctamente el dispositivo y hasta que lo reinicia. Si el usuario habilita la pantalla de bloqueo luego de desbloquear el dispositivo, esto no bloquea el almacenamiento encriptado por credenciales.
Cómo solicitar acceso de ejecución durante el inicio directo
Debes registrar los componentes de las apps en el sistema para que estas puedan ejecutarse durante el modo de inicio directo o acceder al almacenamiento encriptado por el dispositivo. Para registrar una app en el sistema, debes marcar los componentes como con reconocimiento de encriptación. Para marcar tu componente como con reconocimiento de encriptación, configura el atributo android:directBootAware
como verdadero en el manifiesto.
Los componentes con reconocimiento de encriptación pueden registrarse para recibir un mensaje de transmisión ACTION_LOCKED_BOOT_COMPLETED
del sistema cuando se reinicia el dispositivo. En este punto, ya está disponible el almacenamiento encriptado por dispositivo, y el componente puede realizar tareas que se deben ejecutar durante el modo de inicio directo, como activar una alarma programada.
El siguiente fragmento de código es un ejemplo de cómo registrar un BroadcastReceiver
como con reconocimiento de encriptación y de cómo agregar un filtro de intents para ACTION_LOCKED_BOOT_COMPLETED
en el manifiesto de la app:
<receiver android:directBootAware="true" > ... <intent-filter> <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" /> </intent-filter> </receiver>
Una vez que el usuario haya desbloqueado el dispositivo, todos los componentes podrán acceder tanto al almacenamiento encriptado por dispositivo como al almacenamiento encriptado por credenciales.
Cómo acceder al almacenamiento encriptado por dispositivo
Para acceder al almacenamiento encriptado por dispositivo, llama a Context.createDeviceProtectedStorageContext()
a fin de crear una segunda instancia de Context
. Todas las llamadas de API de almacenamiento realizadas usando este contexto acceden al almacenamiento encriptado por dispositivo. En el siguiente ejemplo, se accede al almacenamiento encriptado por dispositivo y se abre un archivo de datos de la app existente:
Kotlin
val directBootContext: Context = appContext.createDeviceProtectedStorageContext() // Access appDataFilename that lives in device encrypted storage val inStream: InputStream = directBootContext.openFileInput(appDataFilename) // Use inStream to read content...
Java
Context directBootContext = appContext.createDeviceProtectedStorageContext(); // Access appDataFilename that lives in device encrypted storage FileInputStream inStream = directBootContext.openFileInput(appDataFilename); // Use inStream to read content...
Usa el almacenamiento encriptado por dispositivo solo para información a la que se deba poder acceder durante el modo de inicio directo. No lo uses como almacenamiento de propósito general. En el caso de la información privada del usuario o de los datos encriptados que no sean necesarios durante el modo de inicio directo, usa el almacenamiento encriptado con credenciales.
Cómo recibir notificaciones sobre el desbloqueo del usuario
Una vez que el usuario desbloquee el dispositivo después del reinicio, tu app podrá aplicar un cambio al acceso al almacenamiento encriptado por credenciales y usar los servicios comunes del sistema que dependen de credenciales de usuario.
Si quieres recibir una notificación cuando el usuario desbloquee el dispositivo luego de reiniciarlo, registra un BroadcastReceiver
de un componente en ejecución para detectar mensajes de notificación de desbloqueo. Cuando el usuario desbloquee el dispositivo después del reinicio:
- Si en tu app hay procesos en primer plano que requieren notificación inmediata, busca el mensaje
ACTION_USER_UNLOCKED
. - Si tu app solo usa procesos en segundo plano que pueden influir en una notificación demorada, busca el mensaje
ACTION_BOOT_COMPLETED
.
Si el usuario desbloqueó el dispositivo, puedes llamar a UserManager.isUserUnlocked()
para detectarlo.
Cómo migrar datos existentes
Si un usuario actualiza el dispositivo para usar el modo de inicio directo, es posible que haya datos existentes que se deban migrar al almacenamiento encriptado por dispositivo. Usa Context.moveSharedPreferencesFrom()
y Context.moveDatabaseFrom()
para migrar datos de preferencias y de base de datos del almacenamiento encriptado por credenciales al almacenamiento encriptado por dispositivo.
Debes tener cuidado cuando decidas qué datos migrar entre estos dos tipos de almacenamiento encriptado. No debes migrar información privada del usuario, como contraseñas o tokens de autorización, al almacenamiento encriptado por el dispositivo. En algunos casos, es posible que debas gestionar conjuntos separados de datos en ambos tipos de almacenamiento encriptado.
Cómo probar tu app con reconocimiento de encriptación
Prueba tu app con el reconocimiento de encriptación en el modo de inicio directo habilitado. Hay dos maneras de habilitar el inicio directo.
Precaución: Si habilitas el inicio directo, se borrarán todos los datos de usuario del dispositivo.
En el caso de los dispositivos compatibles que ejecutan Android 7.0, habilita el inicio directo mediante una de las siguientes opciones:
- En el dispositivo, habilita Opciones para desarrolladores (si no lo has hecho aún) yendo a Configuración > Acerca del teléfono y presionando Número de compilación siete veces. Una vez que aparezca la pantalla de opciones para desarrolladores, dirígete a Configuración > Opciones para desarrolladores y selecciona Convertir a encriptación de archivo.
- Usa los siguientes comandos shell adb para habilitar el modo de inicio directo:
$ adb reboot-bootloader $ fastboot --wipe-and-use-fbe
También está disponible un modo de inicio directo emulado en caso de que debas cambiar de modo en tus dispositivos de prueba. El modo emulado solo debería usarse durante el desarrollo, y puede provocar la pérdida de datos. Para habilitar el modo de inicio directo emulado, debes establecer un patrón de bloqueo en el dispositivo, elegir "No, gracias" si te pregunta si deseas un inicio seguro al configurar un patrón de bloqueo y, luego, usar el siguiente comando shell adb:
$ adb shell sm set-emulate-fbe true
Para desactivar el modo de inicio directo emulado, usa el siguiente comando:
$ adb shell sm set-emulate-fbe false
El uso de estos comandos provoca el reinicio del dispositivo.
Cómo comprobar el estado de encriptación de la política de dispositivo
Las apps de administración de dispositivos pueden usar DevicePolicyManager.getStorageEncryptionStatus()
para comprobar el estado de encriptación actual del dispositivo. Si tu app está dirigida a API nivel inferior a 24.0 (Android 7.0), getStorageEncryptionStatus()
mostrará ENCRYPTION_STATUS_ACTIVE
si el dispositivo usa encriptación en todo el disco o encriptación basada en archivos con inicio directo. En ambos casos, los datos se almacenan encriptados de forma estática siempre. Si tu app está dirigida a API nivel 24.0 o superior, getStorageEncryptionStatus()
mostrará ENCRYPTION_STATUS_ACTIVE
si el dispositivo usa encriptación en todo el disco. Por otro lado, si el dispositivo usa encriptación basada en archivos con inicio directo, entonces mostrará ENCRYPTION_STATUS_ACTIVE_PER_USER
.
Si compilas una app de administración de dispositivos dirigida a Android 7.0, asegúrate de buscar ENCRYPTION_STATUS_ACTIVE
y ENCRYPTION_STATUS_ACTIVE_PER_USER
para determinar si el dispositivo está encriptado.
Códigos de ejemplo adicionales
El ejemplo de inicio directo también muestra cómo usar las API que se indican en esta página.