APIs de Android 4.0

Nivel de API: 14

Android 4.0 (ICE_CREAM_SANDWICH) es una versión importante de la plataforma que agrega una variedad de funciones nuevas para los usuarios y los desarrolladores de apps. Además de todas las nuevas funciones y APIs que se analizan a continuación, Android 4.0 es una función de la plataforma porque incorpora el amplio conjunto de APIs y temas holográficos de Android 3.x a pantallas más pequeñas. Como desarrollador de apps, ahora tienes una sola plataforma y un marco de API unificado que te permite desarrollar y publicar tu aplicación con un único APK que proporciona una experiencia del usuario optimizada para teléfonos celulares, tablets y más, cuando se ejecuta la misma versión de Android: Android 4.0 (nivel de API 14) o una versión posterior

Para los desarrolladores, la plataforma de Android 4.0 está disponible como un componente descargable del SDK de Android. La plataforma descargable incluye una biblioteca de Android y una imagen del sistema, así como un conjunto de máscaras de emulador y más. Para comenzar a desarrollar o probar con Android 4.0, usa SDK Manager de Android para descargar la plataforma en tu SDK.

Descripción general de la API

En las siguientes secciones, se proporciona una descripción general técnica de las nuevas APIs de Android 4.0.

APIs de redes sociales en el proveedor de contactos

Las APIs de contacto definidas por el proveedor ContactsContract se ampliaron para admitir nuevas funciones orientadas a las redes sociales, como un perfil personal para el propietario del dispositivo y la capacidad de que los usuarios inviten a contactos individuales a las redes sociales instaladas en el dispositivo.

Perfil de usuario

Android ahora incluye un perfil personal que representa al propietario del dispositivo, como se define en la tabla ContactsContract.Profile. Las apps de redes sociales que mantienen una identidad del usuario pueden contribuir a los datos de su perfil creando una nueva entrada ContactsContract.RawContacts dentro de ContactsContract.Profile. Es decir, los contactos sin procesar que representan al usuario del dispositivo no pertenecen a la tabla de contactos sin procesar tradicional que define el Uri ContactsContract.RawContacts. En su lugar, debes agregar un contacto sin procesar del perfil en la tabla de CONTENT_RAW_CONTACTS_URI. Luego, los contactos sin procesar de esta tabla se agregan al único perfil visible para el usuario etiquetado como "Yo".

Para agregar un contacto sin procesar nuevo para el perfil, se requiere el permiso android.Manifest.permission#WRITE_PROFILE. Del mismo modo, para leer de la tabla de perfiles, debes solicitar el permiso android.Manifest.permission#READ_PROFILE. Sin embargo, la mayoría de las apps no deberían necesitar leer el perfil del usuario, incluso cuando se agregan datos al perfil. Leer el perfil del usuario es un permiso sensible, y debes esperar que los usuarios sean escépticos con las apps que lo solicitan.

Intent de invitación

La acción de intent INVITE_CONTACT permite que una app para invocar una acción que indique que el usuario desea agregar un contacto a una red social. La app al recibir la aplicación, la utiliza para invitar al contacto especificado a esa red social. La mayoría de las apps estarán en el extremo receptor de esta operación. Por ejemplo, el la app de Personas integrada invoca el intent de invitación cuando el usuario selecciona "Agregar conexión" de una configuración que aparece en los detalles de contacto de una persona.

Para que tu app sea visible como en la lista "Agregar conexión", debe proporcionar un adaptador de sincronización para sincronizar la información de contacto de tu red social. Luego, debes indicar al sistema que tu app responde al intent INVITE_CONTACT Agregando el atributo inviteContactActivity al archivo de configuración de sincronización de tu app, con un nombre completamente calificado de la actividad que el sistema debe iniciar cuando envía el intent de invitación. La actividad que se inicia puede recuperar el URI del contacto en cuestión de los datos del intent y realizar el trabajo necesario para invitar a ese contacto a la red o agregar a la persona a las conexiones del usuario.

Fotos grandes

Android ahora admite fotos de alta resolución para los contactos. Ahora, cuando envías una foto a un registro de contacto, el sistema la procesa en una miniatura de 96 × 96 (como lo hacía anteriormente) y una “foto de visualización” de 256 × 256 que se almacena en una nueva tienda de fotos basada en archivos (las dimensiones exactas que elija el sistema pueden variar en el futuro). Puedes agregar una foto grande a un contacto colocando foto en la columna habitual PHOTO de un a la fila de datos, que el sistema procesará hasta crear la miniatura y la foto que se mostrarán correctamente registros.

Comentarios sobre el uso de Contactos

Las nuevas APIs de ContactsContract.DataUsageFeedback te permiten hacer un seguimiento la frecuencia con la que el usuario utiliza determinados métodos para ponerse en contacto con las personas, por ejemplo, qué tan seguido utiliza cada número de teléfono o dirección de correo electrónico. Esta información ayuda a mejorar la clasificación de cada contacto. método asociado a cada persona y ofrecer mejores sugerencias para ponerse en contacto con cada una de ellas.

Proveedor de calendario

Las nuevas APIs de Calendar te permiten leer, agregar, modificar y borrar calendarios, eventos, asistentes, recordatorios y alertas, que se almacenan en el Proveedor de calendario.

Varias apps y widgets pueden usar estas APIs para leer y modificar eventos del calendario. Sin embargo, algunos de los casos de uso más atractivos son los adaptadores de sincronización que sincronizan el calendario del usuario desde otros servicios de calendario con el proveedor de calendario, a fin de ofrecer una ubicación unificada para todos los de los eventos del usuario. Los eventos del Calendario de Google, por ejemplo, se sincronizan con el proveedor de calendario a través de el adaptador de sincronización del Calendario de Google, que permite ver estos eventos con la versión desde la app de Calendario.

CalendarContract define el modelo de datos para los calendarios y la información relacionada con eventos en el proveedor de calendarios. Todos los datos de calendario del usuario se almacenan Cantidad de tablas definidas por varias subclases de CalendarContract:

  • La tabla CalendarContract.Calendars contiene la información específica del calendario. Cada fila de esta tabla contiene los detalles de un solo calendario, como el nombre, el color, sincronizar información, etc.
  • La tabla CalendarContract.Events contiene información específica del evento. Cada fila de esta tabla incluye información de un solo evento, como el título del evento, la ubicación, la hora de inicio, la hora de finalización, etc. El evento puede ocurrir una sola vez o repetirse varias veces. Los asistentes, los recordatorios y las propiedades extendidas se almacenan en tablas independientes y usan el _ID del evento para vincularlos con él.
  • La tabla CalendarContract.Instances contiene la hora de inicio y finalización de las ocurrencias de un evento. Cada fila de esta tabla representa un solo caso. Para eventos únicos hay una asignación uno a uno de instancias a eventos. En el caso de los eventos recurrentes, se agregan varias filas que se genere automáticamente para que se correspondan con los casos múltiples de ese evento.
  • La tabla CalendarContract.Attendees contiene la información del asistente o invitado al evento. Cada fila representa un solo invitado a un evento. Especifica el tipo de huésped la persona y su respuesta al evento.
  • La tabla CalendarContract.Reminders contiene los datos de alerta/notificación. Cada fila representa una sola alerta para un evento. Un evento puede tener múltiples recordatorios. El número de los recordatorios por evento se especifican en MAX_REMINDERS, que establece el adaptador de sincronización que es propietario de ese calendario. Los recordatorios se especifican en la cantidad de minutos antes de que se programe el evento y se especifica un método de alarma, como usar una alerta, un correo electrónico o un SMS para recordarle al usuario.
  • La tabla CalendarContract.ExtendedProperties contiene campos de datos opacos que usa el adaptador de sincronización. El proveedor no realiza ninguna acción con los elementos de esta tabla, excepto borrar cuando se borran los eventos relacionados.

Para acceder a los datos del calendario de un usuario con el proveedor de Calendario, tu aplicación debe solicitar el permiso READ_CALENDAR (para el acceso de lectura) y WRITE_CALENDAR (para el acceso de escritura).

Intención del evento

Si solo quieres agregar un evento al calendario del usuario, puedes usar un intent ACTION_INSERT con los datos definidos por Events.CONTENT_URI para iniciar una actividad en la app de Calendario que cree eventos nuevos. El uso del intent no requiere ningún permiso, y puedes especificar los detalles del evento con los siguientes extras:

Proveedor de mensajes de voz

El nuevo proveedor de buzón de voz permite que las aplicaciones agreguen mensajes de voz al dispositivo para presentar todos los mensajes de voz del usuario en una sola presentación visual. Por ejemplo: es posible que un usuario tenga varias fuentes de buzón de voz, como uno del proveedor de servicios del teléfono y otros de VoIP u otra voz alternativa de Google Cloud. Estas apps pueden usar las APIs del proveedor de mensajes de voz para agregar sus mensajes de voz al dispositivo. Luego, la aplicación Teléfono integrada le presenta todos los mensajes de voz al usuario en una presentación unificada. Si bien la aplicación Teléfono del sistema es la única que puede leer todos los mensajes del buzón de voz, cada aplicación que proporciona mensajes de voz puede leer los que agregó al sistema (pero no puede leer mensajes de voz de otros servicios).

