Cambios en los comportamientos: apps orientadas a niveles de API a partir del 28

Android 9 (nivel 28 de API) presenta varios cambios en el sistema de Android. Los siguientes cambios de comportamiento se aplican exclusivamente a las apps orientadas al nivel de API 28 o versiones posteriores. Las apps que establecen targetSdkVersion en el nivel de API 28 o versiones posteriores deben modificarla para que admita estos comportamientos de manera correcta, cuando corresponda.

Para conocer los cambios que afectan a todas las apps que se ejecutan en Android 9, independientemente del nivel de API al que se orienten, consulta Cambios en el comportamiento: todas las apps.

Servicios en primer plano

Las apps que se orientan a Android 9 o versiones posteriores y usan servicios en primer plano deben solicitar el permiso FOREGROUND_SERVICE. Este es un permiso normal, por lo que el sistema se lo otorgará automáticamente a la app que lo solicite.

Si una app orientada a Android 9 o versiones posteriores intenta crear un servicio en primer plano sin solicitar FOREGROUND_SERVICE, el sistema arroja una SecurityException.

Cambios en la privacidad

Si tu app está orientada a Android 9, debes tener en cuenta los siguientes cambios de comportamiento. Estas actualizaciones de la información de DNS y el número de serie del dispositivo mejoran la privacidad del usuario.

Baja del número de serie de compilación

En Android 9, Build.SERIAL siempre está configurado en "UNKNOWN" para proteger la privacidad del usuario.

Si tu app necesita acceder al número de serie del hardware de un dispositivo, debes solicitar el permiso READ_PHONE_STATE y, luego, llamar a getSerial().

Privacidad de DNS

Las apps orientadas a Android 9 deben respetar las API de DNS privados. En particular, las apps deben garantizar que, si el agente de resolución del sistema usa DNS por TLS, cualquier cliente DNS integrado use un DNS encriptado para el mismo nombre de host que el sistema o que esté inhabilitado en favor del agente de resolución del sistema.

Cambios de seguridad del marco

Android 9 incluye varios cambios de comportamiento que mejoran la seguridad de tu app, pero estos cambios se aplican solo si tu app se orienta al nivel de API 28 o versiones posteriores.

TLS de la red habilitada de forma predeterminada

Si tu app está orientada a Android 9 o versiones posteriores, el método isCleartextTrafficPermitted() mostrará false de forma predeterminada. Si tu app necesita habilitar texto simple para dominios específicos, debes establecer cleartextTrafficPermitted de forma explícita en true para esos dominios en la configuración de seguridad de red de tu app.

Directorios de datos basados en la Web separados por procesos

Para mejorar la estabilidad de la app y la integridad de los datos en Android 9, las apps no pueden compartir un único directorio de datos WebView entre varios procesos. Por lo general, estos directorios de datos almacenan cookies, cachés de HTTP y otro almacenamiento persistente y temporal relacionado con la navegación web.

En la mayoría de los casos, tu app debe usar clases del paquete android.webkit, como WebView y CookieManager, en un solo proceso. Por ejemplo, debes mover al mismo proceso todos los objetos Activity que usan un WebView. Puedes llamar a disableWebView() en los demás procesos de tu app para aplicar la regla de "un solo proceso" de manera más estricta. Esta llamada evita que WebView se inicialice por error en esos otros procesos, incluso si se llama desde una biblioteca dependiente.

Si tu app debe usar instancias de WebView en más de un proceso, debes asignar un sufijo de directorio de datos único para cada proceso, por medio del método WebView.setDataDirectorySuffix(), antes de usar una instancia determinada de WebView en ese proceso. Este método ubica datos web de cada proceso en su propio directorio dentro del directorio de datos de tu app.

Dominios SELinux por app

Las apps orientadas a Android 9 o versiones posteriores no pueden compartir datos con otras apps con permisos Unix accesibles para todo el mundo. Este cambio mejora la integridad de la zona de pruebas de aplicaciones para Android, en particular, el requisito de que solo esa app pueda acceder a los datos privados de una app.

Para compartir archivos con otras apps, usa un proveedor de contenido.

Cambios de conectividad

Recuento de datos de conectividad y múltiples rutas

En las apps que se orientan a Android 9 o versiones posteriores, el sistema cuenta el tráfico de red en redes que no son la predeterminada actual (como el tráfico móvil mientras el dispositivo está conectado a una red Wi-Fi) y proporciona métodos en la clase NetworkStatsManager para consultar ese tráfico.

