Cambios de comportamiento en Android 8.0

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 todas las apps cuando ejecutar en la plataforma Android 8.0 (nivel de API 26), sin importar la nivel de API objetivo. Todos los desarrolladores deben revisar estos cambios y modificar las apps para admitirlos correctamente cuando corresponda a la app.

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 un IllegalStateException 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 a Context.startForegroundService() incluso cuando la app está en segundo plano. Sin embargo, la app debe llamar al método startForeground() 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 el requestPinShortcut() de la clase ShortcutManager.
  • El ACTION_CREATE_SHORTCUT intent ahora puede crear accesos directos a aplicaciones que administres con la Clase ShortcutManager. Este intent también puede crear accesos directos de selector heredados que no interactúan ShortcutManager 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 las ACTION_CREATE_SHORTCUT ahora son accesos directos completos a aplicaciones. Como resultado, las apps ahora pueden actualizarlas con los métodos de ShortcutManager.
  • 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 una NullPointerException. 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 el View 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 Atributo android:defaultFocusHighlightEnabled para false en el archivo en formato XML de diseño que contiene el elemento View o pasa false a setDefaultFocusHighlightEnabled() 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 muestra false. Anteriormente, este método mostraba true en su lugar.
  • Llamando setSaveFormData() rechazaron la invitación ya no tiene ningún efecto.
WebViewDatabase
  • Llamando clearFormData() rechazaron la invitación ya no tiene ningún efecto.
  • El Método hasFormData() ahora muestra false. Anteriormente, este método mostraba true cuando el formulario contenía datos.

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 tu View usan los objetos. Si TalkBack aún no reconoce los gestos que se realizan en estos dispositivos View objetos, anular performAccessibilityAction()

  • Los servicios de accesibilidad ahora conocen ClickableSpan instancias en la API TextView.

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 encabezado Content-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 en http://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:

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 de ANDROID_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.

  • 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) y someMethod(TextView) que lleva el resultado de una llamada a findViewById()
  • 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. Cada WebView 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 y net.dns3 y net.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 objeto NetworkRequest o Objeto NetworkCallback. 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 la READ_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 de LauncherApps 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 un onAudioFocusChange() 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 argumento streamType para la función AudioTrack), 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:
    1. 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.
    2. 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.
    3. 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.
    4. 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 a Collections.sort(), porque esto provocaría un desbordamiento de pila debido a la recurrencia infinita. Si prefieres que el comportamiento predeterminado en tu implementación de List, debes evitar anular sort()

    Si una clase superior implementa sort() de forma inapropiada, es por lo general, es correcto anular List.sort() con una implementación basada en List.toArray(), Arrays.sort() y ListIterator.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, como sortCompat(), en lugar de anular sort()

  • Collections.sort() ahora se registra como una modificación estructural en Enumera las implementaciones que llaman a sort(). Por ejemplo, en las versiones de la plataforma en versiones anteriores a Android 8.0 (nivel de API 26), iterando sobre un ArrayList y llamando a sort() en él a mitad de la iteración habría arrojado una ConcurrentModificationException si la ordenación se hizo llamando a List.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.