Debido a que, actualmente, las APIs no permiten que las apps de terceros lean todos los mensajes de voz del sistema, las únicas apps de terceros que deben usar las APIs de voz de correo son aquellas que tienen mensajes de voz para entregar al usuario.

La clase VoicemailContract define el proveedor de contenido para el Creador de mensajes de voz. Las subclases VoicemailContract.Voicemails y VoicemailContract.Status proporcionan tablas en las que las apps pueden insertar datos de buzón de voz para almacenarlos en el dispositivo. Para ver un ejemplo de una app de proveedor de buzón de voz, consulta la Proveedor de mensajes de voz Demostración.

Multimedia

Android 4.0 agrega varias APIs nuevas para aplicaciones que interactúan con contenido multimedia, como fotos, videos y música.

Efectos multimedia

Un nuevo framework de efectos multimedia te permite aplicar una variedad de efectos visuales a las imágenes y los videos. Por ejemplo, los efectos de imagen te permiten corregir fácilmente los ojos rojos, convertir una imagen a escala de grises, ajustar el brillo, ajustar la saturación, rotar una imagen, aplicar un efecto ojo de pez y mucho más. El sistema realiza todo el procesamiento de efectos en la GPU para obtener el máximo rendimiento.

Para obtener el máximo rendimiento, los efectos se aplican directamente a las texturas de OpenGL, por lo que tu aplicación debe tener un contexto de OpenGL válido antes de poder usar las APIs de efectos. Las texturas a las que aplicas los efectos pueden provenir de mapas de bits, videos o incluso la cámara. Sin embargo, existen ciertas restricciones texturas deben cumplir con lo siguiente:

  1. Se deben vincular a una imagen de textura GL_TEXTURE_2D.
  2. Deben contener al menos un nivel de mipmap.

Un objeto Effect define un único efecto multimedia al que te puedes aplicar un marco de imagen. El flujo de trabajo básico para crear un Effect es el siguiente:

  1. Llama a EffectContext.createWithCurrentGlContext() desde tu contexto de OpenGL ES 2.0.
  2. Usa el EffectContext que se muestra para llamar a EffectContext.getFactory(), que muestra una instancia de EffectFactory.
  3. Llama a createEffect() y pásale un nombre del efecto de @link android.media.effect.EffectFactory}, como EFFECT_FISHEYE o EFFECT_VIGNETTE.

Para ajustar los parámetros de un efecto, llama a setParameter() y pasa un nombre y un valor de parámetro. Cada tipo de efecto acepta parámetros diferentes, que se documentan con el nombre del efecto. Por ejemplo, EFFECT_FISHEYE tiene un parámetro para el scale de la distorsión.

Para aplicar un efecto en una textura, llama a apply() en la Effect y pasa la textura de entrada, el ancho y la altura, y el resultado. textura. La textura de entrada debe vincularse a una textura GL_TEXTURE_2D. imagen (por lo general, se hace llamando a glTexImage2D() función). Puedes proporcionar varios niveles de mipmap. Si la textura de salida no se vinculó a una imagen de textura, el efecto la vinculará automáticamente como GL_TEXTURE_2D y con un nivel de mipmap (0), que tendrá el mismo tamaño que la entrada.

Se garantiza la compatibilidad con todos los efectos enumerados en EffectFactory. Sin embargo, algunos efectos adicionales disponibles de las bibliotecas externas no son compatibles con todos los dispositivos. por lo que primero debes verificar si el efecto deseado de la biblioteca externa es compatible llamando isEffectSupported()

Cliente de control remoto

El nuevo RemoteControlClient permite que los reproductores multimedia habiliten la reproducción. controles de acceso desde clientes de control remoto, como la pantalla de bloqueo del dispositivo. Los reproductores multimedia también pueden exponer información sobre el contenido multimedia que se está reproduciendo actualmente para mostrar en el control remoto, como la pista y la imagen del álbum.

Para habilitar clientes de control remoto para tu reproductor multimedia, crea una instancia de RemoteControlClient con su constructor y pásale un PendingIntent que transmita ACTION_MEDIA_BUTTON. El intent también debe declarar el componente BroadcastReceiver explícito en tu app que controla el evento ACTION_MEDIA_BUTTON.

Para declarar las entradas de control multimedia que puede controlar el reproductor, debes llamar a setTransportControlFlags() en tu RemoteControlClient, que pasa un conjunto de marcas FLAG_KEY_MEDIA_*, como FLAG_KEY_MEDIA_PREVIOUS y FLAG_KEY_MEDIA_NEXT.

Luego, debes registrar tu RemoteControlClient pasándolo a MediaManager.registerRemoteControlClient(). Una vez registrado, el receptor de emisión que declaraste cuando creaste una instancia de RemoteControlClient recibirá ACTION_MEDIA_BUTTON eventos cuando se presiona un botón desde un control remoto. El intent que recibes incluye el KeyEvent de la tecla multimedia presionada, que puedes recuperar del intent con getParcelableExtra(Intent.EXTRA_KEY_EVENT).

Para mostrar información en el control remoto sobre el contenido multimedia que se está reproduciendo, llama a editMetaData() y agrega metadatos al RemoteControlClient.MetadataEditor que se muestra. Puedes proporcionar un mapa de bits para material gráfico multimedia, información numérica, como el tiempo transcurrido, e información de texto, como el título de la pista. Para Para obtener información sobre las claves disponibles, consulta las marcas METADATA_KEY_* en MediaMetadataRetriever.

Para ver una implementación de ejemplo, consulta Random Music Player, que proporciona una lógica de compatibilidad para habilitar el cliente de control remoto en dispositivos Android 4.0 y, al mismo tiempo, seguir admitiendo dispositivos hasta Android 2.1.

Reproductor multimedia

  • La transmisión de contenido multimedia en línea desde MediaPlayer ahora requiere el permiso INTERNET. Si usas MediaPlayer para Reproducir contenido de Internet, asegúrate de agregar INTERNET permiso en tu manifiesto; de lo contrario, la reproducción de contenido multimedia no funcionará a partir de Android 4.
  • setSurface() te permite definir un Surface para que se comporte como receptor de video.
  • setDataSource() te permite enviar encabezados HTTP adicionales con tu solicitud, lo que puede ser útil para la transmisión en vivo HTTP(S).
  • La transmisión en vivo HTTP(S) ahora respeta las cookies HTTP en todas las solicitudes

Tipos de medios

Android 4.0 agrega compatibilidad con lo siguiente:

  • Protocolo de transmisión en vivo HTTP/HTTPS, versión 3
  • Codificación de audio AAC sin procesar ADTS
  • Imágenes WEBP
  • Video Matroska

Para obtener más información, consulta Contenido multimedia compatible. Formatos

Cámara

La clase Camera ahora incluye APIs para detectar rostros y controlar las áreas de enfoque y medición.

Detección de rostro

Las apps de cámara ahora pueden mejorar sus capacidades con las APIs de detección de rostro de Android, que no Solo detectan el rostro de una persona, pero también rasgos faciales específicos, como los ojos y la boca.

Para detectar rostros en tu aplicación de cámara, debes registrar un Camera.FaceDetectionListener llamando a setFaceDetectionListener(). Luego, puedes iniciar la superficie de la cámara y comenzar a detectar rostros llamando a startFaceDetection().

Cuando el sistema detecta uno o más rostros en la escena de la cámara, llama a la devolución de llamada onFaceDetection() en tu implementación de Camera.FaceDetectionListener, incluido un array de objetos Camera.Face.

Una instancia de la clase Camera.Face proporciona información sobre lo siguiente: el rostro detectado, por ejemplo:

  • Un Rect que especifica los límites del rostro en relación con el campo de visión actual de la cámara
  • Un número entero entre 1 y 100 que indica la confianza del sistema en que el objeto es un rostro humano
  • Un ID único para que puedas hacer un seguimiento de varios rostros
  • Varios objetos Point que indican dónde se encuentran los ojos y la boca

Nota: Es posible que la detección de rostro no sea compatible con algunos dispositivos por lo que debes verificar llamando a getMaxNumDetectedFaces() y asegurarte de que es mayor que cero. Además, es posible que algunos dispositivos no admitan la identificación de los ojos y la boca, en cuyo caso, esos campos en el objeto Camera.Face serán nulos.

Áreas de enfoque y medición

Las apps de cámara ahora pueden controlar las áreas que la cámara usa para enfocar y para medir el balance de blancos y la exposición automática. Ambas funciones usan la nueva clase Camera.Area para especificar la región de la vista actual de la cámara que se debe enfocar o medir. Una instancia de la clase Camera.Area define los límites del área con un Rect y el peso del área (que representa el nivel de importancia de esa área en relación con otras áreas en consideración) con un número entero.

Antes de establecer un área de enfoque o de medición, primero debes llamar a getMaxNumFocusAreas() o getMaxNumMeteringAreas(), respectivamente. Si devuelve cero, entonces el dispositivo no es compatible con la función correspondiente.