En particular, getMultipathPreference() ahora muestra un valor basado en el tráfico de red mencionado anteriormente. A partir de Android 9, el método muestra true para los datos de celdas, pero cuando en un día se acumula más de una cierta cantidad de tráfico, comienza a mostrar false. Las apps que se ejecutan en Android 9 deben llamar al método y cumplir con esta sugerencia.

La clase ConnectivityManager.NetworkCallback ahora envía información sobre las VPN a las apps. Este cambio facilita que las apps escuchen eventos de conectividad sin tener que mezclar llamadas síncronas y asíncronas, y usar APIs limitadas. Además, significa que la transferencia de información funciona como se espera cuando un dispositivo se conecta a varias redes Wi-Fi o móviles simultáneamente.

Baja del cliente HTTP de Apache

En Android 6.0, quitamos la compatibilidad con el cliente HTTP de Apache. A partir de Android 9, esa biblioteca se quita de la ruta de clase de arranque y no está disponible de forma predeterminada para las apps.

Para seguir usando el cliente HTTP de Apache, las apps orientadas a Android 9 y versiones posteriores pueden agregar lo siguiente a su AndroidManifest.xml:

<uses-library android:name="org.apache.http.legacy" android:required="false"/>

Como alternativa al uso de la biblioteca Apache de tiempo de ejecución, las apps pueden empaquetar su propia versión de la biblioteca org.apache.http en su APK. Si lo haces, debes volver a empaquetar la biblioteca (con una utilidad como Jar Jar) para evitar problemas de compatibilidad de clases con las clases proporcionadas en el tiempo de ejecución.

Cambios de IU

Enfoque de objetos View

Las vistas con valores de superficie 0 (valores nulos de ancho y alto) ya no son enfocables.

Además, las actividades ya no asignan implícitamente el foco inicial en el modo táctil. En cambio, depende de ti solicitar explícitamente el enfoque inicial, si lo deseas.

Manejo de valores hexadecimales CSS RGBA

Las apps orientadas a Android 9 o versiones posteriores deben habilitar el comportamiento del borrador nivel 4 de módulo de color CSS para manejar colores de CSS de 4 y 8 dígitos hexadecimales.

El nivel 4 de módulo de color de CSS es compatible con Chrome desde la actualización 52, pero actualmente WebView inhabilita la función porque se descubrió que las aplicaciones para Android existentes contienen colores hexadecimales de 32 bits en la ordenación de Android (ARGB), lo que causaba errores de renderización.

Por ejemplo, el color #80ff8080 actualmente se renderiza en WebView como rojo claro opaco (#ff8080) para las apps que se orientan al nivel de API 27 o versiones anteriores. Actualmente, se ignora el componente principal (que Android interpretaría como el componente alfa). Si una app se orienta a un nivel de API 28 o superior, #80ff8080 se interpreta como un 50% de color verde claro transparente (#80ff80).

Detección de tipo MIME para archivos: URI

Las versiones de Android anteriores a Android 9 podían inferir los tipos de MIME a partir del contenido del archivo. A partir de Android 9 (nivel de API 28), las apps deben usar la extensión de archivo correcta cuando carguen los URI de file: en una WebView.

El uso del contenido del archivo para inferir los tipos de MIME puede ser una fuente de errores de seguridad, y los navegadores modernos no suelen permitirlo.

Si un archivo tiene una extensión de archivo reconocida, como .html, .txt, .js o .css, la extensión determinará el tipo de MIME. Si un archivo no tiene extensión o una no se reconoce, el tipo de MIME será texto sin formato.

Por ejemplo, un URI como file:///sdcard/test.html se renderizará como HTML, pero un URI como file:///sdcard/test se renderizará como texto sin formato, incluso si el archivo contiene datos HTML.

Elemento de desplazamiento de documentos

Android 9 controla correctamente el caso en el que el elemento raíz de un documento es el elemento que se desplaza. En versiones anteriores, la posición de desplazamiento se configuraba en el elemento del cuerpo y el elemento raíz tenía valores de desplazamiento cero. En Android 9, se habilita el comportamiento conforme a los estándares, según el cual el elemento de desplazamiento es el elemento raíz.

Además, el acceso directo a document.body.scrollTop, document.body.scrollLeft, document.documentElement.scrollTop o document.documentElement.scrollLeft se comportará de manera diferente según el SDK de destino. Para acceder a los valores de desplazamiento del viewport, usa document.scrollingElement, si está disponible.

Notificaciones de apps suspendidas

Antes de Android 9, las notificaciones de apps suspendidas se cancelaban. A partir de Android 9, las notificaciones de apps suspendidas se ocultan hasta que se reanuda.