Nivel de API: 14
Android 4.0 (ICE_CREAM_SANDWICH
) es una actualización importante de la plataforma que agrega una variedad de funciones nuevas para usuarios y desarrolladores de apps. Además de todas las funciones y APIs nuevas que se analizan a continuación, Android 4.0 es una versión de la plataforma importante porque incluye el amplio conjunto de API y temas holográficos de Android 3.x en pantallas más pequeñas. Como desarrollador de apps, ahora tienes una sola plataforma y un framework de API unificado que te permite desarrollar y publicar tu aplicación con un solo 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 a Android 4.0 (nivel de API 14) o versiones posteriores.
Para los desarrolladores, la plataforma Android 4.0 está disponible como un componente descargable del SDK de Android. La plataforma descargable incluye una imagen del sistema y una biblioteca de Android, así como un conjunto de máscaras de emulador y mucho más. Para comenzar a desarrollar o probar Android 4.0, usa Android SDK Manager 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 API en Android 4.0.
APIs sociales en el proveedor de contactos
Las APIs de contacto definidas por el proveedor de ContactsContract
se extendieron para admitir nuevas funciones sociales, como un perfil personal para el propietario del dispositivo y la capacidad de los usuarios de invitar contactos individuales a las redes sociales que están 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 sociales que mantienen la identidad de un usuario pueden contribuir a los datos de su perfil mediante la creación de una nueva entrada ContactsContract.RawContacts
en ContactsContract.Profile
. Es decir, los contactos sin procesar que representan al usuario del dispositivo no pertenecen a la tabla tradicional de contactos sin procesar definida por el URI ContactsContract.RawContacts
. En su lugar, debes agregar un contacto sin procesar de perfil en la tabla en CONTENT_RAW_CONTACTS_URI
. Los contactos sin procesar de esta tabla se agregan en el perfil único visible para el usuario etiquetado como “Yo”.
Para agregar un nuevo contacto sin procesar al perfil, se requiere el permiso android.Manifest.permission#WRITE_PROFILE. Del mismo modo, para leer desde 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 aportan datos al perfil. La lectura del perfil del usuario es un permiso sensible y debes esperar que los usuarios sean escépticos con respecto a las apps que lo solicitan.
Intent de invitación
La acción de intent INVITE_CONTACT
permite que una app invoque una acción que indica que el usuario desea agregar un contacto a una red social. La app que recibe la app la usa para invitar al contacto especificado a esa red social. La mayoría de las apps se encuentran en el extremo receptor de esta operación. Por ejemplo, la app de Personas integrada invoca el intent de invitación cuando el usuario selecciona "Agregar conexión" para una app social específica que aparece en los detalles de contacto de una persona.
Para que tu app sea visible como en la lista "Agregar conexión", esta 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
. Para ello, agrega el atributo inviteContactActivity
al archivo de configuración de sincronización de tu app, con un nombre completo de la actividad que el sistema debe iniciar cuando envía el intent de invitación.
Luego, 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 al registro de un contacto, el sistema la procesa en una miniatura de 96 x 96 (como lo hacía antes) y una "foto visible" de 256 x 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). Para agregar una foto grande a un contacto, coloca una foto grande en la columna PHOTO
habitual de una fila de datos, que el sistema procesará para la miniatura adecuada y mostrará los registros de fotos.
Comentarios sobre el uso del contacto
Las nuevas APIs de ContactsContract.DataUsageFeedback
te permiten hacer un seguimiento de la frecuencia con la que el usuario utiliza métodos específicos para comunicarse con las personas, como la frecuencia con la que 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 método de contacto asociado con cada persona y proporciona mejores sugerencias para comunicarse con cada una de ellas.
Proveedor de calendario
Las nuevas APIs de calendario 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 de calendario. Sin embargo, algunos de los casos de uso más convincentes son los adaptadores de sincronización que sincronizan el calendario del usuario de otros servicios de calendario con el proveedor de calendario a fin de ofrecer una ubicación unificada para todos los eventos del usuario. Por ejemplo, el adaptador de sincronización del Calendario de Google sincroniza los eventos del Calendario de Google con el proveedor de calendario, lo que permite que estos eventos se vean con la app de Calendario integrada de Android.
CalendarContract
define el modelo de datos para los calendarios y la información relacionada con los eventos en el Proveedor de calendario. Todos los datos del calendario del usuario se almacenan en una serie de tablas definidas por diversas subclases de CalendarContract
:
- La tabla
CalendarContract.Calendars
contiene la información específica del calendario. Cada fila de la tabla contiene los detalles de un solo calendario, como el nombre, el color, la información de sincronización, etcétera. - La tabla
CalendarContract.Events
contiene información específica del evento. Cada fila de esta tabla contiene la información de un solo evento, como el título, la ubicación, la hora de inicio y la hora de finalización, entre otros datos. El evento puede ocurrir una vez o repetirse varias veces. Los asistentes, los recordatorios y las propiedades extendidas se almacenan en tablas separadas y usan el_ID
del evento para vincularlos con este. - La tabla
CalendarContract.Instances
contiene la hora de inicio y finalización de los casos de un evento. Cada fila de esta tabla representa un solo caso. Para los eventos únicos, hay una asignación uno a uno de instancias a eventos. En el caso de los eventos recurrentes, se generan automáticamente varias filas para que coincidan con los distintos casos de ese evento. - La tabla
CalendarContract.Attendees
contiene la información del asistente al evento o del invitado. Cada fila representa un solo invitado a un evento. Especifica el tipo de invitado que tiene 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. La cantidad de recordatorios por evento se especifica enMAX_REMINDERS
, que se establece mediante el adaptador de sincronización al que pertenece el calendario determinado. Los recordatorios se especifican en la cantidad de minutos antes de la programación del evento y se establece 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 borrarlos cuando se borran sus 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 acceso de lectura) y WRITE_CALENDAR
(para acceso de escritura).
Intent del evento
Si lo único que deseas hacer es 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:
Events.TITLE
: Es el nombre del evento.CalendarContract.EXTRA_EVENT_BEGIN_TIME
: Es la hora de inicio del evento en milisegundos desde la época.CalendarContract.EXTRA_EVENT_END_TIME
: Es la hora de finalización del evento en milisegundos desde la época.Events.EVENT_LOCATION
: Ubicación del eventoEvents.DESCRIPTION
: Descripción del eventoIntent.EXTRA_EMAIL
: Direcciones de correo electrónico de las personas a las que se invitaráEvents.RRULE
: Es la regla de recurrencia del evento.Events.ACCESS_LEVEL
: Indica si el evento es privado o público.Events.AVAILABILITY
: Indica si el período de este evento permite que se programen otros para el mismo horario.
Proveedor de buzón 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 una del proveedor de servicios del teléfono y otra de VoIP o algún otro servicio de voz alternativo. Estas apps pueden usar las API de Buzón de voz para agregar los mensajes de voz al dispositivo. Luego, la aplicación de teléfono integrada presenta todos los mensajes de voz al usuario en una presentación unificada. Si bien la aplicación de teléfono del sistema es la única que puede leer todos los mensajes de voz, cada aplicación que proporciona mensajes de voz puede leer aquellos que haya agregado al sistema (pero no puede leer mensajes de voz de otros servicios).
Debido a que, por el momento, 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 buzón de voz son aquellas que tienen buzón de voz para entregar al usuario.
La clase VoicemailContract
define el proveedor de contenido para el proveedor del buzón de voz. Las subclases VoicemailContract.Voicemails
y VoicemailContract.Status
proporcionan tablas en las que las apps pueden insertar datos del buzón de voz para almacenarlos en el dispositivo. Para ver un ejemplo de una app proveedora de buzón de voz, consulta la Demostración del proveedor de buzón de voz.
Multimedia
Android 4.0 agrega varias API 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 imágenes y 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 de ojo de pez y mucho más. El sistema realiza todos los procesamientos 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 OpenGL válido antes de poder usar las APIs de efectos. Las texturas a las que aplicas efectos pueden ser de mapas de bits, videos o incluso la cámara. Sin embargo, existen ciertas restricciones que deben cumplir las texturas:
- Deben vincularse a una imagen de textura
GL_TEXTURE_2D
. - Deben contener al menos un nivel de mipmap
Un objeto Effect
define un solo efecto multimedia que puedes aplicar a un marco de imagen. El flujo de trabajo básico para crear un Effect
es el siguiente:
- Llama a
EffectContext.createWithCurrentGlContext()
desde tu contexto de OpenGL ES 2.0. - Usa el objeto
EffectContext
que se muestra para llamar aEffectContext.getFactory()
, que muestra una instancia deEffectFactory
. - Llama a
createEffect()
y pásale un nombre de efecto desde @link android.media.effect.EffectFactory}, comoEFFECT_FISHEYE
oEFFECT_VIGNETTE
.
Para ajustar los parámetros de un efecto, llama a setParameter()
y pasa el nombre y el valor del parámetro. Cada tipo de efecto acepta diferentes parámetros, que se documentan con el nombre del efecto. Por ejemplo, EFFECT_FISHEYE
tiene un parámetro para la scale
de la distorsión.
Para aplicar un efecto en una textura, llama a apply()
en Effect
y pasa la textura de entrada, su ancho y alto, y la textura de salida. La textura de entrada debe vincularse a una imagen de textura GL_TEXTURE_2D
(por lo general, se realiza mediante una llamada a la función glTexImage2D()
). 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 un elemento 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 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 a isEffectSupported()
.
Cliente de control remoto
El nuevo RemoteControlClient
permite que los reproductores multimedia habiliten los controles de reproducción desde clientes de control remoto, como la pantalla de bloqueo del dispositivo. Los reproductores multimedia también pueden mostrar información sobre el contenido multimedia que se está reproduciendo para mostrar en el control remoto, como la información de la pista y la imagen del álbum.
Si quieres habilitar los 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 qué entradas de control de contenido multimedia puede procesar tu reproductor, debes llamar a setTransportControlFlags()
en tu RemoteControlClient
y pasar 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á eventos ACTION_MEDIA_BUTTON
cuando se presione un botón desde un control remoto. El intent que recibes incluye el KeyEvent
para 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 el 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 obtener información sobre las claves disponibles, consulta las marcas METADATA_KEY_*
en MediaMetadataRetriever
.
Para ver una muestra de implementación, consulta el Reproductor de música aleatorio, que proporciona una lógica de compatibilidad de modo que habilita el cliente de control remoto en dispositivos Android 4.0 sin dejar de admitir dispositivos con Android 2.1.
Reproductor multimedia
- La transmisión de contenido multimedia en línea desde
MediaPlayer
ahora requiere el permisoINTERNET
. Si usasMediaPlayer
para reproducir contenido de Internet, asegúrate de agregar el permisoINTERNET
a tu manifiesto. De lo contrario, la reproducción de contenido multimedia no funcionará a partir de Android 4.0. setSurface()
te permite definir unSurface
para que se comporte como el 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 las solicitudes
Tipos de medios
Android 4.0 incorpora compatibilidad con lo siguiente:
- Versión 3 del protocolo de transmisión en vivo HTTP/HTTPS
- Codificación de audio AAC sin procesar ADTS
- Imágenes WEBP
- Video de Matroska
Para obtener más información, consulta los Formatos de medios compatibles.
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 un sujeto, sino 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
, que incluye un array de objetos Camera.Face
.
Una instancia de la clase Camera.Face
proporciona información variada sobre el rostro detectado, incluida la siguiente:
- Un objeto
Rect
que especifica los límites del rostro en relación con el campo visual 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 que te permite hacer el 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 llamar a getMaxNumDetectedFaces()
para verificarlo y asegurarte de que el valor que se muestra sea mayor que cero. Además, es posible que algunos dispositivos no admitan la identificación de ojos y boca. En ese caso, esos campos del 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 el enfoque 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 medir o enfocar. Una instancia de la clase Camera.Area
define los límites del área con un objeto 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 un área de medición, primero debes llamar a getMaxNumFocusAreas()
o getMaxNumMeteringAreas()
, respectivamente. Si muestran cero, el dispositivo no admite la función correspondiente.
Para especificar las áreas de enfoque o medición que se usarán, simplemente llame a setFocusAreas()
o setMeteringAreas()
. Cada una toma una List
de objetos Camera.Area
que indican las áreas que se deben tener en cuenta para el enfoque o la medición. Por ejemplo, puedes implementar una función que permita al usuario establecer el área de enfoque tocando un área de la vista previa, que luego traducirás a un objeto Camera.Area
y solicitará que la cámara enfoque esa área de la escena.
El enfoque o la exposición de esa área se actualizarán continuamente a medida que cambie el ambiente de la zona.
Enfoque automático continuo para fotos
Ahora puedes habilitar el enfoque automático continuo (CAF) al tomar fotos. Para habilitar el CAF en tu app de cámara, pasa FOCUS_MODE_CONTINUOUS_PICTURE
a setFocusMode()
. Cuando estés listo para tomar una foto, llama a autoFocus()
. Tu Camera.AutoFocusCallback
recibe una devolución de llamada de inmediato 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 aisVideoSnapshotSupported()
para asegurarte de que el hardware sea compatible. - Ahora puedes bloquear la exposición automática y el balance de blancos con
setAutoExposureLock()
ysetAutoWhiteBalanceLock()
para evitar que cambien estas propiedades. - Ahora puedes llamar a
setDisplayOrientation()
mientras se ejecuta la vista previa de la cámara. Anteriormente, solo podías llamar a este método antes de comenzar la vista previa, pero ahora puedes cambiar la orientación en cualquier momento.
Intents de transmisión de la cámara
Camera.ACTION_NEW_PICTURE
: Indica que el usuario capturó una foto nueva. La app de cámara integrada invoca esta emisión después de que se captura una foto, y las apps de cámara de terceros también deben transmitir este intent después de tomar una foto.Camera.ACTION_NEW_VIDEO
: Indica que el usuario capturó un video nuevo. La app de cámara integrada invoca esta transmisión 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 capturar un video.
Android Beam (NDEF Push con NFC)
Android Beam es una nueva función NFC que te permite enviar mensajes NDEF de un dispositivo a otro (un proceso también conocido como "NDEF Push"). La transferencia de datos se inicia cuando dos dispositivos Android compatibles con Android Beam se encuentran 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 Personas 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 dos maneras:
- Define un solo elemento
NdefMessage
para enviar mientras esté en la actividad:Llama a
setNdefPushMessage()
en cualquier momento para configurar el mensaje que deseas enviar. Por ejemplo, puedes llamar a este método y pasarle tuNdefMessage
durante el métodoonCreate()
de tu actividad. Luego, cada vez que Android Beam se activa con otro dispositivo mientras la actividad está en primer plano, el sistema envía elNdefMessage
al otro dispositivo. - Define el
NdefMessage
que se enviará en el momento en que se inicie Android Beam:Implementa
NfcAdapter.CreateNdefMessageCallback
, en el cual la implementación del métodocreateNdefMessage()
muestra elNdefMessage
que deseas enviar. Luego, pasa la implementación deNfcAdapter.CreateNdefMessageCallback
asetNdefPushMessageCallback()
.En este caso, cuando Android Beam se activa con otro dispositivo mientras tu actividad está en primer plano, el sistema llama a
createNdefMessage()
para recuperar elNdefMessage
que deseas enviar. Esto te permite definir elNdefMessage
para entregar solo una vez que se inicia Android Beam, en caso de que el contenido del mensaje varíe durante la vida de la actividad.
En caso de que desees ejecutar algún 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()
. Luego, el sistema llamará a onNdefPushComplete()
cuando se entregue el mensaje.
En el dispositivo receptor, el sistema envía mensajes push 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 de MIME configurado según el primer NdefRecord
de NdefMessage
. En la actividad a la que deseas responder, 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 quieres que tu NdefMessage
lleve un URI, ahora puedes usar el método útil createUri
para construir un nuevo NdefRecord
basado en una cadena o en 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, debes crear un filtro de intents para tu actividad mediante el uso del mismo esquema de URI a fin de recibir el mensaje NDEF entrante.
También debes pasar un "registro de aplicación para Android" con tu NdefMessage
a fin de garantizar que tu aplicación controle el mensaje NDEF entrante, incluso si otras aplicaciones filtran la misma acción de intent. Si deseas crear un registro de aplicación para Android, llama a createApplicationRecord()
y pásale el nombre del paquete de tu aplicación. Cuando el otro dispositivo recibe el mensaje NDEF con el registro de la aplicación y varias aplicaciones contienen actividades que manejan el intent especificado, el sistema siempre entrega el mensaje a la actividad de tu aplicación (en función del registro de aplicación coincidente). Si el dispositivo de destino no tiene instalada tu aplicación actualmente, el sistema utiliza el registro de la aplicación para Android a fin de iniciar Google Play y llevar al usuario a la aplicación a fin de instalarla.
Si tu aplicación no usa APIs de NFC para realizar mensajes push NDEF, Android proporciona un comportamiento predeterminado: cuando tu aplicación está en primer plano en un dispositivo y Android Beam se invoca con otro dispositivo Android, el otro dispositivo recibe un mensaje NDEF con un registro de aplicación para Android que identifica tu aplicación. Si el dispositivo receptor tiene la aplicación instalada, el sistema la inicia. Si no está instalada, Google Play se abre y lleva al usuario a tu aplicación para instalarla.
Puedes obtener más información sobre Android Beam y otras funciones de NFC en la guía para desarrolladores de Conceptos básicos de NFC. Para ver código de ejemplo con Android Beam, consulta la demostración de Android Beam.
P2P Wi-Fi
Android ahora admite conexiones Wi-Fi entre pares (P2P) entre dispositivos con Android y otros tipos de dispositivos (de acuerdo con el programa de certificación Wi-Fi DirectTM de Wi-Fi Alliance) sin un hotspot ni una conexión a Internet. El framework de Android proporciona un conjunto de APIs de P2P de Wi-Fi que te permiten descubrir otros dispositivos y conectarte a ellos cuando cada uno admite Wi-Fi P2P. Luego, se comunica a través de una conexión rápida a distancias mucho más largas que una conexión Bluetooth.
Un paquete nuevo, android.net.wifi.p2p
, contiene todas las APIs para realizar conexiones entre pares 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 varias interfaces y clases adicionales, como las siguientes:
- La interfaz
WifiP2pManager.ActionListener
te permite recibir devoluciones de llamada cuando una operación, como descubrir pares o conectarte a ellos, es correcta o falla. - La interfaz
WifiP2pManager.PeerListListener
te permite recibir información sobre los pares detectados. La devolución de llamada proporciona unWifiP2pDeviceList
, desde el cual puedes recuperar un objetoWifiP2pDevice
para cada dispositivo que esté dentro del rango y obtener información como el nombre, la dirección, el tipo de dispositivo y las configuraciones de WPS que admite el dispositivo, entre otros. - La interfaz
WifiP2pManager.GroupInfoListener
te permite recibir información sobre un grupo P2P. La devolución de llamada proporciona un objetoWifiP2pGroup
, que brinda información del grupo, como el propietario, el nombre de la red y la frase de contraseña. WifiP2pManager.ConnectionInfoListener
te permite recibir información sobre la conexión actual. La devolución de llamada proporciona un objetoWifiP2pInfo
, que contiene información como si se formó un grupo y quién es el propietario.
Para usar las APIs de P2P Wi-Fi, tu app debe solicitar los siguientes permisos de usuario:
ACCESS_WIFI_STATE
CHANGE_WIFI_STATE
INTERNET
(aunque técnicamente la app no se conecta a Internet, la comunicación con pares Wi-Fi P2P con sockets de Java estándar requiere permiso de Internet).
El sistema Android también transmite varias acciones diferentes durante ciertos eventos P2P Wi-Fi:
WIFI_P2P_CONNECTION_CHANGED_ACTION
: El estado de conexión P2P cambió. Esto llevaEXTRA_WIFI_P2P_INFO
con un objetoWifiP2pInfo
yEXTRA_NETWORK_INFO
con un objetoNetworkInfo
.WIFI_P2P_STATE_CHANGED_ACTION
: El estado P2P cambió de habilitado a inhabilitado. TransportaEXTRA_WIFI_STATE
conWIFI_P2P_STATE_DISABLED
oWIFI_P2P_STATE_ENABLED
.WIFI_P2P_PEERS_CHANGED_ACTION
: Cambió la lista de dispositivos de intercambio de tráfico.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION
: Cambiaron los detalles de este dispositivo.
Consulta la documentación de WifiP2pManager
para obtener más información. Observa también la aplicación de ejemplo de Demostración de P2P Wi-Fi.
Dispositivos Bluetooth de salud
Android ahora admite dispositivos de perfil de salud Bluetooth, por lo que puedes crear aplicaciones que utilizan Bluetooth para comunicarse con dispositivos de salud compatibles con Bluetooth, como monitores de frecuencia cardíaca, medidores de sangre, termómetros y balanzas.
Al igual que con los dispositivos de perfil A2DP y de auriculares normales, debes llamar a getProfileProxy()
con un BluetoothProfile.ServiceListener
y el tipo de perfil HEALTH
para establecer una conexión con el objeto de proxy de perfil.
Una vez que adquieras el proxy de perfiles de salud (el objeto BluetoothHealth
), la conexión con dispositivos de salud vinculados y la comunicación con ellos implica las siguientes clases de Bluetooth nuevas:
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 del canal de Bluetooth.BluetoothHealthAppConfiguration
: Durante las devoluciones de llamada a tuBluetoothHealthCallback
, recibirás una instancia de este objeto, que proporciona información de configuración sobre el dispositivo de estado Bluetooth disponible, que debes usar para realizar varias operaciones, como iniciar y finalizar conexiones con las APIs deBluetoothHealth
.
Para obtener más información sobre el uso del perfil de estado 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 táctil y las APIs extendidas que te permiten proporcionar más información sobre el contenido de las vistas o desarrollar servicios de accesibilidad avanzados.
Modo de exploración táctil
Los usuarios con pérdida de la visión ahora pueden explorar la pantalla tocando y arrastrando un dedo por la pantalla para escuchar las 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 los lectores de pantalla cuando el usuario navega con un pad direccional o una bola de seguimiento: con la lectura de la información que proporcionan android:contentDescription
y setContentDescription()
en un evento "desplazamiento" simulado. Por lo tanto, ten en cuenta que este es un recordatorio de 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 naturalmente.
Accesibilidad de las 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, se notifica a la vista respectiva con una llamada a sendAccessibilityEvent()
. Anteriormente, la implementación de sendAccessibilityEvent()
inicializaba un AccessibilityEvent
y lo enviaba a AccessibilityManager
. El nuevo comportamiento incluye algunos métodos de devolución de llamada adicionales que permiten que la vista y sus elementos superiores agreguen más información contextual al evento:
- Cuando se invocan, los métodos
sendAccessibilityEvent()
ysendAccessibilityEventUnchecked()
difieren aonInitializeAccessibilityEvent()
.Es posible que las implementaciones personalizadas de
View
quieran implementaronInitializeAccessibilityEvent()
para adjuntar información de accesibilidad adicional aAccessibilityEvent
, pero también deben llamar a la superimplementación para proporcionar información predeterminada, como la descripción de contenido estándar, el índice de elementos, etc. Sin embargo, no debes agregar contenido de texto adicional en esta devolución de llamada, ya que eso sucede a continuación. - Una vez inicializado, si el evento es uno de los varios tipos que deben propagarse con información de texto, la vista recibe una llamada a
dispatchPopulateAccessibilityEvent()
, que difiere de la devolución de llamadaonPopulateAccessibilityEvent()
.Por lo general, las implementaciones personalizadas de
View
deben implementaronPopulateAccessibilityEvent()
para agregar contenido de texto adicional aAccessibilityEvent
si falta el textoandroid:contentDescription
o si es insuficiente. Para agregar más descripciones de texto aAccessibilityEvent
, llama agetText()
.add()
. - En este punto,
View
pasa el evento por la jerarquía de vistas llamando arequestSendAccessibilityEvent()
en la vista superior. Cada vista superior tiene la oportunidad de aumentar la información de accesibilidad agregando unAccessibilityRecord
hasta llegar a la vista raíz, que envía el evento alAccessibilityManager
consendAccessibilityEvent()
.
Además de los métodos nuevos anteriores, que son útiles cuando se extiende 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 haces, 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 no controle el delegado se devuelve directamente a la vista para obtener 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, admitir las nuevas APIs de accesibilidad, puedes hacerlo con la versión más reciente de la biblioteca de compatibilidad v4 (en Paquete de compatibilidad, r4) mediante un conjunto de clases de utilidades que proporcionen las nuevas APIs de accesibilidad en un diseño retrocompatible.
Servicios de accesibilidad
Si estás desarrollando un servicio de accesibilidad, la información sobre varios eventos de accesibilidad se expandió significativamente a fin de habilitar comentarios sobre accesibilidad más avanzados para los usuarios. En particular, los eventos se generan según la composición de las vistas, lo que proporciona mejor información de contexto y permite que los servicios de accesibilidad recorran jerarquías de vistas para obtener información de vistas adicional y manejar casos especiales.
Si estás desarrollando un servicio de accesibilidad (como un lector de pantalla), puedes acceder a información adicional de contenido y recorrer jerarquías de vistas con el siguiente procedimiento:
- Cuando recibas un
AccessibilityEvent
de una aplicación, llama aAccessibilityEvent.getRecord()
para recuperar unAccessibilityRecord
específico (puede haber varios registros adjuntos al evento). - Desde
AccessibilityEvent
o unAccessibilityRecord
individual, puedes llamar agetSource()
para recuperar un objetoAccessibilityNodeInfo
.Un
AccessibilityNodeInfo
representa un nodo único del contenido de la ventana en un formato que te permite consultar información de accesibilidad sobre ese nodo. El objetoAccessibilityNodeInfo
que muestraAccessibilityEvent
describe la fuente del evento, mientras que la fuente de unaAccessibilityRecord
describe el predecesor de la fuente del evento. - Con la
AccessibilityNodeInfo
, puedes consultar información sobre ella, llamar agetParent()
ogetChild()
para desviar la jerarquía de vistas o incluso 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
. Si quieres 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 de XML.
Otras APIs de accesibilidad
Si te interesa el estado de accesibilidad del dispositivo, AccessibilityManager
tiene algunas APIs nuevas, como las siguientes:
AccessibilityManager.AccessibilityStateChangeListener
es una interfaz que te permite recibir una devolución de llamada cada vez que la accesibilidad está habilitada o inhabilitada.getEnabledAccessibilityServiceList()
proporciona información sobre los servicios de accesibilidad que están habilitados en este momento.isTouchExplorationEnabled()
te indica si el modo de exploración táctil está habilitado.
Servicios de corrector ortográfico
Un nuevo framework del corrector ortográfico permite que las apps creen correctores ortográficos de manera similar al framework del método de entrada (para IME). Para crear un nuevo corrector ortográfico, debes implementar un servicio que extienda SpellCheckerService
y extender la clase SpellCheckerService.Session
para proporcionar sugerencias ortográficas basadas en el texto proporcionado por los métodos de devolución de llamada de la interfaz. En los métodos de devolución de llamada SpellCheckerService.Session
, debes mostrar las sugerencias de ortografía 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 incluir un elemento <meta-data>
que declare la información de configuración del corrector ortográfico.
Consulta la app de muestra del Servicio del corrector ortográfico y la del Cliente del 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 extendieron de manera significativa 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 un par de 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 proporcionado por el sistema o configurar un motor personalizado con setEngineByPackageName()
. En Android 4.0, el método setEngineByPackageName()
dejó de estar disponible y ahora puedes especificar el motor para usar con un nuevo constructor TextToSpeech
que acepte 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 incluye metadatos, como el ícono, la etiqueta y el nombre del paquete del motor.
Cómo crear motores de texto a voz
Antes, los motores personalizados requerían que el motor se compilara con un archivo de encabezado nativo sin documentar. En Android 4.0, existe un conjunto completo de APIs de 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 ocurre durante la devolución de llamada onSynthesizeText()
, en un servicio que extiende TextToSpeechService
. A este método, el sistema le entrega dos objetos:
SynthesisRequest
: Contiene varios datos, incluidos el texto que se sintetizará, la configuración regional, la velocidad de voz y el tono de voz.SynthesisCallback
: Esta es la interfaz por la que tu motor de TTS entrega los datos de voz resultantes como audio de transmisión. Primero, el motor debe llamar astart()
para indicar que está listo para entregar el audio. Luego, debe llamar aaudioAvailable()
y pasarle los datos de audio en un búfer de bytes. Una vez que el motor pase todo el audio a través del búfer, llama adone()
.
Ahora que el framework admite una verdadera API 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 puedes usar para convertir tus motores de TTS antiguos al nuevo marco de trabajo.
Para ver un ejemplo de motor de TTS con las nuevas APIs, consulta la app de ejemplo Text to Speech Engine.
Uso de red
Android 4.0 brinda a los usuarios una visibilidad precisa de la cantidad de datos de red que usan sus aplicaciones. La app de Configuración proporciona controles que permiten a los usuarios administrar límites establecidos para el uso de datos de red e incluso inhabilitar el uso de datos en segundo plano para apps individuales. Para evitar que los usuarios inhabiliten el acceso de tu app a los datos en segundo plano, debes desarrollar estrategias para usar la conexión de datos de manera eficiente y ajustar tu uso según el tipo de conexión disponible.
Si tu aplicación realiza muchas transacciones de red, debes proporcionar una configuración de usuario que permita a los usuarios controlar los hábitos de datos de tu app, como la frecuencia con la que tu app sincroniza datos, si realiza cargas o descargas solo cuando hay una conexión Wi-Fi, si usa datos con 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, en cambio, usar la app con precisión.
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 el uso de datos de tu aplicación. Por lo tanto, cuando el usuario inspecciona cuántos datos usa tu app desde la app de Configuración, aparece un botón "Ver la configuración de la aplicación" que inicia tu actividad de preferencias para que el usuario pueda definir mejor cuántos datos usa tu app.
Además, ten en cuenta que getBackgroundDataSetting()
ahora es obsoleto y siempre muestra un valor verdadero; en su lugar, usa getActiveNetworkInfo()
. Antes de intentar realizar cualquier transacción 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 conexión. Luego, puedes verificar otras propiedades de la conexión, como si el dispositivo está en roaming o conectado a Wi-Fi.
Enterprise
Android 4.0 expande las capacidades de las aplicaciones empresariales con las siguientes funciones.
Servicios de VPN
La nueva 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 una red virtual con su propia dirección y reglas de enrutamiento, y realiza toda la lectura y escritura con un descriptor de archivo.
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 termines, podrás establecer la interfaz llamando a establish()
, que muestra un ParcelFileDescriptor
.
Debido a que un servicio de VPN puede interceptar paquetes, existen implicaciones de seguridad. Por lo tanto, si implementas VpnService
, tu servicio debe requerir el BIND_VPN_SERVICE
para garantizar que solo el sistema pueda vincularse a él (solo al sistema se le otorga este permiso; las apps no pueden solicitarlo). Para luego usar tu 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 usando setCameraDisabled()
y la propiedad USES_POLICY_DISABLE_CAMERA
(aplicada con un elemento <disable-camera />
en el archivo de configuración de políticas).
Administración de certificados
La nueva clase KeyChain
proporciona APIs que te permiten importar certificados en el almacén de claves del sistema y acceder a ellos. Los certificados optimizan la instalación de los certificados de cliente (para validar la identidad del usuario) y de los certificados de autoridad certificadora (para verificar la identidad del servidor). Las aplicaciones como navegadores web o clientes de correo electrónico pueden acceder a los certificados instalados para autenticar a los usuarios en los servidores. Consulta la documentación de KeyChain
para obtener más información.
Sensores de dispositivos
En Android 4.0, se agregaron dos tipos de sensores nuevos:
TYPE_AMBIENT_TEMPERATURE
: Un sensor de temperatura que proporciona la temperatura ambiente (de la habitación) en grados Celsius.TYPE_RELATIVE_HUMIDITY
: Es un sensor de humedad que proporciona la humedad relativa del ambiente (habitación) en forma de 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
, dejó de estar disponible. En su lugar, debes usar el sensor TYPE_AMBIENT_TEMPERATURE
.
Además, se mejoraron mucho los tres sensores sintéticos de Android, por lo que ahora tienen una latencia más baja y resultados más fluidos. 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 sensor del giroscopio para mejorar su salida, de modo que solo aparecen en dispositivos que tienen giroscopio.
Barra de acciones
Se actualizó ActionBar
para admitir varios comportamientos nuevos. 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 el teléfono está en orientación vertical), las pestañas de navegación de la barra de acciones aparecen en una "barra apilada", que aparece directamente debajo de la barra de acciones principal. También puedes habilitar una "barra de acciones dividida", que ubica todos los elementos de acción en una barra independiente en la parte inferior de la pantalla cuando la pantalla está angosta.
Barra de acciones dividida
Si la barra de acciones incluye varios elementos de acción, no todos entrarán en la barra de acciones en una pantalla estrecha, por lo que el sistema colocará más elementos en el menú ampliado. Sin embargo, Android 4.0 te permite habilitar la "barra de acciones dividida" para que puedan aparecer más elementos de acción en la pantalla en una barra separada en la parte inferior. Para habilitar la barra de acciones dividida, agrega android:uiOptions
con "splitActionBarWhenNarrow"
a la etiqueta <application>
o a las etiquetas <activity>
individuales en el archivo de manifiesto. Cuando se habilite, el sistema agregará una barra adicional en la parte inferior de la pantalla para todos los elementos de acción cuando la pantalla esté angosta (no aparecerá ningún elemento 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 las pestañas aparezcan en la parte superior), habilita la barra de acciones dividida como se describió anteriormente y 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 acciones principal, desaparece. Todo lo 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 elemento de diseño o color de fondo a la barra apilada y a la barra dividida, respectivamente. También puedes configurar estos diseños en el tiempo de ejecución con setStackedBackgroundDrawable()
y setSplitBackgroundDrawable()
.
Proveedor de acciones
La nueva clase ActionProvider
te permite crear un controlador especializado para los 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 con 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 acciones. En lugar de usar un 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 controlan el intent ACTION_SEND
. Cuando el usuario selecciona una aplicación para usar en la acción, ShareActionProvider
recuerda esa selección y la proporciona en la vista de acción para un acceso más rápido a la acción compartida con esa app.
Si quieres 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 desde el elemento de menú y configura 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 que use ShareActionProvider
, consulta ActionBarShareActionProviderActivity en ApiDemos.
Vistas de acciones 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 la contracción SearchView
cuando se usaba como vista de acción, pero ahora puedes agregar una vista de acción para cualquier elemento de acción y alternar entre el estado expandido (la vista de acción es visible) y el estado contraído (el elemento de acción es visible).
Para declarar que un elemento de acción que contiene una vista de acción se puede contraer, 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 cambia entre expandida y contraída, registra una instancia de MenuItem.OnActionExpandListener
con el MenuItem
correspondiente llamando a setOnActionExpandListener()
. Por lo general, debes hacerlo durante la devolución de llamada onCreateOptionsMenu()
.
Para controlar una vista de acción que se puede contraer, puedes llamar a collapseActionView()
y expandActionView()
en el MenuItem
correspondiente.
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 se contrae.
Otras APIs para la barra de acciones
setHomeButtonEnabled()
te permite especificar si el ícono o logotipo se comporta como un botón para navegar a la página principal o "hacia arriba" (pasa "true" a fin de que se comporte como un botón).setIcon()
ysetLogo()
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 inhabilitar la visibilidad de los elementos del menú de opciones que declara el fragmento. Esto es útil si el fragmento se agregó a la actividad, pero no es visible, por lo que los elementos de menú deberían estar ocultos.FragmentManager.invalidateOptionsMenu()
te permite invalidar el menú de opciones de la actividad durante varios estados del ciclo de vida del fragmento en los que el uso del método equivalente deActivity
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 las vistas secundarias en una cuadrícula rectangular. A diferencia de TableLayout
, GridLayout
se basa en una jerarquía plana y no utiliza vistas intermedias, como filas de tablas, para proporcionar la estructura.
En cambio, los elementos secundarios especifican qué filas y columnas deben ocupar (las celdas pueden abarcar varias filas o columnas) y, de forma predeterminada, se disponen de forma secuencial en las filas y columnas de la cuadrícula.
La orientación GridLayout
determina si los elementos secundarios secuenciales se disponen de forma horizontal o vertical de forma predeterminada. El espacio entre los elementos secundarios se puede especificar mediante instancias de la nueva vista Space
o mediante la configuración de los parámetros de margen relevantes en los elementos secundarios.
Consulta ApiDemos para ver ejemplos 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 porque se comporta como una vista normal, en lugar de crear una ventana independiente, por lo que puedes tratarlo como cualquier otro objeto View
. Por ejemplo, puedes aplicar transformaciones, animarlas 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 botón de activación de dos estados que los usuarios pueden arrastrar a un lado o al otro (o simplemente presionarlo) para activar o desactivar una opción entre dos estados.
Puedes usar los atributos android:textOn
y android:textOff
para especificar el texto que aparecerá en el interruptor cuando esté activada o desactivada. El atributo android:text
también te permite colocar una etiqueta junto al interruptor.
Para ver un ejemplo del uso de interruptores, consulta el archivo de diseño switches.xml y la actividad correspondiente de Switches .
Menús emergentes
Android 3.0 introdujo PopupMenu
para crear menús contextuales cortos que aparecen en el punto de anclaje que especificas (por lo general, en el punto del elemento seleccionado). Android 4.0 amplía 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 de menú. - Ahora 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 las preferencias que proporcionan una opción de selección de dos estados. El nuevo SwitchPreference
es una extensión de TwoStatePreference
que proporciona un widget de 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 Configuración usa un SwitchPreference
para los ajustes de Wi-Fi y Bluetooth.
Temas del sistema
El tema predeterminado para todas las aplicaciones que se orientan a Android 4.0 (estableciendo targetSdkVersion
o minSdkVersion
en “14"
o una versión posterior) ahora es el tema "predeterminado del dispositivo": Theme.DeviceDefault
. Puede ser el tema oscuro de Holo o un tema oscuro diferente definido por el dispositivo específico.
Se garantiza que la familia de temas Theme.Holo
no cambiará de un dispositivo a otro cuando se ejecute la misma versión de Android. Si aplicas explícitamente cualquiera de los temas Theme.Holo
a tus actividades, puedes estar seguro de que no cambiarán de carácter en diferentes dispositivos dentro de la misma versión de la plataforma.
Si deseas que tu app se integre con el tema general del dispositivo (por ejemplo, cuando diferentes OEM proporcionan diferentes temas predeterminados para el sistema), debes aplicar explícitamente temas de la familia Theme.DeviceDefault
.
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 un botón de menú en pantalla en las apps diseñadas para versiones anteriores de Android.
Para brindar la mejor experiencia del usuario, las apps nuevas y actualizadas deben usar ActionBar
para proporcionar acceso a los elementos de menú y establecer targetSdkVersion
en "14"
para aprovechar los comportamientos predeterminados más recientes del framework.
Controles para la visibilidad de la IU del sistema
Desde los inicios de Android, el sistema ha administrado un componente de la IU conocido como la barra de estado, que se encuentra en la parte superior de los teléfonos celulares para enviar información, como la señal del proveedor, la hora, las notificaciones, etc. Android 3.0 agregó la barra del sistema para tablets, que se encuentra en la parte inferior de la pantalla para proporcionar controles de navegación del sistema (Inicio, Atrás, etc.) y también una interfaz para elementos que tradicionalmente proporciona la barra de estado. En Android 4.0, el sistema proporciona un nuevo tipo de IU del sistema llamado barra de navegación. Podrías considerar la barra de navegación como una versión reajustada de la barra del sistema diseñada para teléfonos celulares: proporciona controles de navegación para dispositivos que no tienen equivalentes de hardware para navegar por el sistema, pero omite la IU de notificaciones de la barra del sistema y los controles de configuración. 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 los teléfonos celulares mediante la marca FLAG_FULLSCREEN
. En Android 4.0, las APIs que controlan la visibilidad de la barra del sistema se actualizaron para reflejar mejor el comportamiento de la barra del sistema y de la barra de navegación:
- La marca
SYSTEM_UI_FLAG_LOW_PROFILE
reemplaza a la marcaSTATUS_BAR_HIDDEN
. Cuando se establece, esta marca habilita el modo de "perfil bajo" para la barra del sistema o de navegación. Los botones de navegación se atenúan y también se ocultan otros elementos de la barra del sistema. Habilitar esta opción es útil para crear juegos más envolventes sin distracciones de los botones de navegación del sistema. - La marca
SYSTEM_UI_FLAG_VISIBLE
reemplaza a la marcaSTATUS_BAR_VISIBLE
para solicitar que la barra del sistema o la barra de navegación sean visibles. SYSTEM_UI_FLAG_HIDE_NAVIGATION
es una marca nueva que solicita que la barra de navegación se oculte por completo. Ten en cuenta que esta opción 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 visualizarse en cuanto el sistema recibe las entradas del usuario. Por lo tanto, este modo es útil principalmente para la reproducción de video o en otros casos en los que se necesita toda la pantalla, pero no se requiere la entrada del usuario.
Puedes configurar 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) todas las marcas de todas las vistas de tu ventana y las aplica a la IU del sistema, siempre que esta tenga foco de entrada. Cuando la ventana pierde el enfoque de entrada (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, sus marcas dejarán de aplicarse.
Para sincronizar otros eventos en 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 de la barra de navegación.
Consulta la clase OverscanActivity para ver una demostración de las diferentes opciones de IU del sistema.
Framework de entrada
Android 4.0 agrega compatibilidad para eventos de desplazamiento del cursor y nuevos eventos de la pluma stylus y del botón del mouse.
Eventos de colocar el cursor sobre un elemento
La clase View
ahora admite eventos de "desplazamiento" para habilitar interacciones más enriquecidas mediante dispositivos de puntero (como un mouse u otros dispositivos que manejan un cursor en pantalla).
Para recibir eventos de colocar el cursor sobre una vista, implementa View.OnHoverListener
y regístralo con setOnHoverListener()
. Cuando se produce un evento de desplazamiento en la vista, el objeto de escucha recibe una llamada a onHover()
y proporciona el View
que recibió el evento y un MotionEvent
que describe el tipo de evento de desplazamiento que ocurrió. El evento de colocar el cursor sobre un elemento puede ser uno de los siguientes:
Tu View.OnHoverListener
debería mostrar un valor verdadero desde onHover()
si controla el evento de colocar el cursor sobre él. Si el objeto de escucha muestra el valor "false", 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 proporcionar un elemento de diseño en segundo plano diferente cuando un cursor se coloca sobre la vista.
Para ver una demostración de los nuevos eventos de colocar el cursor sobre un elemento, consulta la clase Hover en ApiDemos.
Eventos de la pluma stylus y del botón del mouse
Android ahora proporciona APIs para recibir entradas de un dispositivo de entrada de pluma stylus, como un periférico de tablet digitalizador o una pantalla táctil compatible con la pluma stylus.
La entrada de la pluma stylus funciona de manera similar a la entrada táctil o del mouse. Cuando la pluma stylus está en contacto con el digitalizador, las aplicaciones reciben eventos táctiles del mismo modo que lo harían cuando se usa un dedo para tocar la pantalla. Cuando la pluma stylus se coloca por encima del digitalizador, las aplicaciones reciben eventos de desplazamiento del mismo modo que lo harían cuando se mueve un puntero del mouse por la pantalla cuando no se presiona ningún botón.
Tu aplicación puede distinguir entre la entrada de dedo, mouse, pluma stylus y borrador consultando el "tipo de herramienta" asociado 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
. Si se consulta el tipo de herramienta, tu aplicación puede elegir controlar la entrada de la pluma stylus de diferentes maneras, desde la entrada con el dedo o el mouse.
Tu aplicación también puede consultar qué botones del mouse o de la pluma stylus se presionan con una consulta del "estado del botón" de un MotionEvent
con getButtonState()
. Los estados de los botones definidos actualmente son: BUTTON_PRIMARY
, BUTTON_SECONDARY
, BUTTON_TERTIARY
, BUTTON_BACK
y BUTTON_FORWARD
. Para mayor comodidad, los botones para retroceder y avanzar del mouse se asignan automáticamente a las teclas KEYCODE_BACK
y KEYCODE_FORWARD
. Tu aplicación puede controlar estas teclas para admitir la navegación hacia atrás y hacia adelante basada en el botón del mouse.
Además de medir con precisión la posición y la presión de un contacto, algunos dispositivos de entrada de la pluma stylus también informan la distancia entre la punta de la pluma stylus y el digitalizador, el ángulo de inclinación y el ángulo de orientación de la pluma stylus. Tu aplicación puede consultar esta información mediante 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 manera rápida, eficiente y fácil de especificar una propiedad en cualquier objeto que permite que los emisores establezcan o obtengan valores de forma genérica en los objetos de destino. También permite la funcionalidad de pasar referencias de campo o método y permite que el código establezca o obtenga valores de la propiedad sin conocer los detalles de los campos o métodos.
Por ejemplo, si deseas establecer el valor del campo bar
en el objeto foo
, antes harías esto:
Kotlin
foo.bar = value
Java
foo.bar = value;
Si deseas llamar al método set para un campo privado subyacente bar
, antes harías lo siguiente:
Kotlin
foo.setBar(value)
Java
foo.setBar(value);
Sin embargo, si deseas pasar la instancia de foo
y establecer algún otro código en el valor bar
, no hay manera de hacerlo antes de Android 4.0.
Con la clase Property
, puedes declarar un objeto Property
BAR
en la clase Foo
de modo que puedas configurar 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 establecer varios campos, como las propiedades de transformación que se agregaron en Android 3.0 (ROTATION
, ROTATION_X
, TRANSLATION_X
, etcétera).
La clase ObjectAnimator
también usa la clase Property
, por lo que puedes crear un ObjectAnimator
con un Property
, que es más rápido, eficiente y seguro que el enfoque basado en strings.
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 estableció targetSdkVersion
o minSdkVersion
en “14"
o una versión posterior. Por lo general, la aceleración de hardware da como resultado animaciones y desplazamientos más fluidos, además de un mejor rendimiento y una respuesta a la interacción del usuario en general.
Si es necesario, puedes inhabilitar manualmente la aceleración de hardware con el atributo hardwareAccelerated
para elementos <activity>
individuales o el elemento <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 las operaciones de dibujo no compatibles, 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 era un problema siempre que el recolector de elementos no utilizados no moviera objetos, pero parecía funcionar, ya que permitía escribir código con errores. En Android 4.0, el sistema ahora usa referencias indirectas para detectar estos errores.
Los pormenores de las referencias locales de JNI se describen en la sección “Referencias locales y globales” de la sección Sugerencias de JNI. En Android 4.0, CheckJNI se mejoró para detectar estos errores. Mira el Blog para desarrolladores de Android a fin de encontrar una próxima publicación sobre errores comunes con las referencias de JNI y cómo solucionarlos.
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 una versión posterior. Si configuraste estos atributos en un valor inferior, las referencias locales de JNI se comportan de la misma manera que en versiones anteriores.
WebKit
- WebKit se actualizó a la versión 534.30
- Compatibilidad con fuentes índicas (devanagari, bengalí y tamil, incluida la compatibilidad con caracteres complejos que se necesitan para combinar glifos) en
WebView
y el navegador integrado - Compatibilidad con fuentes etíopes, georgianas y armenias en
WebView
y en el navegador integrado - La compatibilidad con WebDriver te permite probar con mayor facilidad apps que usan
WebView
Navegador Android
La aplicación Navegador agrega las siguientes funciones para admitir aplicaciones web:
- Compilador de JavaScript V8 actualizado para un rendimiento más rápido
- Además, ahora están disponibles otras mejoras notables transferidas de Android 3.0 para teléfonos:
- Compatibilidad con elementos de posición fija en todas las páginas
- Captura de medios HTML
- Eventos de orientación del dispositivo
- Transformaciones CSS 3D
Permisos
Los siguientes son permisos nuevos:
ADD_VOICEMAIL
: Permite que un servicio de buzón de voz agregue mensajes de voz al dispositivo.BIND_TEXT_SERVICE
: Un servicio que implementaSpellCheckerService
debe requerir este permiso para sí mismo.BIND_VPN_SERVICE
: Un servicio que implementaVpnService
debe requerir este permiso para sí mismo.- android.Manifest.permission#READ_PROFILE: Proporciona acceso de lectura al proveedor
ContactsContract.Profile
. - android.Manifest.permission#WRITE_PROFILE: Proporciona acceso de escritura al proveedor
ContactsContract.Profile
.
Funciones del dispositivo
Las siguientes son funciones nuevas del dispositivo:
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 la API 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 naturalmente admite todas las API de versiones anteriores. Debido a que la plataforma Android 3.x solo está disponible para dispositivos de pantalla grande, si desarrollaste principalmente para teléfonos celulares, es posible que no estés al tanto de todas las APIs agregadas a Android en estas versiones recientes.
A continuación, te mostramos algunas de las APIs más destacadas que quizás te perdiste y que ahora también están disponibles 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 guía para desarrolladores de Fragments.ActionBar
: Es un reemplazo de la barra de título tradicional en la parte superior de la ventana de actividades. Incluye el logotipo de la aplicación en la esquina izquierda y proporciona una nueva interfaz para los elementos de menú. Consulta la guía para desarrolladores sobre la Barra de acciones.Loader
: Es un componente del framework que facilita la carga asíncrona de datos en combinación con los componentes de la IU para cargar datos de forma dinámica sin bloquear el subproceso principal. Consulta la guía para desarrolladores sobre cargadores.- Portapapeles del sistema: Las aplicaciones pueden copiar y pegar datos (más allá del mero 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 la vista que facilita las operaciones de arrastrar y soltar. Consulta la guía para desarrolladores sobre Arrastrar y soltar.
- Un framework de animación flexible nuevo te permite animar propiedades arbitrarias de cualquier objeto (vista, elemento de diseño, fragmento, objeto o cualquier otro) y definir aspectos de animación, como duración, interpolación, repetición y mucho más. El nuevo framework hace que las animaciones de Android sean más fáciles que nunca. Consulta la guía para desarrolladores sobre Animación de propiedades.
- Gráficos y Compute Engine de RenderScript: RenderScript ofrece una API de procesamiento y renderización de gráficos 3D de alto rendimiento en el nivel nativo, que se escribe en C (estándar C99), lo que proporciona el tipo de rendimiento que esperas de un entorno nativo, sin dejar de ser portátil en varias CPU y GPU. Consulta la guía para desarrolladores de RenderScript.
- Gráficos 2D acelerados por hardware: Ahora puedes habilitar el procesador OpenGL para tu aplicación configurando {android:hardwareAccelerated="true"} en el elemento
<application>
del manifiesto o para elementos<activity>
individuales. De esta manera, se obtienen animaciones y desplazamientos más fluidos, además de un mejor rendimiento y una respuesta a la interacción del usuario en general.Nota: Si configuras
minSdkVersion
otargetSdkVersion
de tu aplicación en"14"
o un valor superior, la aceleración de hardware se habilita de forma predeterminada. - Y mucho, mucho más. Consulta las notas de la Plataforma Android 3.0 para obtener más información.
- Android 3.1
-
- APIs de USB: APIs nuevas y potentes para integrar periféricos conectados con aplicaciones para Android Las APIs se basan en una pila USB y en servicios integrados en la plataforma, incluida la compatibilidad con interacciones de dispositivos y hosts USB. Consulta la guía para desarrolladores sobre hosts y accesorios USB.
- APIs de MTP/PTP: Las aplicaciones pueden interactuar directamente con las cámaras conectadas y otros dispositivos PTP para recibir notificaciones cuando se conectan y quitan dispositivos, administrar archivos y el almacenamiento en esos dispositivos, y transferir archivos y metadatos desde y hacia ellos. La API de MTP implementa el subconjunto de PTP (Protocolo de transferencia de imágenes) de la especificación de MTP (Protocolo de transferencia de medios). Consulta la documentación de
android.mtp
. - APIs de RTP: Android expone una API a su pila de RTP (protocolo de transporte en tiempo real) integrada, que las aplicaciones pueden usar para administrar la transmisión de datos interactiva o a pedido. En particular, las apps que proporcionan VoIP, enviar para hablar, conferencias y transmisión de audio pueden usar la API a fin de 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 API nuevas.
- Android 3.2
-
- Las nuevas pantallas 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 la capacidad de orientarse con precisión a rangos de tamaño de pantalla específicos por dimensiones, medidas en unidades de píxeles independientes de la densidad (como 600 dp o 720 dp de ancho), en lugar de sus tamaños generalizados (como grande o extragrande). Por ejemplo, esto es importante para ayudarte a distinguir entre un dispositivo de 5" y un dispositivo de 7, que tradicionalmente se agruparían como pantallas "grandes". Consulta la entrada de blog New Tools for Managing Screen Sizes.
- Nuevas constantes para que
<uses-feature>
declare los requisitos de orientación de pantalla horizontal o vertical. - La configuración de "tamaño de pantalla" del dispositivo ahora cambia durante un cambio de orientación de la pantalla. Si tu app está orientada al nivel de API 13 o superior, debes controlar el cambio de configuración de
"screenSize"
si también deseas controlar el cambio de configuración de"orientation"
. Consultaandroid:configChanges
para obtener más información. - Consulta las notas de la Plataforma 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 propio sistema. Este identificador, denominado "nivel de API", permite que el sistema determine correctamente si una aplicación es compatible con él antes de instalarla.
Para usar las APIs que se introdujeron en Android 4.0 en tu aplicación, deberás compilarla en 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?