Para especificar las áreas de enfoque o medición que se usarán, simplemente llama a setFocusAreas() o setMeteringAreas(). Cada uno toma una List de objetos Camera.Area que indican las áreas que se deben considerar. para enfocar o medir. Por ejemplo, puedes implementar una función que le permita al usuario establecer el área de enfoque tocando un área de la vista previa, que luego traduces a un objeto Camera.Area y solicitas que la cámara enfoque esa área de la escena. El enfoque o la exposición en esa área se actualizarán continuamente a medida que cambie la escena.

Enfoque automático continuo para las fotos

Ahora puedes habilitar el enfoque automático continuo (CAF) cuando tomes fotos. Para habilitar CAF en tu app de cámara, pasa FOCUS_MODE_CONTINUOUS_PICTURE a setFocusMode(). Cuando tengas todo listo para tomar una foto, llama a autoFocus(). Tu Camera.AutoFocusCallback recibe de inmediato una devolución de llamada para indicar si se logró el enfoque. Para reanudar el CAF después de recibir la devolución de llamada, debes llamar a cancelAutoFocus().

Nota: El enfoque automático continuo también es compatible cuando se captura video con FOCUS_MODE_CONTINUOUS_VIDEO, que se agregó en el nivel de API 9.

Otras funciones de la cámara

  • Mientras grabas un video, ahora puedes llamar a takePicture() para guardar una foto sin interrumpir la sesión de video. Antes de hacerlo, debes llamar a isVideoSnapshotSupported() para asegurarte de que el hardware lo admita.
  • Ahora puedes bloquear la exposición automática y el balance de blancos con setAutoExposureLock() y setAutoWhiteBalanceLock() para evitar que estas propiedades cambien.
  • Ahora puedes llamar a setDisplayOrientation() mientras se ejecuta la vista previa de la cámara. Antes, se podía llamar así solo antes de iniciar la vista previa, pero ahora puede cambiar la orientación en cualquier momento.

Intents de transmisión de la cámara

  • Camera.ACTION_NEW_PICTURE Esto indica que el usuario capturó una foto nueva. La app de Cámara integrada invoca este después de capturar una foto, y apps de cámara de terceros también deben transmitir este intent después de tomar una foto.
  • Camera.ACTION_NEW_VIDEO Esto indica que el usuario capturó un video nuevo. La app de Cámara integrada invoca este después de que se graba un video, y las apps de cámara de terceros también deben transmitir este intent después de grabar un video.

Android Beam (envío de NDEF con NFC)

Android Beam es una nueva función de NFC que te permite enviar mensajes NDEF de un dispositivo a otro (un proceso que también se conoce como "Push NDEF"). La transferencia de datos se inicia cuando dos dispositivos con Android que admiten Android Beam están cerca (alrededor de 4 cm), por lo general, con la parte posterior en contacto. Los datos dentro del mensaje NDEF pueden contener cualquier dato que desees compartir. entre dispositivos. Por ejemplo, la app de Contactos comparte contactos, YouTube comparte videos y el navegador comparte URLs con Android Beam.

Para transmitir datos entre dispositivos con Android Beam, debes crear un NdefMessage que contenga la información que deseas compartir mientras tu actividad está en primer plano. Luego, debes pasar el NdefMessage al sistema de una de las siguientes maneras:

En caso de que quieras ejecutar un código específico una vez que el sistema haya entregado correctamente tu mensaje NDEF al otro dispositivo, puedes implementar NfcAdapter.OnNdefPushCompleteCallback y configurarlo con setNdefPushCompleteCallback(). El sistema y, luego, llama a onNdefPushComplete() cuando se entregue el mensaje.

En el dispositivo receptor, el sistema envía mensajes de inserción NDEF de manera similar a las etiquetas NFC normales. El sistema invoca un intent con la acción ACTION_NDEF_DISCOVERED para iniciar una actividad, con una URL o un tipo MIME establecido según el primer NdefRecord en NdefMessage. Para la actividad que quieres respondes, puedes declarar filtros de intents para las URLs o los tipos de MIME que son importantes para tu app. Para obtener más información sobre el envío de etiquetas, consulta la guía para desarrolladores de NFC.

Si deseas que tu NdefMessage lleve un URI, ahora puedes usar la función conveniente. el método createUri para construir un nuevo NdefRecord basado en una cadena o un objeto Uri. Si el URI es un formato especial que quieres que tu aplicación también reciba durante un evento de Android Beam, puedes debes crear un filtro de intents para tu actividad con el mismo esquema de URI para recibir el mensaje NDEF entrante.

También debes pasar un “registro de la aplicación para Android” con tu NdefMessage en para garantizar que tu aplicación maneje el mensaje NDEF entrante, incluso si se las aplicaciones filtran la misma acción de intent. Puedes crear un registro de aplicación para Android con llamando a createApplicationRecord(), pasándola el nombre del paquete de tu aplicación. Cuando el otro dispositivo recibe el mensaje NDEF con el registro de aplicación y varias aplicaciones contienen actividades que manejan el intent especificado, el sistema siempre entrega el mensaje a la actividad en tu aplicación (en función de la coincidencia registro de aplicación). Si el dispositivo de destino no tiene instalada tu aplicación, el sistema usa el registro de la aplicación para Android para iniciar Google Play y dirigir al usuario a la aplicación para que la instale.

Si tu aplicación no usa las APIs de NFC para realizar la mensajería de NDEF Push, Android proporciona un comportamiento predeterminado: cuando tu aplicación está en primer plano en un dispositivo y se invoca Android Beam con otro dispositivo con Android, el otro dispositivo recibe un mensaje NDEF con un registro de aplicación de Android que identifica tu aplicación. Si el dispositivo receptor tiene instalada la aplicación, el sistema la inicia. Si no está instalada, se abre Google Play y dirige al usuario a tu aplicación para que la instale.

Puedes obtener más información sobre Android Beam y otras funciones de NFC en la guía para desarrolladores Conceptos básicos de NFC. Para ver un código de ejemplo con Android Beam, consulta la documentación de Android Demostración de Beam.

P2P Wi-Fi

Android ahora admite conexiones Wi-Fi entre pares (P2P) entre dispositivos con Android y otros tipos de dispositivos (de conformidad con el programa de certificación Wi-Fi Direct™ de Wi-Fi Alliance) sin un hotspot ni conexión a Internet. El framework de Android proporciona un conjunto de APIs de Wi-Fi P2P que te permiten detectar otros dispositivos y conectarte a ellos si cada uno admite Wi-Fi P2P, y después comunicarte mediante una conexión rápida a distancias mayores que las permitidas por una conexión Bluetooth.

Un paquete nuevo, android.net.wifi.p2p, contiene todas las APIs para realizar conexiones entre pares conexiones con Wi-Fi. La clase principal con la que debes trabajar es WifiP2pManager, que puedes adquirir llamando a getSystemService(WIFI_P2P_SERVICE). WifiP2pManager incluye APIs que te permiten hacer lo siguiente:

  • Inicializa tu aplicación para conexiones P2P llamando a initialize()
  • Llama a discoverPeers() para descubrir dispositivos cercanos
  • Inicia una conexión P2P llamando a connect()
  • Y mucho más

También se necesitan otras interfaces y clases, como las siguientes:

  • La interfaz WifiP2pManager.ActionListener te permite recibir las devoluciones de llamadas cuando se realiza correctamente o falla una operación, como descubrir pares o conectarse a ellos.
  • La interfaz WifiP2pManager.PeerListListener te permite recibir información sobre los pares descubiertos. La devolución de llamada proporciona un WifiP2pDeviceList, desde el cual puedes recuperar un objeto WifiP2pDevice para cada dispositivo dentro del alcance y obtener información como la siguiente: el nombre del dispositivo, la dirección, el tipo de dispositivo, las configuraciones de WPS que admite el dispositivo y mucho más.
  • La interfaz WifiP2pManager.GroupInfoListener te permite hacer lo siguiente: recibir información sobre un grupo P2P. La devolución de llamada proporciona un objeto WifiP2pGroup, que proporciona información del grupo, como el propietario, el nombre de la red y la frase de contraseña.
  • La interfaz WifiP2pManager.ConnectionInfoListener te permite recibir información sobre la conexión actual. La devolución de llamada proporciona un objeto WifiP2pInfo, que tiene información como si se formó un grupo y quién es su propietario.

Para usar las APIs de Wi-Fi P2P, tu app debe solicitar los siguientes permisos del usuario:

El sistema Android también transmite varias acciones diferentes durante ciertos eventos de P2P Wi-Fi:

Consulta la documentación de WifiP2pManager para obtener más información. También mira la Demostración de P2P Wi-Fi en la aplicación de ejemplo.

Dispositivos de salud Bluetooth

Android ahora admite dispositivos del perfil de salud de Bluetooth, por lo que puedes crear aplicaciones que usen Bluetooth para comunicarse con dispositivos de salud que admiten Bluetooth, como monitores de frecuencia cardíaca, medidores de la sangre, termómetros y balanzas.

Al igual que con los dispositivos de perfil A2DP y de auriculares comunes, debes llamar a getProfileProxy() con un BluetoothProfile.ServiceListener y el tipo de perfil HEALTH para establecer una conexión con el perfil. objeto de proxy.

