Android 10 incluye cambios de comportamiento que podrían afectar a tu app.
Los cambios que se indican en esta página se aplican a tu app cuando se ejecuta
en Android 10, independientemente de la targetSdkVersion
de la app. Deberías probar
tu app y modifícala según sea necesario para admitir estos cambios de manera correcta.
Si la targetSdkVersion de tu app es 29
o una versión posterior, también deberás
admitir cambios adicionales. Asegúrate de leer los cambios en el comportamiento para apps que se orientan al nivel de API 29 para obtener detalles.
Nota: Además de los cambios que se enumeran en esta página, Android 10 presenta varios cambios y restricciones basados en la privacidad, incluidos los siguientes:
- Acceso en segundo plano a la ubicación del dispositivo
- Inicio de actividades en segundo plano
- Información sobre la afinidad de contactos
- Aleatorización de direcciones MAC
- Metadatos de la cámara
- Modelo de permisos
Estos cambios afectan a todas las apps y mejoran la privacidad del usuario. Para obtener más información cómo admitir estos cambios, consulta la Página Cambios en la privacidad.
Restricciones en interfaces no SDK
Para garantizar la estabilidad y compatibilidad de las apps, la plataforma comenzó a restringir qué interfaces que no pertenecen al SDK que tu app puede usar en Android 9 (nivel de API 28). Android 10 incluye listas actualizadas de interfaces restringidas que no pertenecen al SDK en función de la colaboración con desarrolladores de Android y las pruebas internas más recientes. Nuestro objetivo es asegurarnos de que el acceso hay alternativas disponibles antes de restringir las interfaces que no pertenecen al SDK.
Si no orientarás tu app a Android 10 (nivel de API 29), algunos de estos cambios podría no afectarte de inmediato. Sin embargo, aunque actualmente puedes usar algunas interfaces que no pertenecen al SDK (según el nivel de API al que esté orientada la app), utilizar cualquier método o campo que no pertenezca al SDK siempre implica un gran riesgo de error para tu app.
Si no sabes con seguridad si tu app usa este tipo de interfaces, puedes probarla para verificarlo. Si tu app depende de interfaces que no pertenecen al SDK, deberías planificar migración a alternativas de SDK. Sin embargo, sabemos que algunas apps tienen casos prácticos válidos para usarlas. Si no encuentras una alternativa a usar una interfaz que no pertenece al SDK para una función de tu app, debes solicitar una nueva API pública
Para obtener más información, consulta Actualizaciones a las restricciones de interfaces que no pertenecen al SDK para Android 10. y consulta Restricciones en interfaces que no pertenecen al SDK.
Navegación por gestos
A partir de Android 10, los usuarios pueden habilitar la navegación por gestos en todo el dispositivo. Si un usuario habilita la navegación por gestos, esta acción afecta a todas las apps en el dispositivo, independientemente de si se orientan al nivel de API 29 o no. Por ejemplo, si el usuario desliza desde el borde de la pantalla, el sistema interpreta ese gesto como un gesto de retroceso a menos que una app anule ese gesto específicamente para partes de la pantalla.
Para que tu aplicación sea compatible con la navegación por gestos, tendrás que extender el contenido de la app de borde a borde y manejar los gestos conflictivos de manera adecuada. Para obtener más información, consulta el artículo Navegación por gestos en la documentación de Google Cloud.
NDK
En Android 10, se incluyen los siguientes cambios en el NDK.
Los objetos compartidos no pueden contener reubicaciones de texto
Uso no permitido de Android 6.0 (nivel de API 23) de reubicaciones de texto en objetos compartidos. El código se debe cargar tal como está y no debe modificarse. Este cambio mejora la seguridad y los tiempos de carga de la app.
SELinux aplica esta restricción en las apps que se orientan a Android 10 o versiones posteriores. Si estas apps continúan usando objetos compartidos que contienen texto las reubicaciones, tienen un alto riesgo de fallar.
Cambios en las bibliotecas Bionic y las rutas de vinculador dinámico
A partir de Android 10, varias rutas de acceso son vínculos simbólicos archivos regulares. Apps que han dependido de que las rutas fueran archivos normales puede romperse:
/system/lib/libc.so
->/apex/com.android.runtime/lib/bionic/libc.so
/system/lib/libm.so
->/apex/com.android.runtime/lib/bionic/libm.so
/system/lib/libdl.so
->/apex/com.android.runtime/lib/bionic/libdl.so
/system/bin/linker
->/apex/com.android.runtime/bin/linker
Estos cambios se aplican también a las variantes de 64 bits del archivo, con
Se reemplazó lib/
por lib64/
.
Para la compatibilidad, los symlinks se proporcionan en las rutas de acceso anteriores. Por ejemplo, /system/lib/libc.so
es un symlink a /apex/com.android.runtime/lib/bionic/libc.so
. De esta manera,
dlopen(“/system/lib/libc.so”)
sigue funcionando, pero las apps encontrarán
la diferencia cuando intentan examinar las bibliotecas cargadas leyendo
/proc/self/maps
o algo similar, lo cual no es habitual, pero descubrimos que
algunas lo hacen como parte de su proceso antipiratería. Si es así, el
Las rutas /apex/…
se deben agregar como rutas válidas para los archivos Bionic.
Bibliotecas y objetos binarios del sistema asignados a memoria de solo ejecución
A partir de Android 10, los segmentos ejecutables de objetos binarios del sistema
y las bibliotecas se asignan a la memoria de solo ejecución (no legible) como
técnica contra ataques de reutilización de código. Si tu app realiza operaciones de lectura en
segmentos de memoria marcados como de solo ejecución (ya sea por un error, una vulnerabilidad o
inspección intencional de la memoria: el sistema envía una señal SIGSEGV
a tu app.
Para identificar si este comportamiento causó una falla
archivo tombstone en /data/tombstones/
. Una falla relacionada con la ejecución solo contiene el siguiente mensaje de anulación:
Cause: execute-only (no-read) memory access error; likely due to data in .text.
Para solucionar este problema y realizar operaciones como la inspección de memoria, es
posible marcar los segmentos de solo ejecución como de lectura y ejecución llamando
mprotect()
Sin embargo, te recomendamos revertir la configuración a "solo ejecución" una vez que termines, ya que de esta manera se brindará más protección a tu app y los usuarios.
Seguridad
Android 10 incluye los siguientes cambios de seguridad.
TLS 1.3 habilitado de forma predeterminada
En Android 10 y versiones posteriores, TLS 1.3 está habilitado de forma predeterminada para todos conexiones TLS. A continuación, se presentan algunos detalles importantes sobre nuestra TLS 1.3 implementación:
- Los conjuntos de algoritmos de cifrado de TLS 1.3 no se pueden personalizar. Aquellos que son compatibles siempre están habilitados cuando TLS 1.3 está habilitado. Cualquier intento de inhabilitar
llamando a
setEnabledCipherSuites()
se ignora. - Cuando se negocia TLS 1.3,
HandshakeCompletedListener
los objetos se llaman antes de que se agreguen sesiones a la caché de sesiones. (En TLS 1.2, y otras versiones anteriores, se llama a estos objetos después de que se agregan las sesiones a la caché de la sesión). - En algunas situaciones en las que
SSLEngine
de instancias arrojan unSSLHandshakeException
activado versiones anteriores de Android, estas instancias muestran unSSLProtocolException
en su lugar en Android 10 y versiones posteriores. - No se admite el modo 0-RTT.
Si lo deseas, puedes obtener un SSLContext
que tenga TLS 1.3 inhabilitado con una llamada a SSLContext.getInstance("TLSv1.2")
.
También puedes habilitar o inhabilitar versiones de protocolo por conexión mediante
llamando a setEnabledProtocols()
en un objeto adecuado.
Los certificados firmados con SHA-1 no son confiables en TLS
En Android 10, los certificados que usan el algoritmo de hash SHA-1 no son confiables en las conexiones TLS. Las AC raíz no emitieron ese certificado desde 2016 y ya no se consideran confiables en Chrome ni en otros navegadores importantes.
Cualquier intento de conexión falla si la conexión es con un sitio que presenta una certificado con SHA-1.
Mejoras y cambios en el comportamiento de KeyChain
Algunos navegadores, como Google Chrome, permiten que los usuarios elijan un certificado cuando un
El servidor TLS envía un mensaje de solicitud de certificado como parte de un protocolo de enlace TLS. Hasta el
Android 10
Los objetos KeyChain
respetan a las entidades emisoras
los parámetros de especificación clave cuando llamas a KeyChain.choosePrivateKeyAlias()
para
mostrar a los usuarios un mensaje de selección de certificado. En particular, esta instrucción no
contienen opciones que no cumplen con las especificaciones del servidor.
Si no hay ningún certificado disponible para que el usuario seleccione, como sucede cuando no hay certificados coinciden con la especificación del servidor o si un dispositivo no tiene ninguno certificados instalados, no se mostrará la solicitud de selección de certificado.
Además, no es necesario en Android 10 o versiones posteriores tener una
bloqueo de pantalla del dispositivo para importar claves o certificados de la AC a un objeto KeyChain
.
Otros cambios en la criptografía y en TLS
Se realizaron pequeños cambios en las bibliotecas de criptografía y TLS que se aplicarán en Android 10:
- Los algoritmos de cifrado AES/GCM/NoPadding y ChaCha20/Poly1305/NoPadding devuelven más
tamaños de búfer más precisos a partir de
getOutputSize()
. - El conjunto de algoritmos de cifrado
TLS_FALLBACK_SCSV
se omite de los intentos de conexión con un protocolo máximo de TLS 1.2 o superior. Debido a las mejoras en el servidor TLS no recomendamos probar el resguardo de TLS externo. En su lugar, recomendamos basarse en la negociación de versiones de TLS. - ChaCha20-Poly1305 es un alias para ChaCha20/Poly1305/NoPadding.
- Los nombres de hosts con puntos finales no se consideran nombres de hosts de SNI válidos.
- La extensión supported_signature_algorithms admitida en
CertificateRequest
es cuando se elige una clave de firma para las respuestas de certificados. - Las claves de firma opacas, como las del almacén de claves de Android, se pueden usar con Firmas RSA-PSS en TLS
Transmisiones por Wi-Fi directo
En Android 10, las siguientes transmisiones relacionadas con Wi-Fi Los anuncios directos no son fijos:
Si tu app dependió de la recepción de estas transmisiones en el registro debido a
estaban fijos, usa el método get()
apropiado en la inicialización para
en su lugar, obtener la información.
Capacidades de reconocimiento de Wi-Fi
Android 10 agrega compatibilidad para facilitar la creación de un socket TCP/UDP mediante reconocimiento de Wi-Fi
de rutas de datos. Para crear un socket TCP/UDP que se conecte a un ServerSocket
, el dispositivo del cliente debe conocer la dirección IPv6 y el puerto del servidor. Esto anteriormente
necesario para comunicarse fuera de banda, por ejemplo, mediante Bluetooth o la capa de reconocimiento de Wi-Fi.
o descubiertos en banda mediante otros protocolos, como mDNS. Con
Android 10, la información se puede comunicar como parte de la configuración de red.
El servidor puede realizar cualquiera de las siguientes acciones:
- Inicializar un
ServerSocket
y obtener o configurar el puerto que se usará - Especificar la información del puerto como parte de la solicitud de red de reconocimiento de Wi-Fi
En la siguiente muestra de código, se indica cómo especificar la información del puerto como parte de la solicitud de red:
Kotlin
val ss = ServerSocket() val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle) .setPskPassphrase("some-password") .setPort(ss.localPort) .build() val myNetworkRequest = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE) .setNetworkSpecifier(ns) .build()
Java
ServerSocket ss = new ServerSocket(); WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier .Builder(discoverySession, peerHandle) .setPskPassphrase(“some-password”) .setPort(ss.getLocalPort()) .build(); NetworkRequest myNetworkRequest = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE) .setNetworkSpecifier(ns) .build();
Luego, el cliente realiza una solicitud de red de reconocimiento de Wi-Fi para obtener las direcciones IPv6 y el puerto que proporciona el servidor:
Kotlin
val callback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { ... } override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) { ... } override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { ... val ti = networkCapabilities.transportInfo if (ti is WifiAwareNetworkInfo) { val peerAddress = ti.peerIpv6Addr val peerPort = ti.port } } override fun onLost(network: Network) { ... } }; connMgr.requestNetwork(networkRequest, callback)
Java
callback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { ... } @Override public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) { ... } @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { ... TransportInfo ti = networkCapabilities.getTransportInfo(); if (ti instanceof WifiAwareNetworkInfo) { WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti; Inet6Address peerAddress = info.getPeerIpv6Addr(); int peerPort = info.getPort(); } } @Override public void onLost(Network network) { ... } }; connMgr.requestNetwork(networkRequest, callback);
SYSTEM_ALERT_WINDOW en dispositivos Go
Las apps que se ejecutan en dispositivos con Android 10 (edición Go) no pueden recibir el
SYSTEM_ALERT_WINDOW
permiso. Esto se debe a que el procesamiento de ventanas superpuestas usa demasiada memoria, lo que es particularmente dañino para el rendimiento de los dispositivos Android con poca memoria.
Si una app que se ejecuta en un dispositivo Go con Android 9 o versiones anteriores recibe el
SYSTEM_ALERT_WINDOW
, la app retiene el permiso incluso si la
se actualice a Android 10. Sin embargo, las apps que aún no tienen eso
no se le puede otorgar permiso después de que se actualiza el dispositivo.
Si una app en un dispositivo Go envía un intent con la acción.
ACTION_MANAGE_OVERLAY_PERMISSION
,
el sistema rechaza automáticamente la solicitud y lleva al usuario a un
la pantalla Configuración que indica que el permiso no está permitido porque
ralentiza el dispositivo. Si una app en un dispositivo Go llama a Settings.canDrawOverlays()
, el método siempre mostrará un resultado falso. Estas restricciones no se aplican a las apps
que recibió el permiso SYSTEM_ALERT_WINDOW
antes de que el dispositivo se
se actualizó a Android 10.
Advertencias para las apps orientadas a versiones anteriores de Android
Los dispositivos que ejecutan Android 10 o versiones posteriores advierten a los usuarios la primera vez que estos ejecutan una app orientada a Android 5.1 (nivel de API 22) o a una versión anterior. Si la aplicación requiere que el usuario otorgue permisos, también se le da una oportunidad para ajustar los permisos de la app antes de que esta pueda ejecutarse tiempo.
Debido a la API objetivo de Google Play empresariales, un usuario ve estas advertencias solo cuando ejecuta una app que no se actualizó recientemente. En el caso de las apps que se distribuyen en otras tiendas, se usa una API objetivo similar. en la nube durante 2019. Para obtener más información sobre estos requisitos, consulta Cómo expandir los requisitos del nivel de API objetivo en 2019.
Eliminación de conjuntos de cifrado SHA-2 CBC
Se quitaron de la plataforma los siguientes conjuntos de cifrado SHA-2 CBC:
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Estos conjuntos de cifrado son menos seguros que otros similares que usan GCM. y la mayoría de los servidores admiten las variantes de GCM y CBC de estos cifrados paquetes ni admitir ninguno de ellos.
Uso de apps
Android 10 presenta los siguientes cambios en el comportamiento relacionados con el uso de apps:
Mejoras en el uso de apps de UsageStats: Android 10 realiza un seguimiento preciso del uso de la app con UsageStats cuando las apps usarse en el modo de pantalla dividida o pantalla en pantalla. Además, Android 10 puede realizar un seguimiento adecuado del uso de las apps instantáneas.
Escala de grises por app Android 10 puede establecer un modo de visualización en escala de grises para cada app.
Estado de distracción por app: Android 10 puede configurar las apps de forma selectiva en un "estado de distracción" en el que se suprimen sus notificaciones y no aparecen como apps sugeridas.
Suspensión y reproducción: En Android 10, las apps suspendidas no pueden reproducir audio.
Cambios en la conexión HTTPS
Si una app que ejecuta Android 10 pasa null
a
setSSLSocketFactory()
,
un IllegalArgumentException
o cuándo ocurre. En versiones anteriores, se pasaba null
a setSSLSocketFactory()
.
tuvo el mismo efecto que pasar el valor predeterminado actual
Factory.
La biblioteca android.preference dejó de estar disponible
La biblioteca android.preference
dejó de estar disponible a partir de Android 10.
En su lugar, los desarrolladores deben usar la biblioteca de preferencia de AndroidX, que forma parte de Android.
Jetpack Para obtener recursos adicionales de ayuda en la migración y
desarrollo, consulta la versión actualizada de la Configuración
Guía junto con nuestra muestra pública
aplicación
y documentación de referencia.
Cambios en la biblioteca de utilidades de archivos ZIP
En Android 10, se introducen los siguientes cambios en las clases de la java.util.zip
que maneja archivos ZIP. Estos cambios hacen que el comportamiento de la biblioteca sea más
coherente entre Android y otras plataformas que usan java.util.zip
.
Inflater
En versiones anteriores, algunos métodos de la clase Inflater
arrojaban una IllegalStateException
si se invocaban después de una llamada a end()
.
En Android 10, estos métodos muestran una
NullPointerException
en su lugar.
ZipFile
En Android 10 y versiones posteriores, el constructor para
ZipFile
que tome argumentos de tipo File
, int
, y Charset
no arroje una
ZipException
si el archivo ZIP proporcionado
no contiene ningún archivo.
ZipOutputStream
En Android 10 y versiones posteriores, la
método finish()
en
ZipOutputStream
no arroja un
ZipException
si intenta escribir un
de salida para un archivo ZIP que no contiene ningún archivo.
Cambios en la cámara
Muchas apps que usan la cámara suponen que, si el dispositivo está configurado en modo vertical, entonces el dispositivo físico también se encuentra en orientación vertical, como se describe en Orientación de la cámara. Esta suposición solía ser cierta, pero con la expansión de los factores de forma disponibles, como los dispositivos plegables, ya no se aplica, Que en estos dispositivos puede llevar a una rotación o escala incorrectas (o ambas) del visor de la cámara.
Las aplicaciones orientadas al nivel de API 24 o a uno superior deben establecer explícitamente
android:resizeableActivity
y proporcionar la funcionalidad necesaria para procesar
una operación multiventana.
Seguimiento del uso de batería
A partir de Android 10,
Se restablece SystemHealthManager
las estadísticas de uso de la batería cuando el dispositivo se desconecta después de una
evento de carga. En términos generales, un evento de carga importante
es el siguiente: el dispositivo
se cargó completamente o el dispositivo pasó de estar casi agotado a
que se hayan cargado correctamente.
En versiones anteriores a Android 10, las estadísticas de uso de batería se restablecían cada vez que el dispositivo se sin estar enchufada, por muy poco cambio en el nivel de la batería.
Baja de Android Beam
En Android 10, dejará de estar disponible Android Beam oficialmente, una antigua función para iniciar el uso compartido de datos entre dispositivos por medio de la Comunicación de campo cercano (NFC). También daremos de baja varias de las APIs de NFC relacionadas. Android Beam seguirá disponible de manera opcional para los socios fabricantes que quieran usarla, pero no se seguirá desarrollando. Sin embargo, Android aún admitirá otras API y capacidades de NFC, y los casos de uso como la lectura de etiquetas y pagos seguirán funcionando como se espera.
Cambio de comportamiento de java.math.BigDecimal.stripTrailingZeros()
BigDecimal.stripTrailingZeros()
ya no conserva los ceros finales como un
caso especial si el valor de entrada es cero.
Cambios en el comportamiento de java.util.regex.Matcher y patrón
Se cambió el resultado de split()
para que ya no comience con una String
vacía ("") cuando hay una coincidencia de ancho cero al comienzo de la entrada. Esto también afecta a String.split()
. Por ejemplo, "x".split("")
ahora muestra {"x"}
.
mientras que solía mostrar {"", "x"}
en versiones anteriores de Android.
"aardvark".split("(?=a)"
ahora muestra {"a", "ardv", "ark"}
en lugar de
{"", "a", "ardv", "ark"}
También se mejoró el comportamiento de excepción para argumentos no válidos:
- Ahora
appendReplacement(StringBuffer, String)
lanza unIllegalArgumentException
en lugar deIndexOutOfBoundsException
siString
de reemplazo termina con una sola barra inversa, lo cual es ilegal. El ahora se arroja la misma excepción si elString
de reemplazo termina con$
. Anteriormente, no se mostraba ninguna excepción en esta situación. replaceFirst(null)
ya no llama areset()
enMatcher
si arroja unNullPointerException
Ahora también se arrojaNullPointerException
cuando hay no hay coincidencia. Anteriormente, se lanzaba solo cuando había una coincidencia.start(int group)
,end(int group)
ygroup(int group)
ahora arrojan un másIndexOutOfBoundsException
general si el índice de grupo está fuera de los límites. Anteriormente, estos métodos arrojabanArrayIndexOutOfBoundsException
.
El ángulo predeterminado para GradientDrawable ahora es TOP_BOTTOM.
En Android 10, si defines una
GradientDrawable
en XML y no proporcionan una medición de ángulo, la orientación del gradiente
la configuración predeterminada es
TOP_BOTTOM
Este es un cambio con respecto a las versiones anteriores de Android, en las que el valor predeterminado era LEFT_RIGHT
.
Como solución alternativa, si actualizas a la versión más reciente de AAPT2, haz lo siguiente: la herramienta establece una medición de ángulo de 0 para apps heredadas si no hay un ángulo se especifica la medición.
Registro de objetos serializados con el SUID predeterminado
A partir de Android 7.0 (nivel de API 24), la plataforma realizó una corrección en el serialVersionUID
predeterminado para objetos serializables. Esta corrección
no afectó a las apps orientadas al nivel de API 23 o anterior.
A partir de Android 10, si una app tiene como objetivo el nivel de API 23 o versiones anteriores
y se basa en el serialVersionUID
antiguo, incorrecto y predeterminado de los registros del sistema
enviar una advertencia y sugerir
una corrección de código.
Específicamente, el sistema registra una advertencia si se cumplen todas las siguientes condiciones:
- La app tiene como objetivo el nivel de API 23 o uno anterior.
- Se serializa una clase.
- La clase serializada usa el
serialVersionUID
predeterminado, en lugar de configurar unserialVersionUID
de forma explícita. - El
serialVersionUID
predeterminado es diferente delserialVersionUID
si la app tuviera como objetivo el nivel de API 24 o uno superior.
Esta advertencia se registra una vez por cada clase afectada.
El mensaje de advertencia incluye una solución sugerida, que es configurar de forma explícita serialVersionUID
en el valor predeterminado que se calcularía si la app se orientara al nivel de API 24 o uno superior. Con esa corrección, puedes asegurarte de que
si un objeto de esa clase se serializa en una app que se orienta al nivel de API
23 o versiones anteriores, las apps que se orientan a 24 o versiones posteriores leerán correctamente el objeto.
y viceversa.
Cambios en java.io.FileChannel.map()
A partir de Android 10, FileChannel.map()
no es compatible con
archivos no estándares, como /dev/zero
, cuyo tamaño no se puede cambiar usando
truncate()
Anteriores
las versiones de Android se tragaron el errno
truncate()
, pero Android 10 arroja una IOException. Si necesitas el comportamiento anterior,
debes usar código nativo.