Además de las funciones y capacidades nuevas, Android 8.0 (nivel de API 26) incluye varios cambios de comportamiento del sistema y de la API. Este documento se destacan algunos de los cambios clave que debe comprender y tener en cuenta. en tus apps.
La mayoría de estos cambios afectan a todas las apps, independientemente de la versión de Android al que se orientan. Sin embargo, varios cambios solo afectan la segmentación de apps Android 8.0 Para maximizar la claridad, este La página se divide en dos secciones: Cambios para todas las aplicaciones y Cambios en la segmentación de aplicaciones. Android 8.0
Cambios para todas las apps
Estos cambios de comportamiento se aplican a
Background execution limits
Uno de los cambios que introduce Android 8.0 (nivel de API 26) en mejorar la duración de la batería, cuando tu aplicación ingresa almacenado en caché sin activar componentes, el sistema libera los bloqueos de activación que contiene la app.
Además, para mejorar el rendimiento del dispositivo, el sistema limita ciertos de las apps que no se ejecutan en primer plano. Más precisamente:
- Las apps que se ejecutan en segundo plano ahora tienen límites sobre la libertad de estos pueden acceder a servicios en segundo plano.
- Las apps no pueden usar sus manifiestos para registrarse en la mayoría de las transmisiones implícitas (es decir, transmisiones que no están orientadas específicamente a la app).
De forma predeterminada, estas restricciones se aplican únicamente a apps orientadas a Android O. Sin embargo, Los usuarios pueden habilitar estas restricciones para cualquier app desde la pantalla Configuración. incluso si la aplicación no se orientó a O.
Android 8.0 (nivel de API 26) también incluye los siguientes cambios en métodos específicos:
- El método
startService()
ahora arroja unIllegalStateException
si se trata de una app la orientación a Android 8.0 intenta usar ese método en una situación en la que no se permite crear servicios en segundo plano. - El nuevo método
Context.startForegroundService()
inicia un servicio en primer plano. El sistema permite que las apps llamar aContext.startForegroundService()
incluso cuando la app está en segundo plano. Sin embargo, la app debe llamar al métodostartForeground()
de ese servicio en un plazo de cinco segundos después de que se crea el servicio.
Para obtener más información, consulta Límites de ejecución en segundo plano.
Limites de ubicación en segundo plano de Android
Para preservar la batería, la experiencia del usuario y el estado del sistema las aplicaciones en segundo plano reciben actualizaciones de ubicación con menos frecuencia cuando se usan en un dispositivo con Android 8.0. Este cambio de comportamiento afecta a todas las apps que reciben actualizaciones de ubicación, incluidos los Servicios de Google Play.
Estos cambios afectan las siguientes API:
- Proveedor de ubicación combinada (FLP)
- Geovallado
- GNSS Measurements
- Location Manager
- Administrador de Wi-Fi
Para asegurarte de que tu app se ejecute de la forma prevista, completa los siguientes pasos:
- Revisa la lógica de tu app y asegúrate de usar la ubicación más reciente APIs
- Prueba que tu app muestre el comportamiento que esperas para cada uso para determinar si este es el caso.
- Considera usar Fusionados Location Provider (FLP) o geovallado para manejar los casos de uso que dependen de la ubicación actual del usuario.
Para obtener más información sobre estos cambios, consulta Ubicación en segundo plano Límites.
Accesos directos a aplicaciones
Android 8.0 (nivel de API 26) incluye los siguientes cambios en los accesos directos a aplicaciones:
- El número de la transmisión de
com.android.launcher.action.INSTALL_SHORTCUT
ya no tiene ningún efecto en tu app, porque ahora es una política transmisión. En su lugar, debes crear un acceso directo a la app con elrequestPinShortcut()
de la claseShortcutManager
. - El
ACTION_CREATE_SHORTCUT
intent ahora puede crear accesos directos a aplicaciones que administres con la ClaseShortcutManager
. Este intent también puede crear accesos directos de selector heredados que no interactúanShortcutManager
Anteriormente, este intent podía solo pueden crear atajos de selector heredados. - Accesos directos creados con
requestPinShortcut()
y accesos directos creados en una actividad que controla lasACTION_CREATE_SHORTCUT
ahora son accesos directos completos a aplicaciones. Como resultado, las apps ahora pueden actualizarlas con los métodos deShortcutManager
. - Los accesos directos heredados conservan la funcionalidad de las versiones anteriores de Android, pero debes convertirlos manualmente en accesos directos a aplicaciones en tu app.
Para obtener más información sobre los cambios en los accesos directos a aplicaciones, consulta la Fijación de atajos y Widgets.
Configuración regional e internacionalización
Android 7.0 (nivel de API 24) introdujo el concepto de poder
especificar una configuración regional de categoría predeterminada, pero algunas APIs siguieron usando la
Locale.getDefault()
genérico
sin argumentos, cuando debería haber usado la configuración regional predeterminada de la categoría DISPLAY
. En Android 8.0 (nivel de API 26), la
Los siguientes métodos ahora usan Locale.getDefault(Category.DISPLAY)
en lugar de Locale.getDefault()
:
Locale.getDisplayScript(Locale)
también
vuelve a ser Locale.getDefault()
cuando la
Se especificó un valor displayScript para el Locale
no está disponible.
Los cambios adicionales relacionados con la configuración regional y la internacionalización son los siguientes: sigue:
- Llamar a
Currency.getDisplayName(null)
arroja unaNullPointerException
. coinciden con el comportamiento documentado. - El análisis nombres de zonas horarias ha cambiado. Anteriormente,
Los dispositivos Android usaron el valor del reloj del sistema que se mostró al iniciar el dispositivo
tiempo para almacenar en caché los nombres de zona horaria usados para analizar la fecha
veces. Como resultado, el análisis podría verse afectado negativamente si el sistema
era incorrecto al momento del inicio o en otros casos menos frecuentes.
En casos comunes, la lógica de análisis usa ICU y el el valor actual del reloj del sistema cuando se analizan los nombres de zonas horarias. Esta cambio proporciona resultados más correctos, que pueden diferir de los anteriores versiones de Android cuando tu app usa clases como
SimpleDateFormat
- Android 8.0 (nivel de API 26) actualiza la versión de ICU a la versión 58.
Ventanas de alerta
Si una app usa SYSTEM_ALERT_WINDOW
permiso y usa uno de los siguientes tipos de ventanas para intentar mostrar
ventanas de alerta sobre otras aplicaciones y ventanas del sistema:
...estas ventanas siempre aparecen debajo de las que utilizan la
TYPE_APPLICATION_OVERLAY
ventana
el tipo de letra. Si una app tiene como objetivo Android 8.0 (nivel de API 26), la app usa el
TYPE_APPLICATION_OVERLAY
tipo de ventana para mostrar ventanas de alerta.
Para obtener más información, consulta el artículo Tipos comunes de ventanas para la sección de ventanas de alerta en los cambios de comportamiento de Apps orientadas a Android 8.0.
Entrada y navegación
Con la llegada de las apps para Android en ChromeOS y otros factores de forma grandes, como en las tabletas, estamos viendo un resurgimiento del uso de la navegación con teclado Apps para Android. En Android 8.0 (nivel de API 26), volvimos a abordar mediante el teclado como dispositivo de entrada de navegación, lo que da como resultado una más predecible para la navegación basada en flechas y pestañas.
En particular, hicimos los siguientes cambios en el enfoque del elemento. comportamiento:
-
Si no definiste ningún color de estado de enfoque para un Objeto
View
(en primer o segundo plano) drawable), el framework ahora establece un color predeterminado para destacar el foco para elView
Este enfoque destacado es un elemento de diseño de ondas según el tema de la actividad.Si no quieres que un objeto
View
use este valor destacar cuando recibe el foco, establece el Atributoandroid:defaultFocusHighlightEnabled
parafalse
en el archivo en formato XML de diseño que contiene el elementoView
o pasafalse
asetDefaultFocusHighlightEnabled()
en la lógica de la IU de tu app. - Para probar cómo la entrada del teclado afecta el enfoque del elemento de la IU, puedes habilitar la Dibujo > Opción para desarrolladores Mostrar límites de diseño En Android 8.0, esta opción muestra una "X" sobre el elemento que actualmente tiene no te enfocas en eso.
Además, todos los elementos de la barra de herramientas en Android 8.0 se vuelven automáticamente clústeres de navegación con teclado, lo que facilita a los usuarios la navegación dentro y fuera de cada barra de herramientas como una completo.
Para obtener más información sobre cómo mejorar la compatibilidad con la navegación con el teclado en para tu app, lee el artículo Asistencia Guía de navegación con el teclado.
Autocompletado de formularios web
Ahora que la función Autocompletar de Android
Framework brinda compatibilidad integrada con la función Autocompletar, el
Los siguientes métodos relacionados con objetos WebView
cambiaron
Para las apps instaladas en dispositivos con Android 8.0 (nivel de API 26):
WebSettings
-
- El
getSaveFormData()
ahora muestrafalse
. Anteriormente, este método mostrabatrue
en su lugar. - Llamando
setSaveFormData()
rechazaron la invitación ya no tiene ningún efecto.
- El
WebViewDatabase
-
- Llamando
clearFormData()
rechazaron la invitación ya no tiene ningún efecto. - El
Método
hasFormData()
ahora muestrafalse
. Anteriormente, este método mostrabatrue
cuando el formulario contenía datos.
- Llamando
Accesibilidad
Android 8.0 (nivel de API 26) incluye los siguientes cambios en la accesibilidad:
-
El framework de accesibilidad ahora convierte todos los gestos que presionan dos veces en
ACTION_CLICK
acciones. Este cambio permite que TalkBack se comporte como otros servicios de accesibilidad.Si los objetos
View
de tu app usan un toque personalizado debes verificar que sigan funcionando con TalkBack. Quizás Solo debes registrar el controlador de clics que tuView
usan los objetos. Si TalkBack aún no reconoce los gestos que se realizan en estos dispositivosView
objetos, anularperformAccessibilityAction()
- Los servicios de accesibilidad ahora conocen
ClickableSpan
instancias en la APITextView
.
Para obtener más información sobre cómo mejorar la accesibilidad de tu app, consulta Accesibilidad.
Conectividad de red y HTTP(S)
Android 8.0 (nivel de API 26) incluye los siguientes cambios de comportamiento en la red y la conectividad HTTP(S):
- Las solicitudes de OPTIONS sin cuerpo tienen un
Content-Length: 0
encabezado. Antes no tenían un encabezadoContent-Length
. - HttpURLConnection normaliza las URLs que contienen rutas de acceso vacías agregando un anexo.
después del nombre del host o la autoridad. Por ejemplo,
convierte
http://example.com
enhttp://example.com/
- Un selector de proxy personalizado configurado a través de ProxySelector.setDefault() solo se orienta a la dirección (esquema, host y puerto) de una URL solicitada. Como resultado, es posible que la selección se proxy se base únicamente en estos valores. Una URL pasan a un selector de proxy personalizado no incluye la URL solicitada ruta de acceso, parámetros de consulta o fragmentos.
- Los URI no pueden contener etiquetas.
Anteriormente, la plataforma admitía una solución alternativa para aceptar etiquetas vacías en de host, lo que constituye un uso ilegal de los URIs. Esta solución alternativa era para compatibilidad con versiones anteriores de libcore. Desarrolladores que usan la API vería incorrectamente un mensaje de ADB: "URI example..com has empty labels in el nombre de host. El formato es incorrecto y no se aceptará en versiones futuras de Android versiones nuevas". En Android 8.0, se quita esta solución alternativa. el sistema devuelve null para URI con formato incorrecto.
- Implementación de HttpsURLConnection en Android 8.0 no realiza un resguardo de versiones no seguro del protocolo TLS/SSL.
- El control de tunelización de conexiones HTTP(S) cambió de la siguiente manera:
- Cuando se tuneliza la conexión HTTPS, el sistema ubica correctamente el número de puerto (:443) en la línea del host cuando se envía esta información a un servidor intermedio. Anteriormente, el puerto solo se produjo en la línea CONNECT.
- El sistema ya no envía autorizaciones de usuario-agente ni de proxy
de una solicitud tunelizada al servidor proxy.
El sistema ya no envía un encabezado de autorización de proxy en un una Http(s)URLConnection tunelizada al proxy cuando se configura la por túnel. En lugar de eso, el sistema genera un encabezado de autorización de proxy y lo envía al proxy cuando este envía HTTP 407 en respuesta a la solicitud inicial.
Del mismo modo, el sistema ya no copia el encabezado del usuario-agente desde la solicitud tunelizada hasta la solicitud del proxy que configura la por túnel. En cambio, la biblioteca genera un encabezado de usuario-agente para ese para cada solicitud.
- El
send(java.net.DatagramPacket)
genera una SocketException si el método connect() ejecutado anteriormente falló el método.- DatagramSocket.connect() establece una pendingSocketException si hay una. error interno. Antes de Android 8.0, se puede usar una función recv() llamada arrojaba una SocketException aunque una llamada send() se realizara con éxito. Para lograr uniformidad, ambas llamadas ahora producen una SocketException.
- InetAddress.isReachable() prueba el ICMP antes de volver al eco TCP
protocolo.
- Algunos hosts que bloquean el puerto 7 (TCP Echo), como google.com, pueden ahora son accesibles si aceptan el protocolo Echo ICMP.
- Para los hosts inaccesibles, este cambio significa que el doble de la cantidad tiempo se invierte antes de que regrese la llamada.
Bluetooth
Android 8.0 (nivel de API 26) realiza los siguientes cambios en la longitud de
los datos que ScanRecord.getBytes()
obtiene lo siguiente:
- El método
getBytes()
no hace suposiciones la cantidad de bytes recibidos. Por lo tanto, las apps no deben depender de ningún la cantidad mínima o máxima de bytes que se muestran. En cambio, deben evaluar la longitud del array resultante. - Los dispositivos compatibles con Bluetooth 5 pueden mostrar una longitud de datos superior al con un máximo previo de ~60 bytes.
- Si un dispositivo remoto no proporciona una respuesta de análisis, debe tener menos de 60 bytes. se pueden devolver.
Conectividad sin inconvenientes
Android 8.0 (nivel de API 26) incorpora una serie de mejoras en la configuración de Wi-Fi para que sea más fácil elegir la red Wi-Fi que ofrece la mejor experiencia del usuario. Entre los cambios específicos se incluye lo siguiente:
- Mejoras en la estabilidad y la confiabilidad.
- Una IU de lectura más intuitiva.
- Un menú consolidado y único de preferencias de Wi-Fi.
- En dispositivos compatibles, activación automática de la conexión Wi-Fi cuando se guarda una red de alta calidad está cerca.
Seguridad
Android 8.0 incluye las siguientes funciones de seguridad cambios:
- La plataforma ya no es compatible con SSLv3.
- Cuando se establece una conexión HTTPS a un servidor que incorrectamente
implementa la negociación de versiones del protocolo TLS,
HttpsURLConnection
ya no prueba la solución alternativa. de recurrir a versiones anteriores del protocolo TLS y reintentar. - Android 8.0 (nivel de API 26) aplica un Secure Computing (SECCOMP) filtrar a todas las aplicaciones. La lista de llamadas de sistema permitidas se limita a aquellas expuestos por medio de biónico. Aunque se proporcionan otras llamadas de sistema para la retrocompatibilidad, no recomendamos su uso.
- Los objetos
WebView
de tu app ahora se ejecutan en multiprocesos. . El contenido web se maneja en un proceso independiente y aislado del que contiene el proceso de la app para mejorar la seguridad. -
Ya no puedes suponer que los APKs residen en directorios cuyos nombres terminan
en -1 o -2. Las apps deben usar
sourceDir
para obtener de directorio y no depender directamente del formato de directorio. - Para obtener información sobre las mejoras de seguridad relacionadas con el uso de anuncios consulta Bibliotecas nativas.
Además, Android 8.0 (nivel de API 26) introduce los siguientes cambios relacionados con la instalación Apps desconocidas de fuentes desconocidas:
- El valor de la configuración heredada
Ahora
INSTALL_NON_MARKET_APPS
es siempre 1. Para determinar si una fuente desconocida puede instalar apps usando el instalador de paquetes, en su lugar, debes usar el valor de retorno decanRequestPackageInstalls()
- Si intentas cambiar el valor de
INSTALL_NON_MARKET_APPS
que usansetSecureSetting()
, unUnsupportedOperationException
cuando se arroja. Impedir que los usuarios instalen apps desconocidas mediante métodos desconocidos fuentes, debes aplicar el Usuario deDISALLOW_INSTALL_UNKNOWN_SOURCES
restricción. -
Los perfiles administrados creados en dispositivos con Android 8.0 (nivel de API 26) automáticamente tienen la
Usuario de
DISALLOW_INSTALL_UNKNOWN_SOURCES
restricción habilitada. Para los perfiles administrados existentes en dispositivos que se actualizados a Android 8.0, el Usuario deDISALLOW_INSTALL_UNKNOWN_SOURCES
restricción se habilita automáticamente, a menos que el propietario del perfil explícitamente inhabilitó esta restricción (antes de la actualización) estableciendoINSTALL_NON_MARKET_APPS
a 1.
Para obtener más detalles sobre cómo instalar aplicaciones desconocidas, consulta la App desconocida Permisos de instalación.
Para obtener lineamientos adicionales sobre cómo hacer que tu app sea más segura, consulta Seguridad para desarrolladores de Android.
Privacidad
Android 8.0 (nivel de API 26) hace que los siguientes elementos relacionados con la privacidad cambios en la plataforma.
- Ahora, la plataforma maneja los identificadores de manera diferente.
-
Para las apps que se instalaron antes de una actualización inalámbrica a una versión de
Android 8.0 (nivel de API 26)
(nivel de API 26), el valor de
ANDROID_ID
sigue siendo el mismo a menos que se desinstale y vuelva a instalar después de la actualización inalámbrica. Para preservar los valores en desinstalaciones después de la actualización inalámbrica, los desarrolladores pueden asociar los valores antiguos y nuevos usando Copia de seguridad de clave-valor. - En el caso de las apps instaladas en un dispositivo con Android 8.0, el valor de
Ahora el alcance de
ANDROID_ID
por clave de firma de la app y por usuario. El valor deANDROID_ID
es único para cada combinación de clave de firma de la app, usuario y dispositivo. Como resultado, las apps con diferentes claves de firma se ejecutan en el mismo dispositivo dejan de ver el mismo ID de Android (incluso para el mismo usuario). - El valor de
ANDROID_ID
no cambia cuando se desinstala o reinstala el paquete, siempre y cuando clave de firma es la misma (y la app no se instaló antes de una OTA a un versión de Android 8.0). - El valor de
ANDROID_ID
no cambia incluso si una actualización del sistema hace que la clave de firma del paquete cambie. - En los dispositivos que se envían con el ID de publicidad y los Servicios de Google Play,
debes usar
ID de publicidad. Un sistema simple y estándar
para monetizar apps
El ID de publicidad es un ID único que el usuario puede restablecer para publicidad. Se proporciona
de los Servicios de Google Play.
Otros fabricantes de dispositivos deben continuar para proporcionar
ANDROID_ID
.
-
Para las apps que se instalaron antes de una actualización inalámbrica a una versión de
Android 8.0 (nivel de API 26)
(nivel de API 26), el valor de
- La consulta de la propiedad del sistema
net.hostname
da como resultado un valor nulo. resultado.
Registro de excepciones no capturadas
Si una app instala un Thread.UncaughtExceptionHandler
no llamar a la Thread.UncaughtExceptionHandler
predeterminada,
el sistema
No cierren la app cuando se produzca una excepción no detectada. A partir de
Android 8.0 (nivel de API 26), el sistema registra el seguimiento de pila de la excepción en este
actual; en versiones anteriores de la plataforma, el sistema no tendría
registró el seguimiento de pila de la excepción.
Recomendamos usar Thread.UncaughtExceptionHandler
implementaciones siempre llaman a
el controlador predeterminado; las apps que siguen esta recomendación no se ven afectadas
el cambio en Android 8.0.
Cambio de firma de findViewById()
Todas las instancias del método findViewById()
ahora devuelven
<T extends View> T
en lugar de View
. Este cambio
tiene las siguientes implicaciones:
- Esto puede provocar que el código existente ahora tenga un tipo de datos ambiguo que se muestra.
por ejemplo, si hay
someMethod(View)
ysomeMethod(TextView)
que lleva el resultado de una llamada afindViewById()
- Cuando se usa el lenguaje de origen Java 8, se requiere una conversión explícita para
View
cuando el tipo de datos que se muestra no tiene restricciones (por ejemplo,assertNotNull(findViewById(...)).someViewMethod())
- Anulaciones de métodos
findViewById()
no finales (para por ejemplo,Activity.findViewById()
) necesitarán la devolución tipo actualizado.
Cambio en las estadísticas del uso de proveedores de contactos
En versiones anteriores de Android, el componente Proveedor de contactos
permite a los desarrolladores obtener datos de uso de cada contacto. Estos datos de uso
muestra información para cada dirección de correo electrónico y cada número de teléfono asociado
con un contacto, incluida la cantidad de veces que se contactó a él
y la última vez que se contactó al contacto. Las aplicaciones que solicitan el
READ_CONTACTS
puede leer estos datos.
Las apps pueden leer estos datos si lo solicitan
READ_CONTACTS
permiso. En Android 8.0 (nivel de API 26) y versiones posteriores, las consultas de datos de uso devuelven
aproximaciones en lugar de valores exactos. El sistema Android mantiene la
exactos de forma interna, por lo que este cambio no afecta
la API de autocompletar.
Este cambio de comportamiento afecta los siguientes parámetros de consulta:
Manejo de recopilaciones
AbstractCollection.removeAll()
y AbstractCollection.retainAll()
.
ahora arroja siempre una NullPointerException
; anteriormente, el
No se arrojó NullPointerException
cuando se recolectó la información.
vacío. Este cambio hace que el comportamiento se adecue a la documentación.
Android para empresas
Android 8.0 (nivel de API 26) cambia la comportamiento de algunas APIs y funciones para apps empresariales, lo que incluye la administración y controladores de políticas (DPC). Entre los cambios se incluye lo siguiente:
- Nuevos comportamientos que permiten la compatibilidad de las apps con perfiles de trabajo en dispositivos completamente administrados.
- Cambios en el manejo de actualizaciones del sistema, la verificación de apps y la autenticación en aumentar la integridad del dispositivo y del sistema.
- Mejoras en la experiencia del usuario en lo que respecta al aprovisionamiento, las notificaciones, Pantalla Recientes y VPN siempre activada
Para ver todos los cambios empresariales en Android 8.0 (nivel de API 26) y descubrir cómo podrían afectan tu aplicación, consulta Android en la empresa.
Apps orientadas a Android 8.0
Estos cambios de comportamiento se aplican exclusivamente a las apps para las que se segmentan
Android 8.0 (nivel de API 26) o una versión posterior Apps que se compilan con Android 8.0,
o configura targetSdkVersion
en Android 8.0 o una versión posterior
sus apps para admitir estos comportamientos correctamente, cuando corresponda.
Ventanas de alerta
Las apps que usan SYSTEM_ALERT_WINDOW
el permiso ya no puede usar los siguientes tipos de ventanas para mostrar ventanas de alerta
arriba de otras aplicaciones y ventanas del sistema:
En cambio, las apps deben usar un nuevo tipo de ventana llamado
TYPE_APPLICATION_OVERLAY
Cuando uses
TYPE_APPLICATION_OVERLAY
ventana
escribe para mostrar ventanas de alerta de tu app, mantén las siguientes características
del nuevo tipo de ventana en mente:
- Las ventanas de alerta de una app siempre aparecen en ventanas críticas del sistema, como la barra de estado y los IME.
- El sistema puede mover o cambiar el tamaño de las ventanas que usan el
TYPE_APPLICATION_OVERLAY
tipo de ventana para mejorar la presentación de la pantalla. - Al abrir el panel de notificaciones, los usuarios pueden acceder a la configuración para bloquear un
muestre ventanas de alerta que se muestran con el botón
TYPE_APPLICATION_OVERLAY
tipo de ventana.
Notificaciones de cambios de contenido
Android 8.0 (nivel de API 26) cambia la forma
ContentResolver.notifyChange()
y registerContentObserver(Uri, boolean, ContentObserver)
.
en las apps orientadas a Android 8.0.
Estas APIs ahora requieren un ContentProvider
válido
se define para la autoridad en todos los URI. Definir un ContentProvider
válido con los permisos relevantes
te ayudan a defender tu app contra cambios de contenido de apps maliciosas y evitan que
de filtrar datos potencialmente privados en apps maliciosas.
Enfoque de las vistas
Los objetos View
en los que se puede hacer clic ahora también pueden enfocarse en
de forma predeterminada. Si quieres que se pueda hacer clic en un objeto View
, pero no
enfocable, establece el
Atributo android:focusable
para false
en el diseño
Archivo en formato XML que contiene el View
o pasa false
a setFocusable()
en la IU de tu app
lógica.
Coincidencia de usuario-agente en la detección del navegador
Android 8.0 (nivel de API 26) y las versiones posteriores incluyen la
la cadena de identificador de compilación OPR
. Algunas coincidencias de patrones pueden
provocar que la lógica de detección del navegador identifique erróneamente un navegador que no es Opera.
Un ejemplo de una coincidencia de patrones podría ser el siguiente:
if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}
Para evitar problemas que surjan de una identificación errónea de este tipo, utiliza una cadena que no sea
OPR
como coincidencia de patrón para el navegador Opera
Seguridad
Los siguientes cambios afectan la seguridad en Android 8.0 (nivel de API 26):
- Si la configuración de seguridad de red de tu app
opciones
sin admitir el tráfico de texto simple, la capacidad
Los objetos
WebView
no pueden acceder a sitios web a través de HTTP. CadaWebView
debe usar HTTPS en su lugar. - Se quitó la configuración del sistema Permitir fuentes desconocidas. en su el permiso Instalar apps desconocidas administra las instalaciones de apps desconocidas de fuentes desconocidas. Para obtener más información sobre este nuevo permiso, consulta la App desconocida Permisos de instalación.
Para obtener lineamientos adicionales sobre cómo hacer que tu app sea más segura, consulta Seguridad para desarrolladores de Android.
Acceso y visibilidad para cuentas
En Android 8.0 (nivel de API 26), las apps ya no tienen acceso
a las cuentas de usuario, a menos que el autenticador sea el propietario de las cuentas o
otorga ese acceso. El
Permiso GET_ACCOUNTS
ya no es suficiente. Para obtener acceso a una cuenta, las apps deben
usa AccountManager.newChooseAccountIntent()
o un servicio de autenticación específico
. Después de obtener acceso a las cuentas, una app puede llamar
AccountManager.getAccounts()
para acceder a ellos.
Android 8.0 deja de estar disponible
LOGIN_ACCOUNTS_CHANGED_ACTION
Aplicaciones
debería usar
addOnAccountsUpdatedListener()
para obtener actualizaciones sobre las cuentas durante el tiempo de ejecución.
Para obtener información sobre las nuevas APIs y métodos agregados para acceder a la cuenta y visibilidad, consulte Acceso a la cuenta y Visibilidad en la sección Nuevas APIs de este documento.
Privacidad
Los siguientes cambios afectan la privacidad en Android 8.0 (nivel de API 26).
-
Las propiedades del sistema
net.dns1
,net.dns2
ynet.dns3
ynet.dns4
ya no son disponible, un cambio que mejora la privacidad en la plataforma. -
Para obtener información de redes, como servidores DNS, apps con
ACCESS_NETWORK_STATE
puedes registrar un objetoNetworkRequest
o ObjetoNetworkCallback
. Estas clases están disponibles en Android 5.0 (nivel de API 21) y versiones posteriores. -
Build.SERIAL es obsoleto.
En su lugar, las apps que necesitan conocer el número de serie del hardware deberían
usa el nuevo método
Build.getSerial()
, que requiere laREAD_PHONE_STATE
permiso. -
La API de
LauncherApps
ya no admite perfiles de trabajo para obtener información sobre el perfil principal. Cuando un usuario está en un trabajo la API deLauncherApps
se comporta como si no hubiera apps se instalan en otros perfiles dentro del mismo grupo de perfiles. Como antes, intentos de acceder a perfiles no relacionados causa SecurityExceptions.
Permisos
Antes de Android 8.0 (nivel de API 26), si una app solicitaba un permiso durante el tiempo de ejecución y se otorgó el permiso, el sistema también le otorgó a la app el resto de los permisos que pertenecían a la misma grupo de permisos y que se hayan registrado en el manifiesto.
En las apps orientadas a Android 8.0, este comportamiento se ha y cómo se corrige el problema. La app solo recibe los permisos que tiene explícitamente solicitado. Sin embargo, una vez que el usuario otorga un permiso a la app, las siguientes solicitudes de permisos en ese grupo de permisos otorgadas automáticamente.
Por ejemplo, supongamos que una app enumera READ_EXTERNAL_STORAGE
y
WRITE_EXTERNAL_STORAGE
en su manifiesto.
La app solicita READ_EXTERNAL_STORAGE
y
el usuario la otorga. Si la app tiene como objetivo un nivel de API 25 o inferior, el sistema también
otorga WRITE_EXTERNAL_STORAGE
con el mismo
porque pertenece al mismo grupo de permisos STORAGE
y también
registradas en el manifiesto. Si la app tiene como objetivo Android 8.0 (nivel de API 26), el sistema otorga
solo READ_EXTERNAL_STORAGE
en ese momento;
Sin embargo, si la app luego solicita WRITE_EXTERNAL_STORAGE
, el sistema inmediatamente
otorga ese privilegio sin preguntar al usuario.
Contenido multimedia
- El framework puede realizar
autosilenciado de fondo automático
por su cuenta. En este caso, cuando otra aplicación solicita el foco con
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
, la aplicación enfocado reduce su volumen, pero no suele recibir unonAudioFocusChange()
y no o perder el foco de audio. Hay nuevas APIs disponibles para anular este comportamiento en que necesitan pausarse en lugar de atenuar. - Cuando el usuario contesta una llamada telefónica, los flujos de contenido multimedia activos se silencian durante la llamada.
- Todas las APIs relacionadas con el audio deben usar
AudioAttributes
. en lugar de los tipos de transmisiones de audio para describir el caso de uso de reproducción de audio. Continúa usando los tipos de transmisión de audio únicamente para los controles de volumen. Aún se pueden usar otros tipos de transmisión (por ejemplo, el argumentostreamType
para la funciónAudioTrack
), pero el sistema lo registra como un error. - Cuando uses un
AudioTrack
, si la aplicación solicita un búfer de audio lo suficientemente grande, el intentará usar la salida del búfer profundo si está disponible. - En Android 8.0 (nivel de API 26), el control de los eventos de botones multimedia es diferente:
- Cómo administrar los botones multimedia no ha cambiado en una actividad de IU: las actividades en primer plano siguen teniendo prioridad en el control. eventos de botones multimedia.
- Si la actividad en primer plano no controla el evento del botón multimedia, el sistema enruta el evento. a la app que más recientemente reprodujo audio de forma local. El estado activo, las marcas y la reproducción no se consideran el estado de una sesión multimedia cuando se determina qué app recibe contenido multimedia. eventos de botones.
- Si se lanzó la sesión multimedia de la app,
el sistema envía el evento del botón multimedia al
MediaButtonReceiver
si tiene uno. - Para cualquier otro caso, el sistema descarta el evento de botón multimedia.
Bibliotecas nativas
En las apps orientadas a Android 8.0 (nivel de API 26), las bibliotecas nativas no una carga más larga si contienen algún segmento de carga que admita escritura y ejecutable. Es posible que algunas apps dejen de funcionar debido a este cambio si tienen bibliotecas nativas con segmentos de carga incorrectos. Este es un para reforzar la seguridad.
Para obtener más información, consulta Segmentos que admiten escritura y ejecución.
Los cambios de vinculadores están unidos al nivel de API que una app tiene como objetivo. Si es un cambio de vinculador nivel de API objetivo, la app no podrá cargar la biblioteca. Si orientas tus anuncios un nivel de API inferior al nivel de API en el que se produce el cambio de vinculador logcat muestra una advertencia.
Manejo de recopilaciones
En Android 8.0 (nivel de API 26),
Collections.sort()
se implementa el
superior de List.sort()
. La operación inversa
era verdadera en Android 7.x (niveles de API 24 y 25):
La implementación predeterminada de List.sort()
llamada Collections.sort()
.
Este cambio permite que Collections.sort()
para aprovechar la List.sort()
optimizada
implementaciones, pero tiene las siguientes restricciones:
Implementaciones de
List.sort()
no deben llamar aCollections.sort()
, porque esto provocaría un desbordamiento de pila debido a la recurrencia infinita. Si prefieres que el comportamiento predeterminado en tu implementación deList
, debes evitar anularsort()
Si una clase superior implementa
sort()
de forma inapropiada, es por lo general, es correcto anularList.sort()
con una implementación basada enList.toArray()
,Arrays.sort()
yListIterator.set()
Por ejemplo:@Override public void sort(Comparator<? super E> c) { Object[] elements = toArray(); Arrays.sort(elements, c); ListIterator<E> iterator = (ListIterator<Object>) listIterator(); for (Object element : elements) { iterator.next(); iterator.set((E) element); } }
En la mayoría de los casos, también puedes anular
List.sort()
con un una implementación que delega a diferentes implementaciones según el nivel de API. Por ejemplo:@Override public void sort(Comparator<? super E> comparator) { if (Build.VERSION.SDK_INT <= 25) { Collections.sort(this); } else { super.sort(comparator); } }
Si haces esto último solo porque quieres tener un
sort()
disponible en todos los niveles de API, considera asignarle un nombre único, comosortCompat()
, en lugar de anularsort()
-
Collections.sort()
ahora se registra como una modificación estructural en Enumera las implementaciones que llaman asort()
. Por ejemplo, en las versiones de la plataforma en versiones anteriores a Android 8.0 (nivel de API 26), iterando sobre unArrayList
y llamando asort()
en él a mitad de la iteración habría arrojado unaConcurrentModificationException
si la ordenación se hizo llamando aList.sort()
.Collections.sort()
no arrojó una excepción.Este cambio hace que el comportamiento de la plataforma sea más coherente: Ahora, el enfoque genera un
ConcurrentModificationException
.
Comportamiento de carga de clases
Android 8.0 (nivel de API 26) comprueba que los cargadores de clases no
romper las suposiciones del tiempo de ejecución cuando se cargan nuevas clases. Estas verificaciones son
si se hace referencia a la clase desde Java (desde
forName()
),
Dalvik bytecode, o JNI. La plataforma no intercepta llamadas directas de Java al
loadClass()
, ni se verifica
los resultados de esas llamadas. Este comportamiento no debería afectar el funcionamiento de las apps
de clase de clase.
La plataforma comprueba que el descriptor de la clase que muestra el cargador de clases
coincide con el descriptor esperado. Si el descriptor devuelto no coincide,
la plataforma arroja un error NoClassDefFoundError
y almacena en
un mensaje detallado en el que se indique la discrepancia.
La plataforma también comprueba que los descriptores de las clases solicitadas sean válidos. Esta
verifica las llamadas JNI que cargan indirectamente clases como GetFieldID()
,
y pasar descriptores no válidos a esas clases. Por ejemplo, un campo con firma
No se encontró java/lang/String
porque la firma no es válida.
debería ser Ljava/lang/String;
.
Es diferente de una llamada JNI a FindClass()
En el ejemplo anterior, java/lang/String
es un nombre válido completamente calificado.
Android 8.0 (nivel de API 26) no admite que varios cargadores de clases intenten definir clases.
con el mismo objeto DexFile. Si se intenta hacerlo, el tiempo de ejecución de Android arrojará una
InternalError
con el mensaje "Intento de registrar el archivo dex <filename>
con varios cargadores de clases”.
La API de DexFile dejó de estar disponible, y te recomendamos que la uses
uno de los cargadores de clases de la plataforma, incluido PathClassLoader
o
BaseDexClassLoader
, en su lugar.
Nota: Puedes crear varios cargadores de clases que hagan referencia al
mismo contenedor de archivos APK o JAR del sistema de archivos. Hacerlo normalmente no
generará mucha sobrecarga de memoria: si los archivos DEX en el contenedor se almacenan en lugar de
comprimidos, la plataforma puede realizar una operación mmap
sobre ellos en lugar de
los puedes extraer directamente. Sin embargo, si la plataforma debe extraer el archivo DEX del contenedor,
hacer referencia a un archivo DEX de esta manera puede consumir mucha memoria.
En Android, se considera que todos los cargadores de clases tienen capacidad paralela. Cuando varios subprocesos compiten para cargar la misma clase con la misma clase. loader, el primer subproceso en completar la operación gana, y el resultado se usa para los otros subprocesos. Este comportamiento ocurre independientemente de si el cargador de clases mostró la misma clase o una diferente, o bien arrojó una excepción. La plataforma ignora de forma automática esas excepciones.
Precaución: En las versiones de la plataforma anteriores a Android 8.0 (nivel de API 26), si se incumplen estas suposiciones, se puede definir el mismo varias veces, la corrupción del montón debido a la confusión de la clase y otros efectos no deseados.