Una vez que hayas adquirido el proxy de perfiles de salud (el BluetoothHealth (objeto), conectarse a dispositivos de salud vinculados y comunicarse con ellos implica el siguiente Clases de Bluetooth:

  • BluetoothHealthCallback: Debes extender esta clase e implementar los métodos de devolución de llamada para recibir actualizaciones sobre los cambios en el estado de registro de la aplicación y el estado de canal de Bluetooth.
  • BluetoothHealthAppConfiguration: Durante las devoluciones de llamada a tu BluetoothHealthCallback, recibirás una instancia de este objeto, que proporciona información de configuración sobre el dispositivo de salud Bluetooth disponible que debes usar para realizar varias operaciones, como iniciar y finalizar conexiones con las APIs de BluetoothHealth.

Para obtener más información sobre el uso del perfil de salud de Bluetooth, consulta la documentación de BluetoothHealth.

Accesibilidad

Android 4.0 mejora la accesibilidad para los usuarios con discapacidad visual con el nuevo modo de exploración por toque y las APIs extendidas que te permiten proporcionar más información sobre el contenido de la vista o desarrollar servicios de accesibilidad avanzados.

Modo de exploración táctil

Ahora, los usuarios con pérdida de visión pueden explorar la pantalla tocando y arrastrando un dedo sobre el pantalla para escuchar descripciones de voz del contenido. Debido a que el modo de exploración táctil funciona como un cursor virtual, permite que los lectores de pantalla identifiquen el texto descriptivo de la misma manera que lo hacen cuando el usuario navega con un pad direccional o una bola de seguimiento, ya que leen la información que proporcionan android:contentDescription y setContentDescription() cuando se simula un evento de "colocar el cursor sobre". Por lo tanto, ten en cuenta que debes proporcionar texto descriptivo para las vistas de tu aplicación, en especial para ImageButton, EditText, ImageView y otros widgets que podrían no contener texto descriptivo de forma natural.

Accesibilidad para vistas

Para mejorar la información disponible para los servicios de accesibilidad, como los lectores de pantalla, puedes implementar nuevos métodos de devolución de llamada para eventos de accesibilidad en tus componentes View personalizados.

Es importante tener en cuenta que el comportamiento del método sendAccessibilityEvent() cambió en Android 4.0. Al igual que con la versión anterior de Android, cuando el usuario habilita los servicios de accesibilidad en el dispositivo y se produce un evento de entrada, como un clic o un desplazamiento del mouse, se notifica a la vista correspondiente con una llamada a sendAccessibilityEvent(). Anteriormente, la implementación de sendAccessibilityEvent() inicializaba un AccessibilityEvent y lo enviaba a AccessibilityManager. El nuevo comportamiento implica una devolución de llamada adicional métodos que permiten que la vista y sus elementos superiores agreguen más información contextual al evento:

  1. Cuando se invocan, los métodos sendAccessibilityEvent() y sendAccessibilityEventUnchecked() aplazan su ejecución a onInitializeAccessibilityEvent().

    Es posible que las implementaciones personalizadas de View deseen implementar onInitializeAccessibilityEvent() para adjuntar información de accesibilidad adicional a AccessibilityEvent, pero también deben llamar a la implementación superior para proporcionar información predeterminada, como la descripción del contenido estándar, el índice de elementos y mucho más. Sin embargo, no debes agregar contenido de texto adicional en esta devolución de llamada; eso sucederá más adelante.

  2. Una vez inicializado, el evento es uno de varios tipos que deben completarse con texto. información, la vista recibe una llamada a dispatchPopulateAccessibilityEvent(), que difiere a la onPopulateAccessibilityEvent() devolución de llamada.

    Por lo general, las implementaciones personalizadas de View deben implementar onPopulateAccessibilityEvent() para agregar más contenido de texto a AccessibilityEvent si falta el texto android:contentDescription insuficientes. Para agregar más texto descriptivo al AccessibilityEvent, llama a getText().add().

  3. En este punto, View pasa el evento hacia arriba en la jerarquía de vistas llamando a requestSendAccessibilityEvent() en el vista parental. Luego, cada vista superior tiene la oportunidad de aumentar la información de accesibilidad agregando un AccessibilityRecord, hasta que llega a la vista raíz, que envía el evento a AccessibilityManager con sendAccessibilityEvent().

Además de los nuevos métodos anteriores, que son útiles para extender la clase View, también puedes interceptar estas devoluciones de llamada de eventos en cualquier View extendiendo AccessibilityDelegate y configurándolo en la vista con setAccessibilityDelegate() Cuando lo hagas, cada método de accesibilidad de la vista aplaza la llamada al método correspondiente en el delegado. Por ejemplo, cuando la vista recibe una llamada a onPopulateAccessibilityEvent(), la pasa al mismo método en View.AccessibilityDelegate. Cualquier método que el delegado no controle se devuelve a la vista para el comportamiento predeterminado. Esto te permite anular solo los métodos necesarios para cualquier vista determinada sin extender la clase View.

Si quieres mantener la compatibilidad con versiones de Android anteriores a la 4.0 y, al mismo tiempo, ofrecer compatibilidad las nuevas APIs de accesibilidad, puedes hacerlo con la versión más reciente de la compatibilidad con v4 biblioteca (en Paquete de compatibilidad, r4) usando un conjunto de clases de utilidades que brinden las nuevas APIs de accesibilidad en un entorno retrocompatible el diseño de tu producto.

Servicios de accesibilidad

Si estás desarrollando un servicio de accesibilidad, la información sobre varios eventos de accesibilidad se expandió considerablemente para habilitar comentarios sobre accesibilidad más avanzados para los usuarios. En En particular, los eventos se generan en función de la composición de las vistas, lo que proporciona una mejor información de contexto y lo que permite que los servicios de accesibilidad recorran las jerarquías de vistas para obtener información adicional sobre estas y tratar casos especiales.

Si estás desarrollando un servicio de accesibilidad (como un lector de pantalla), puedes acceder información adicional de contenido y recorrer jerarquías de vistas con el siguiente procedimiento:

  1. Cuando recibas un AccessibilityEvent de una aplicación, llama a AccessibilityEvent.getRecord() para recuperar un AccessibilityRecord específico (puede haber varios registros adjuntos al evento).
  2. Desde AccessibilityEvent o un AccessibilityRecord individual, puedes llamar a getSource() para recuperar un objeto AccessibilityNodeInfo.

    Un AccessibilityNodeInfo representa un solo nodo del contenido de la ventana en un formato que te permita consultar información de accesibilidad sobre ese . El objeto AccessibilityNodeInfo que se muestra desde AccessibilityEvent describe la fuente del evento, mientras que la fuente de un AccessibilityRecord describe el predecesor de la fuente del evento.

  3. Con AccessibilityNodeInfo, puedes consultar información sobre ello, llama a getParent() o getChild() para desviar la vista jerarquía y hasta agregar vistas secundarias al nodo.

Para que tu aplicación se publique en el sistema como un servicio de accesibilidad, debe declarar un archivo de configuración XML que corresponda a AccessibilityServiceInfo. Para obtener más información sobre cómo crear un servicio de accesibilidad, consulta AccessibilityService y SERVICE_META_DATA para obtener información sobre la configuración XML.

Otras APIs de accesibilidad

Si te interesa el estado de accesibilidad del dispositivo, AccessibilityManager tiene algunas APIs nuevas, como las siguientes:

Servicios de corrector ortográfico

Un nuevo marco de trabajo del corrector ortográfico permite que las aplicaciones creen correctores ortográficos de una manera similar a la del framework de métodos de entrada (para IME). Para crear un corrector ortográfico nuevo, debes implementar un servicio que extienda SpellCheckerService y extienda la clase SpellCheckerService.Session para proporcionar sugerencias ortográficas basadas en el texto que proporcionan los métodos de devolución de llamada de la interfaz. En los métodos de devolución de llamada de SpellCheckerService.Session, debes mostrar las sugerencias ortográficas como objetos SuggestionsInfo.

Las aplicaciones con un servicio de corrector ortográfico deben declarar el permiso BIND_TEXT_SERVICE según lo requiera el servicio. El servicio también debe declarar un filtro de intents con <action android:name="android.service.textservice.SpellCheckerService" /> como la acción del intent y debe Incluye un elemento <meta-data> que declara la información de configuración para el hechizo. de verificación.

Consulta la app de ejemplo Servicio de corrector ortográfico y la app de ejemplo Cliente de corrector ortográfico para ver el código de ejemplo.

Motores de texto a voz

Las APIs de texto a voz (TTS) de Android se ampliaron significativamente para permitir que las aplicaciones implementen motores de TTS personalizados con mayor facilidad, mientras que las aplicaciones que desean usar un motor de TTS tienen algunas APIs nuevas para seleccionar un motor.

Cómo usar motores de texto a voz

En versiones anteriores de Android, podías usar la clase TextToSpeech para realizar operaciones de texto a voz (TTS) con el motor de TTS que proporciona el sistema o establecer un motor personalizado con setEngineByPackageName(). En Android 4.0, el método setEngineByPackageName() dejó de estar disponible y ahora puedes especificar el motor que se usará con un nuevo constructor TextToSpeech que acepta el nombre del paquete de un motor de TTS.

También puedes consultar los motores de TTS disponibles con getEngines(). Este método muestra una lista de objetos TextToSpeech.EngineInfo, que incluyen metadatos como el ícono, la etiqueta y el nombre del paquete del motor.

Cómo compilar motores de texto a voz

Antes, los motores personalizados requerían que se compilara con un encabezado nativo sin documentar. . En Android 4.0, hay un conjunto completo de APIs del framework para compilar motores de TTS.

La configuración básica requiere una implementación de TextToSpeechService que responda al intent INTENT_ACTION_TTS_SERVICE. El trabajo principal de un motor de TTS se realiza durante la devolución de llamada de onSynthesizeText() en un servicio que extiende TextToSpeechService. El sistema le entrega a este método dos objetos:

  • SynthesisRequest: Contiene varios datos, como el texto que se sintetizará, la configuración regional, la velocidad de la voz y el tono de voz.
  • SynthesisCallback: Esta es la interfaz a través de la cual el motor de TTS entrega los datos de voz resultantes como audio de transmisión. Primero, el motor debe llamar a start() para indicar que está listo para entregar el audio y, luego, llamar a audioAvailable() y pasarle los datos de audio en un búfer de bytes. Una vez que el motor haya pasado todo el audio a través del búfer, llama a done().

Ahora que el framework admite una API real para crear motores de TTS, se quitó la compatibilidad con la implementación de código nativo. Busca una entrada de blog sobre una capa de compatibilidad que puedas usar para convertir tus motores de TTS anteriores al nuevo framework.

Para ver un ejemplo de un motor de TTS con las nuevas APIs, consulta la app de ejemplo de Motor de texto a voz.

Uso de red

Android 4.0 ofrece a los usuarios una visibilidad precisa de la cantidad de datos de red que utilizan sus aplicaciones. La app de Configuración ofrece controles que permiten a los usuarios administrar y establecer límites para el uso de datos de red incluso inhabilitar el uso de datos en segundo plano para apps individuales. Para evitar que los usuarios inhabiliten tus el acceso de la app a los datos en segundo plano, debes desarrollar estrategias de forma eficiente y ajustar el uso según el tipo de conexión disponible.

Si tu aplicación realiza muchas transacciones de red, debes proporcionar una configuración que permita a los usuarios controlar los hábitos de datos de tu app, como la frecuencia con la que sincroniza los datos, si realiza cargas o descargas solo cuando hay una conexión Wi-Fi, si utiliza los datos mientras está en roaming, etc. Con estos controles a su disposición, es mucho menos probable que los usuarios inhabiliten el acceso de tu app a los datos cuando se acercan a sus límites, ya que pueden controlar con precisión la cantidad de datos que usa tu app. Si proporcionas una actividad de preferencia con esta configuración, debes incluir en su declaración de manifiesto un filtro de intents para la acción ACTION_MANAGE_NETWORK_USAGE. Por ejemplo:

<activity android:name="DataPreferences" android:label="@string/title_preferences">
    <intent-filter>
       <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
       <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Este filtro de intents le indica al sistema que esta es la actividad que controla tu el uso de datos por parte de la aplicación. Por lo tanto, cuando el usuario inspecciona cuántos datos usa tu app desde la app de configuración, se muestra un botón "Ver configuración de la aplicación" que inicia tu actividad de preferencia para que el usuario pueda definir mejor la cantidad de datos que usa tu app.

Además, ten en cuenta que getBackgroundDataSetting() ahora es obsoleto y siempre muestra true; en su lugar, usa getActiveNetworkInfo(). Antes de intentar realizar transacciones de red, siempre debes llamar a getActiveNetworkInfo() para obtener el NetworkInfo que representa la red actual y consultar isConnected() para verificar si el dispositivo tiene una conexión. Luego, puedes verificar otras propiedades de conexión, como si el dispositivo está en roaming o conectado a Wi-Fi.

Enterprise

Android 4.0 amplía las capacidades de las aplicaciones empresariales con las siguientes funciones.

Servicios de VPN

El nuevo VpnService permite que las aplicaciones compilen su propia VPN (red privada virtual), que se ejecuta como Service. Un servicio de VPN crea una interfaz para un red virtual con su propia dirección y reglas de enrutamiento, y realiza todas las lecturas y escrituras con un descriptor de archivos.

Para crear un servicio de VPN, usa VpnService.Builder, que te permite especificar la dirección de red, el servidor DNS, la ruta de red y mucho más. Cuando se complete, puedes establecer la interfaz llamando a establish(), que muestra un ParcelFileDescriptor.

Debido a que un servicio de VPN puede interceptar paquetes, existen consecuencias de seguridad. Por lo tanto, si implementar VpnService, tu servicio debe requerir el BIND_VPN_SERVICE para garantizar que solo el sistema pueda vincularse a él (solo se otorga este permiso al sistema; las aplicaciones no pueden solicitarlo). Luego, para usar el servicio de VPN, los usuarios deben habilitarlo manualmente en la configuración del sistema.

Políticas de dispositivo

Las aplicaciones que administran las restricciones del dispositivo ahora pueden inhabilitar la cámara con setCameraDisabled() y la propiedad USES_POLICY_DISABLE_CAMERA (aplicada con un elemento <disable-camera /> en el archivo de configuración de la política).

Administración de certificados

La nueva clase KeyChain proporciona APIs que te permiten importar y acceder en el almacén de claves del sistema. Los certificados optimizan la instalación de los certificados de cliente (para validar la identidad del usuario) y los certificados de la autoridad certificadora (para verificar la identidad del servidor). Las aplicaciones como los navegadores web o los clientes de correo electrónico pueden acceder a la versión certificados para autenticar usuarios en los servidores. Consulta la KeyChain documentación para obtener más información.

Sensores del dispositivo

Se agregaron dos tipos de sensores nuevos en Android 4.0:

  • TYPE_AMBIENT_TEMPERATURE: Un sensor de temperatura que proporciona la temperatura ambiente (de la habitación) en grados Celsius.
  • TYPE_RELATIVE_HUMIDITY: un sensor de humedad que proporciona la la humedad relativa del ambiente (habitación) como porcentaje.

Si un dispositivo tiene sensores TYPE_AMBIENT_TEMPERATURE y TYPE_RELATIVE_HUMIDITY, puedes usarlos para calcular el punto de condensación y la humedad absoluta.

El sensor de temperatura anterior, TYPE_TEMPERATURE, se ha obsoleto. En su lugar, debes usar el sensor TYPE_AMBIENT_TEMPERATURE.

Además, los tres sensores sintéticos de Android se mejoraron mucho, por lo que ahora tienen una latencia más baja y una salida más fluida. Estos sensores incluyen el sensor de gravedad (TYPE_GRAVITY), el sensor del vector de rotación (TYPE_ROTATION_VECTOR) y el sensor de aceleración lineal (TYPE_LINEAR_ACCELERATION). Los sensores mejorados dependen del giroscopio para mejorar su salida, de modo que los sensores solo aparezcan en dispositivos que tengan giroscopio.

Barra de acciones

Se actualizó ActionBar para admitir varios comportamientos nuevos. Más probable Lo más importante es que el sistema administra correctamente el tamaño y la configuración de la barra de acciones cuando se ejecuta en pantallas más pequeñas para proporcionar una experiencia del usuario óptima en todos los tamaños de pantalla. Por ejemplo: cuando la pantalla es angosta (como cuando un teléfono celular se encuentra en orientación vertical), la barra de acciones las pestañas de navegación aparecen en una “barra apilada”, que aparece justo debajo de la barra de acciones principal. También puedes habilitar una "barra de acciones dividida", que coloca todos los elementos de acción en una barra separada en la parte inferior de la pantalla cuando esta es estrecha.

Barra de acciones dividida

Si tu barra de acciones incluye varios elementos de acción, no todos caben en la barra de acciones en una pantalla estrecha, por lo que el sistema colocará más de ellos en el menú ampliado. Sin embargo, Android 4.0 te permite habilitar la "barra de acciones dividida" para que aparezcan más elementos de acción en la pantalla en una barra separada en la parte inferior de la pantalla. Para habilitar la barra de acción dividida, agrega android:uiOptions con "splitActionBarWhenNarrow" a tu etiqueta <application> o a etiquetas <activity> individuales en tu archivo de manifiesto. Cuando esté habilitada, el sistema agregará una barra adicional en la parte inferior de la pantalla para todos los elementos de acción cuando la pantalla sea estrecha (no aparecerán elementos de acción en la barra de acciones principal).

Si deseas usar las pestañas de navegación que proporcionan las APIs de ActionBar.Tab, pero no necesitas la barra de acciones principal en la parte superior (solo quieres que aparezcan las pestañas en la parte superior), habilita la barra de acciones dividida como se describió anteriormente y también llama a setDisplayShowHomeEnabled(false) para inhabilitar el ícono de la aplicación en la barra de acciones. Cuando no queda nada en la barra de acción principal, esta desaparece. Lo único que queda son las pestañas de navegación en la parte superior y los elementos de acción en la parte inferior de la pantalla.

Estilos de la barra de acciones

Si deseas aplicar un estilo personalizado a la barra de acciones, puedes usar las nuevas propiedades de estilo backgroundStacked y backgroundSplit para aplicar un fondo. drawable o color a la barra apilada y la barra dividida, respectivamente. También puedes configurar estos estilos en el tiempo de ejecución con setStackedBackgroundDrawable() y setSplitBackgroundDrawable().

Proveedor de acciones

La nueva clase ActionProvider te permite crear un controlador especializado para elementos de acción. Un proveedor de acciones puede definir una vista de acción, un comportamiento de acción predeterminado y un submenú para cada elemento de acción al que está asociado. Cuando quieras crear un elemento de acción que tenga comportamientos dinámicos (como una vista de acción variable, una acción predeterminada o un submenú), extender ActionProvider es una buena solución para crear un componente reutilizable, en lugar de controlar las diversas transformaciones de elementos de acción en tu fragmento o actividad

Por ejemplo, ShareActionProvider es una extensión de ActionProvider que facilita una acción de "compartir" desde la barra de acción. En lugar de usar elemento de acción tradicional que invoca el intent ACTION_SEND, puedes usar este proveedor de acciones para presentar una vista de acción con una lista desplegable de aplicaciones que manejan el intent ACTION_SEND. Cuando el usuario selecciona una aplicación para usar para la acción, ShareActionProvider recuerda esa selección y la proporciona en la vista de acción para acceder más rápido al uso compartido con esa app.

Para declarar un proveedor de acciones para un elemento de acción, incluye el atributo android:actionProviderClass en el elemento <item> del menú de opciones de tu actividad, con el nombre de clase del proveedor de acciones como valor. Por ejemplo:

<item android:id="@+id/menu_share"
      android:title="Share"
      android:showAsAction="ifRoom"
      android:actionProviderClass="android.widget.ShareActionProvider" />

En el método de devolución de llamada onCreateOptionsMenu() de tu actividad, recupera una instancia del proveedor de acciones del elemento de menú y establece el intent:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options, menu)
    val shareActionProvider = menu.findItem(R.id.menu_share)?.actionProvider as? ShareActionProvider
    // Set the share intent of the share action provider.
    shareActionProvider?.setShareIntent(createShareIntent())
    ...
    return super.onCreateOptionsMenu(menu)
}

Java

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.options, menu);
    ShareActionProvider shareActionProvider =
          (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();
    // Set the share intent of the share action provider.
    shareActionProvider.setShareIntent(createShareIntent());
    ...
    return super.onCreateOptionsMenu(menu);
}

Para ver un ejemplo del uso de ShareActionProvider, consulta ActionBarShareActionProviderActivity en ApiDemos.

Vistas de acción que se pueden contraer

Los elementos de acción que proporcionan una vista de acción ahora pueden alternar entre su estado de vista de acción y el estado de elemento de acción tradicional. Anteriormente, solo se admitía SearchView se puede contraer cuando se usa como vista de acción, pero ahora puede agregar una vista de acción para cualquier elemento de acción y para alternar entre el estado expandido (la vista de acción es visible) y el estado contraído (el elemento de acción es visibles).

Para declarar que un elemento de acción que contiene una vista de acción es contraíble, incluye la marca “collapseActionView" en el atributo android:showAsAction del elemento <item> en el archivo en formato XML del menú.

Para recibir devoluciones de llamada cuando una vista de acción cambie entre expandida y contraída, registra un instancia de MenuItem.OnActionExpandListener con el MenuItem respectivo llamando a setOnActionExpandListener(). Por lo general, debes hacerlo durante la devolución de llamada de onCreateOptionsMenu().

Para controlar una vista de acción que se puede contraer, puedes llamar a collapseActionView() y expandActionView() en el MenuItem respectivo.

Cuando creas una vista de acción personalizada, también puedes implementar la nueva interfaz CollapsibleActionView para recibir devoluciones de llamada cuando la vista se expande y contraída.

Otras APIs para la barra de acciones

  • setHomeButtonEnabled() te permite especificar si el ícono o el logotipo se comportan como un botón para navegar a la pantalla principal o “arriba” (pasa “verdadero” para que se comporte como un botón).
  • setIcon() y setLogo() te permiten definir el ícono o el logotipo de la barra de acciones durante el tiempo de ejecución.
  • Fragment.setMenuVisibility() te permite habilitar o inhabilita la visibilidad de los elementos del menú de opciones declarados por el fragmento. Esto es útil si el fragmento se agregó a la actividad, pero no es visible, por lo que los elementos de menú deben ocultarse.
  • FragmentManager.invalidateOptionsMenu() te permite invalidar el menú de opciones de la actividad durante varios estados del ciclo de vida del fragmento en las que el uso del método equivalente de Activity podría no estar disponible.

Interfaz de usuario y vistas

Android 4.0 presenta una variedad de vistas nuevas y otros componentes de la IU.

GridLayout

GridLayout es un nuevo grupo de vistas que coloca vistas secundarias en una cuadrícula rectangular. A diferencia de TableLayout, GridLayout se basa en una de datos y no usa vistas intermedias, como filas de la tabla, para proporcionar estructura. En su lugar, los elementos secundarios especifican qué filas y columnas deben ocupar (las celdas pueden abarcar varias filas o columnas) y, de forma predeterminada, se organizan de forma secuencial en las filas y columnas de la cuadrícula. La orientación GridLayout determina si los elementos secundarios secuenciales son de forma predeterminada horizontal o vertical. El espacio entre los niños puede especificarse mediante instancias de la nueva vista Space o estableciendo los parámetros de margen relevantes sobre los niños.

Consulta ApiDemos para ver muestras que usan GridLayout.

Vista de textura

TextureView es una vista nueva que te permite mostrar una transmisión de contenido, como un video o una escena de OpenGL. Aunque es similar a SurfaceView, TextureView es único en el sentido de que se comporta como una vista normal, en lugar de crear una ventana separada, por lo que puedes tratarla como a cualquier otro objeto View. Por ejemplo, puedes aplicarle transformaciones, animarlo con ViewPropertyAnimator o ajustar su opacidad con setAlpha().

Ten en cuenta que TextureView solo funciona dentro de una ventana acelerada por hardware.

Para obtener más información, consulta la documentación de TextureView.

Cambiar widget

El nuevo widget Switch es un interruptor de dos estados que los usuarios pueden arrastrar a un lado o al otro (o simplemente presionar) para activar o desactivar una opción entre dos estados.

Puedes usar los atributos android:textOn y android:textOff para especificar el texto aparezca en el interruptor cuando esté activado o desactivado. El atributo android:text también te permite colocar una etiqueta junto al interruptor.

Para ver un ejemplo que usa interruptores, consulta el archivo de diseño switches.xml y la actividad Switches correspondiente.

Android 3.0 introdujo PopupMenu para crear menús contextuales cortos que se destacan en el punto de anclaje que especifiques (generalmente, en el punto del elemento seleccionado). Android 4.0 extiende PopupMenu con algunas funciones útiles:

  • Ahora, puedes aumentar fácilmente el contenido de un menú emergente desde un recurso de menú XML con inflate() y pasarle el ID de recurso del menú.
  • También puedes crear un PopupMenu.OnDismissListener que reciba una devolución de llamada cuando se descarte el menú.

Preferencias

Una nueva clase abstracta TwoStatePreference sirve de base para que ofrecen una opción de selección de dos estados. El nuevo SwitchPreference es una extensión de TwoStatePreference que proporciona un widget Switch en la vista de preferencias para permitir que los usuarios activen o desactiven un parámetro de configuración sin necesidad de abrir una pantalla o un diálogo de preferencias adicionales. Por ejemplo, la aplicación de Configuración usa un SwitchPreference para la configuración de Wi-Fi y Bluetooth.

Temas del sistema

El tema predeterminado para todas las aplicaciones orientadas a Android 4.0 (estableciendo targetSdkVersion o minSdkVersion a “14" o superior) ahora es el "dispositivo predeterminado" tema: Theme.DeviceDefault. Puede ser el tema Holo oscuro o un tema oscuro diferente definido por el dispositivo específico.

Se garantiza que la familia de temas Theme.Holo no cambie de un dispositivo a otro cuando se ejecute la misma versión de Android. Si explícitamente aplicar cualquiera de los temas Theme.Holo a tus actividades, puedes ten la seguridad de que estos temas no cambiarán de personaje en diferentes dispositivos dentro del mismo versión de la plataforma.

Si deseas que tu app se integre con el tema general del dispositivo (por ejemplo, cuando se crean diferentes OEMs proporcionar diferentes temas predeterminados para el sistema), debes aplicar temas de la familia Theme.DeviceDefault de forma explícita.

Botón del menú de opciones

A partir de Android 4.0, notarás que los teléfonos celulares ya no requieren un botón de hardware de Menú. Sin embargo, no es necesario que te preocupes por esto si tu aplicación existente proporciona un menú de opciones y espera que haya un botón de menú. Para garantizar que las apps existentes sigan funcionando como se espera, el sistema proporciona el botón de menú en pantalla para las aplicaciones diseñadas para versiones anteriores de Android.

Para obtener la mejor experiencia del usuario, las apps nuevas y actualizadas deben usar ActionBar para brindar acceso a los elementos del menú y establecer targetSdkVersion como "14" para aprovechar los comportamientos predeterminados del framework más recientes.

Controles para la visibilidad de la IU del sistema

Desde los primeros días de Android, el sistema administra un componente de la IU conocido como barra de estado, que reside en la parte superior de los dispositivos de telefonía celular para proporcionar información como la señal del operador, la hora, las notificaciones, etcétera. Android 3.0 agregó la barra del sistema para tablets. en la parte inferior de la pantalla para proporcionar los controles de navegación del sistema (Inicio, Atrás, etc.) y también una interfaz para elementos que tradicionalmente proporcionaba la barra de estado. En Android 4.0, el sistema proporciona un nuevo tipo de IU del sistema llamada barra de navegación. Tú podría considerar que la barra de navegación es una versión reajustada de la barra del sistema, diseñada para móviles, ya que proporciona controles de navegación para los dispositivos que no tienen equivalentes de hardware para navegar por el sistema, pero excluye las la IU de notificaciones y los controles de configuración de la barra del sistema. Por lo tanto, un dispositivo que proporciona la barra de navegación también tiene la barra de estado en la parte superior.

Hasta el día de hoy, puedes ocultar la barra de estado en teléfonos celulares con la marca FLAG_FULLSCREEN. En Android 4.0, las APIs que controlan Se actualizó la visibilidad de la barra del sistema para reflejar mejor el comportamiento de ambas. y la barra de navegación:

  • La marca SYSTEM_UI_FLAG_LOW_PROFILE reemplaza a la marca STATUS_BAR_HIDDEN. Cuando se establece, esta marca habilita el modo “de perfil bajo” para la barra del sistema o la barra de navegación. Los botones de navegación atenuados y otros elementos de la barra del sistema también se ocultan. Habilitando Esto es útil para crear juegos más envolventes sin distracciones para la navegación del sistema. botones.
  • La marca SYSTEM_UI_FLAG_VISIBLE reemplaza la marca STATUS_BAR_VISIBLE para solicitar que la barra del sistema o la barra de navegación sean visibles.
  • El SYSTEM_UI_FLAG_HIDE_NAVIGATION es una nueva marca que solicita la barra de navegación se oculta por completo. Ten en cuenta que esto solo funciona para la barra de navegación que usan algunos teléfonos celulares (no oculta la barra del sistema en las tablets). La barra de navegación vuelve a aparecer en cuanto el sistema recibe la entrada del usuario. Por lo tanto, este modo es útil principalmente para la reproducción de videos y otros casos en los que se necesita toda la pantalla, pero no se requiere la entrada del usuario.

Puedes establecer cada una de estas marcas para la barra del sistema y la barra de navegación llamando a setSystemUiVisibility() en cualquier vista de tu actividad. El administrador de ventanas combina (O-juntos) todas las marcas de todas las vistas de la ventana y las aplica a la IU del sistema, siempre y cuando la ventana tenga el enfoque de entrada. Cuando tu ventana pierde datos (el usuario sale de la app o aparece un diálogo), las marcas dejan de tener efecto. Del mismo modo, si quitas esas vistas de la jerarquía de vistas, ya no se aplicarán sus marcas.

Para sincronizar otros eventos de tu actividad con cambios de visibilidad en la IU del sistema (por ejemplo, ocultar la barra de acciones o algún otro control de la IU cuando se oculta la IU del sistema), debes registrar un View.OnSystemUiVisibilityChangeListener para recibir una notificación cuando cambie la visibilidad de la barra del sistema o la barra de navegación.

Consulta la clase OverscanActivity para ver una demostración de las diferentes opciones de la IU del sistema.

Marco de trabajo de entrada

Android 4.0 agrega compatibilidad con eventos de desplazamiento del cursor y nuevos eventos de la pluma stylus y el botón del mouse.

Eventos de desplazamiento del mouse

La clase View ahora admite eventos de "colocar el cursor sobre" para permitir interacciones más enriquecidas a través del uso de dispositivos de puntero (como un mouse o algún otro dispositivo que controle un cursor en pantalla).

Para recibir eventos de colocar el cursor sobre una vista, implementa View.OnHoverListener y regístralo con setOnHoverListener(). Cuando se coloca el cursor sobre en la vista, tu objeto de escucha recibe una llamada a onHover() y proporciona el View recibió el evento y un MotionEvent que describe el tipo de evento de colocar el cursor sobre un elemento que ocurrieron. El evento de desplazamiento puede ser uno de los siguientes:

Tu View.OnHoverListener debe mostrar un valor verdadero desde onHover() si controla el evento de desplazamiento del mouse. Si tu objeto de escucha muestra un valor falso, el evento de desplazamiento se enviará a la vista superior como de costumbre.

Si tu aplicación usa botones u otros widgets que cambian su apariencia en función del estado actual, ahora puedes usar el atributo android:state_hovered en un elemento de diseño de lista de estados para Proporcionan un elemento de diseño de fondo diferente cuando se coloca el cursor sobre la vista.

Para ver una demostración de los nuevos eventos de desplazamiento del mouse, consulta la clase Hover en ApiDemos.

Eventos de la pluma stylus y el botón del mouse

Android ahora proporciona APIs para recibir entradas de un dispositivo de entrada de pluma stylus, como un digitalizador periférico de la tablet o una pantalla táctil compatible con la pluma stylus.

La entrada de la pluma stylus funciona de manera similar a las entradas táctiles o del mouse. Cuando la pluma stylus está en contacto Con el digitalizador, las aplicaciones reciben eventos táctiles tal como lo harían cuando se usa un dedo para toca la pantalla. Cuando la pluma stylus se coloca sobre el digitalizador, las aplicaciones reciben del mismo modo que lo harían cuando el puntero del mouse se moviera por la pantalla cuando no se usaran botones los botones.

Tu aplicación puede distinguir entre entrada de dedo, mouse, pluma stylus y borrador consultando la “tipo de herramienta” asociada con cada puntero en una MotionEvent mediante getToolType(). Los tipos de herramientas definidos actualmente son TOOL_TYPE_UNKNOWN, TOOL_TYPE_FINGER, TOOL_TYPE_MOUSE, TOOL_TYPE_STYLUS y TOOL_TYPE_ERASER. Cuando consultas el tipo de herramienta, tu aplicación puede controlar la entrada de la pluma stylus de diferentes maneras de la entrada del dedo o del mouse.

Tu aplicación también puede consultar qué botones del mouse o de la pluma stylus se presionan estado" de un objeto MotionEvent con getButtonState(). Los estados de botón definidos actualmente son: BUTTON_PRIMARY, BUTTON_SECONDARY, BUTTON_TERTIARY, BUTTON_BACK y BUTTON_FORWARD. Para mayor comodidad, los botones del mouse hacia atrás y hacia adelante se asignan automáticamente a las teclas KEYCODE_BACK y KEYCODE_FORWARD. Tu aplicación puede controlar estas claves para admitir botón del mouse basada en la navegación hacia atrás y adelante.

Además de medir con precisión la posición y la presión de un contacto, algunos dispositivos de entrada de pluma stylus también informan la distancia entre la punta de la pluma stylus y el digitalizador, el ángulo de inclinación de la pluma stylus y el ángulo de orientación de la pluma stylus. Tu aplicación puede consultar esta información usando getAxisValue() con los códigos de eje AXIS_DISTANCE, AXIS_TILT y AXIS_ORIENTATION.

Para ver una demostración de los tipos de herramientas, los estados de los botones y los nuevos códigos de eje, consulta la clase TouchPaint en ApiDemos.

Propiedades

La nueva clase Property proporciona una forma rápida, eficiente y sencilla de especificar una propiedad en cualquier objeto que permita a los llamadores establecer o obtener valores de forma genérica en los objetos de destino. También permite la funcionalidad de pasar referencias de campos o métodos y permite que el código establezca o obtenga valores de la propiedad sin conocer los detalles de cuáles son los campos o métodos.

Por ejemplo, si quieres establecer el valor del campo bar en el objeto foo, debes antes hicieron esto:

Kotlin

foo.bar = value

Java

foo.bar = value;

Si deseas llamar al set de un campo privado subyacente bar, antes deberías hacer lo siguiente:

Kotlin

foo.setBar(value)

Java

foo.setBar(value);

Sin embargo, si deseas pasar la instancia de foo y hacer que otro código establezca el valor de bar, no hay forma de hacerlo antes de Android 4.0.

Con la clase Property, puedes declarar un Property. el objeto BAR en la clase Foo para que puedas establecer el campo en la instancia foo de la clase Foo de la siguiente manera:

Kotlin

BAR.set(foo, value)

Java

BAR.set(foo, value);

La clase View ahora aprovecha la clase Property para permitirte configurar varios campos, como las propiedades de transformación que se agregaron en Android 3.0 (ROTATION, ROTATION_X, TRANSLATION_X, etc.).

La clase ObjectAnimator también usa Property. por lo que puedes crear un ObjectAnimator con un Property, que es más rápido, eficiente y más seguro de tipos que el basado enfoque.

Aceleración de hardware

A partir de Android 4.0, la aceleración de hardware para todas las ventanas está habilitada de forma predeterminada si tu aplicación configuró targetSdkVersion o minSdkVersion a “14" o una versión posterior. Por lo general, la aceleración de hardware genera animaciones y desplazamientos más fluidos, y un mejor rendimiento y respuesta a la interacción del usuario en general.

Si es necesario, puedes inhabilitar manualmente la aceleración de hardware con hardwareAccelerated. para elementos <activity> individuales o el <application> . Como alternativa, puedes inhabilitar la aceleración de hardware para vistas individuales llamando a setLayerType(LAYER_TYPE_SOFTWARE).

Para obtener más información sobre la aceleración de hardware, incluida una lista de operaciones de dibujo que no se admiten, consulta el documento Aceleración de hardware.

Cambios de JNI

En versiones anteriores de Android, las referencias locales de JNI no eran controladores indirectos; Android usaba punteros directos. Esto no fue un problema mientras el recolector de elementos no utilizados no moviera objetos, pero parecía funcionar porque posibilitaba la escritura de códigos con errores. En Android 4.0, el sistema ahora usa referencias indirectas para detectar estos errores.

Los detalles de las referencias locales de JNI se describen en "Referencias locales y globales" en Sugerencias de JNI. En Android 4.0, CheckJNI se mejoró para detectar estos errores. Mira el Blog para desarrolladores de Android para conocer una próxima publicación sobre errores comunes con referencias de JNI y cómo puedes corregirlos.

Este cambio en la implementación de JNI solo afecta a las apps orientadas a Android 4.0, ya que establece targetSdkVersion o minSdkVersion en “14" o versiones posteriores. Si fijaste estos atributos en un valor menor, las referencias locales de JNI se comportan igual que en versiones anteriores.

WebKit

  • WebKit actualizado a la versión 534.30
  • Compatibilidad con fuentes índicas (devanagari, bengalí y tamil, incluida la compatibilidad con caracteres complejos) necesario para combinar glifos) en WebView y en el navegador integrado
  • Compatibilidad con fuentes etíopes, georgianas y armenias en WebView y las navegador integrado
  • La compatibilidad con WebDriver te permite probar apps que usan WebView con mayor facilidad.

Navegador Android

La aplicación de navegador agrega las siguientes funciones para admitir aplicaciones web:

Permisos

Los siguientes son permisos nuevos:

Funciones del dispositivo

Las siguientes son funciones nuevas de los dispositivos:

  • FEATURE_WIFI_DIRECT: Declara que la aplicación usa Wi-Fi para las comunicaciones entre pares.

Para obtener una vista detallada de todos los cambios de las APIs en Android 4.0 (nivel de API 14), consulta el Informe de diferencias de las APIs.

APIs anteriores

Además de todo lo anterior, Android 4.0 admite, de forma predeterminada, todas las APIs de versiones anteriores. Como la plataforma de Android 3.x solo está disponible para dispositivos con pantallas grandes, si tienes desarrollaron principalmente para teléfonos celulares, entonces es posible que no conozcas todas las APIs que se agregan a Android en estas versiones recientes.

Aquí te mostramos algunas de las APIs más notables que quizás no hayas visto y que ya están disponibles también en teléfonos celulares:

Android 3.0
  • Fragment: Es un componente del framework que te permite separar elementos distintos de una actividad en módulos independientes que definen su propia IU y ciclo de vida. Consulta la Fragment para desarrolladores.
  • ActionBar: Es un reemplazo de la barra de título tradicional en la parte superior de la ventana de actividad. Incluye el logotipo de la aplicación en la esquina izquierda y proporciona un nuevo para los elementos del menú. Consulta la Barra de acciones.
  • Loader: Es un componente del framework que facilita la carga asíncrona de datos en combinación con componentes de la IU para cargar datos de forma dinámica sin bloquear el subproceso principal. Consulta la guía para desarrolladores de cargadores.
  • Portapapeles del sistema: Las aplicaciones pueden copiar y pegar datos (más allá del simple texto) desde y hacia el portapapeles de todo el sistema. Los datos recortados pueden ser texto sin formato, un URI o un intent. Consulta la guía para desarrolladores sobre Copiar y pegar.
  • Arrastrar y soltar: Es un conjunto de APIs integradas en el framework de vista que facilita las operaciones de arrastrar y soltar. Consulta la guía para desarrolladores sobre Cómo arrastrar y soltar.
  • Un nuevo framework de animación flexible permite animar propiedades arbitrarias de cualquier (vista, elemento de diseño, fragmento, objeto o cualquier otro elemento) y define los aspectos de la animación, como como duración, interpolación, repetición y más. El nuevo framework permite crear animaciones en Android. más simple que nunca. Consulta la guía para desarrolladores de Animación de propiedades.
  • RenderScript Graphics y Compute Engine: RenderScript ofrece una API de renderización y procesamiento de gráficos en 3D de alto rendimiento a nivel nativo, que escribes en C (estándar C99), lo que proporciona el tipo de rendimiento que esperas de un entorno nativo y, al mismo tiempo, es portátil en varias CPUs y GPUs. Consulta la guía para desarrolladores de RenderScript.
  • Gráficos 2D con aceleración de hardware: Ahora puedes habilitar el renderizador de OpenGL para tu aplicación. Para ello, configura {android:hardwareAccelerated="true"} en el elemento <application> del elemento de manifiesto o para elementos <activity> individuales. Esto da como resultado animaciones y desplazamientos más fluidos, y un mejor rendimiento y respuesta general para el usuario interacción.

    Nota: Si configuras minSdkVersion o targetSdkVersion de tu aplicación en "14" o una versión posterior, la aceleración de hardware se habilita de forma predeterminada.

  • Y mucho, mucho más. Consulta las notas de la plataforma de Android 3.0 para obtener más información.
Android 3.1
  • APIs de USB: Son nuevas APIs potentes para integrar periféricos conectados con aplicaciones para Android. Las APIs se basan en una pila y servicios USB integrados en la plataforma, lo que incluye compatibilidad con interacciones de host y dispositivo USB. Consulta la guía para desarrolladores de Accesorios y hosts USB.
  • APIs de MTP/PTP: Las aplicaciones pueden interactuar directamente con cámaras conectadas y otros dispositivos PTP para recibir notificaciones cuando se conectan y quitan dispositivos, administrar archivos y almacenamiento en esos dispositivos, y transferir archivos y metadatos hacia y desde ellos. La API de MTP implementa el subconjunto PTP (protocolo de transferencia de imágenes) de la especificación MTP (protocolo de transferencia multimedia). Consulta la documentación de android.mtp.
  • API de RTP: Android expone una API a su pila de protocolo de transporte en tiempo real (RTP) integrada. qué aplicaciones pueden usar para administrar la transmisión de datos interactiva o a pedido. En particular, las apps que proporcionan VOIP, push-to-talk, videoconferencias y transmisión de audio pueden usar la API para iniciar sesiones y transmitir o recibir flujos de datos a través de cualquier red disponible. Consulta la documentación de android.net.rtp.
  • Compatibilidad con joysticks y otras entradas de movimiento genéricas.
  • Consulta las notas de la plataforma de Android 3.1 para ver muchas más APIs nuevas.
Android 3.2
  • Las pantallas nuevas admiten APIs que te brindan más control sobre cómo se muestran tus aplicaciones en diferentes tamaños de pantalla. La API extiende el modelo de compatibilidad de pantalla existente con el capacidad para orientar con precisión a rangos de tamaño de pantalla específicos por dimensiones, medidos en unidades de píxeles independientes de la densidad (como 600 dp o 720 dp de ancho), en lugar de hacerlo por tamaños de pantalla (como grandes o extragrandes). Por ejemplo, esto es importante para ayudarte distinguir entre una y una de 7" que, tradicionalmente, se agruparían como buckets “grande” pantallas. Consulta la entrada de blog, Nuevas herramientas para administrar los tamaños de pantalla.
  • Se agregaron nuevas constantes para <uses-feature> para declarar los requisitos de orientación horizontal o vertical de la pantalla.
  • El "tamaño de la pantalla" del dispositivo configuración ahora cambia durante la orientación de la pantalla cambio. Si tu app tiene como objetivo el nivel de API 13 o uno superior, debes controlar las "screenSize" cambio de configuración si también quieres controlar el cambio de configuración de "orientation". Consulta android:configChanges para obtener más información.
  • Consulta las notas de la plataforma de Android 3.2 para ver otras APIs nuevas.

Nivel de API

A la API de Android 4.0 se le asigna un identificador de número entero (14) que se almacena en el sistema. Este identificador, denominado "nivel de API", permite que el sistema determine correctamente si un aplicación sea compatible con el sistema antes de instalarla.

Para usar las APIs que se introdujeron en Android 4.0 en tu aplicación, debes compilarla con una plataforma de Android que admita el nivel de API 14 o versiones posteriores. Según tus necesidades, es posible que también debas agregar un atributo android:minSdkVersion="14" al elemento <uses-sdk>.

Para obtener más información, consulta ¿Qué es el nivel de API?