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 actualización importante de la plataforma porque incluye el amplio conjunto de APIs 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: 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 biblioteca de Android, una imagen del sistema, un conjunto de máscaras de emulador y mucho 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 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 que los usuarios inviten a 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 una identidad de usuario pueden contribuir a los datos de perfil del usuario 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 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 al perfil único visible para el usuario etiquetado como “Yo”.
Agregar un nuevo contacto sin procesar para el perfil requiere el permiso android.Manifest.permission#WRITE_PROFILE. Del mismo modo, para leer desde la tabla de perfil, debes solicitar el permiso android.Manifest.permission#READ_PROFILE. Sin embargo, la mayoría de las apps no necesitan leer el perfil del usuario, incluso cuando se contribuyen datos al perfil. La lectura del perfil de usuario es un permiso sensible, y debes esperar que los usuarios sean escépticos sobre las apps que lo solicitan.
Intención de invitación
La acción de intent INVITE_CONTACT
permite que una app invoque una acción que indique 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 integrada de Personas invoca el intent de invitación cuando el usuario selecciona "Agregar conexión" para una app social específica que se muestra 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 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 x 96 (como lo hacía anteriormente) 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 podrían 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.
Comunicarse con los comentarios sobre el uso
Las nuevas APIs de ContactsContract.DataUsageFeedback
te permiten hacer un seguimiento de la frecuencia con la que el usuario utiliza métodos particulares 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 a 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 atractivos son los adaptadores de sincronización que sincronizan el calendario del usuario de otros servicios 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 de Calendario de Google sincroniza los eventos de Calendario de Google con el proveedor de calendario, lo que permite que estos eventos se puedan ver con la app de Calendario integrada de Android.
El modelo de datos para calendarios y la información relacionada con eventos en el Proveedor de calendario se define mediante CalendarContract
. 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, etcétera. 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 correspondan a los distintos casos de ese evento. - La tabla
CalendarContract.Attendees
contiene la información del asistente al evento o de los invitados. Cada fila representa un solo invitado a un evento. Especifica el tipo de invitado que es la persona y la respuesta de esta 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 establece el adaptador de sincronización propietario del calendario determinado. Los recordatorios se especifican en minutos antes de la programación del evento y también establecen 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 de 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 quieres 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 crea 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
: Hora de inicio del evento en milisegundos desde la épocaCalendarContract.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 va a invitarEvents.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 programar otros eventos 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 otras de VoIP, o bien otros servicios de voz alternativos. Estas apps pueden usar las APIs de Buzón de voz para agregar sus mensajes de voz al dispositivo. Luego, la aplicación integrada de teléfono 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 aplicación 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 las APIs actualmente 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 las 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. Si quieres ver un ejemplo de una app del proveedor de buzón de voz, consulta la Demostración del proveedor de buzón de voz.
Multimedia
En Android 4.0, se agregan 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 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 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 mipmaps
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
EffectContext
que se muestra para llamar aEffectContext.getFactory()
, que muestra una instancia deEffectFactory
. - Llama a
createEffect()
y pásale un nombre de efecto de @link android.media.effect.EffectFactory}, comoEFFECT_FISHEYE
oEFFECT_VIGNETTE
.
Para ajustar los parámetros de un efecto, llama a setParameter()
y pasa un nombre y un 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 el scale
de la distorsión.
Para aplicar un efecto a 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 mipmaps. Si la textura de salida no se vinculó a una imagen de textura, quedará vinculada automáticamente por el efecto como una 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 en 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 portada 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 una 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 controlar el 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 en el control remoto información 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 implementación de muestra, consulta el reproductor de música aleatorio, que brinda una lógica de compatibilidad de modo que habilita el cliente de control remoto en dispositivos con 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 para 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 Formatos multimedia 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 habilidades 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 la 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, incluido lo 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 qué tan seguro está el sistema de que el objeto es un rostro humano
- Un ID único para que puedas 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 deberías llamar a getMaxNumDetectedFaces()
para verificarlo y asegurarte de que el valor que se muestra sea superior a cero. Además, es posible que algunos dispositivos no admitan la identificación de los ojos y la 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 usa la cámara 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 enfocar o medir. Una instancia de la clase Camera.Area
define los límites del área con un valor de Rect
y el peso del área, lo 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 muestran cero, el dispositivo no admite la función correspondiente.
Para especificar las áreas de enfoque o medición que deseas usar, simplemente llama a setFocusAreas()
o setMeteringAreas()
. Cada uno 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 en 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 las fotos
Ahora puedes habilitar el enfoque automático continuo (CAF) cuando tomas fotos. Para habilitar el CAF en tu app de cámara, pasa FOCUS_MODE_CONTINUOUS_PICTURE
a setFocusMode()
. Cuando estés listo para capturar 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. Antes de hacerlo, debes llamar aisVideoSnapshotSupported()
para asegurarte de que el hardware lo admita. - Ahora puedes bloquear la exposición automática y el balance de blancos con
setAutoExposureLock()
ysetAutoWhiteBalanceLock()
para evitar que estas propiedades cambien. - 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 transmisió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 capturar 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 con Android que admiten Android Beam se encuentran cerca (aproximadamente 4 cm) y, por lo general, con la parte trasera en contacto. Los datos dentro del mensaje NDEF pueden contener cualquier dato que desees compartir entre dispositivos. Por ejemplo, la app Personas comparte contactos, YouTube comparte videos y el navegador comparte URL 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 estas dos maneras:
- Define un solo
NdefMessage
para enviar durante 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 tu implementación del métodocreateNdefMessage()
muestra el objetoNdefMessage
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 que se entregue solo una vez que se inicia Android Beam, en caso de que el contenido del mensaje varíe durante el ciclo de 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 le interesan a tu app. Para obtener más información sobre el despacho de etiquetas, consulta la guía para desarrolladores de NFC.
Si deseas que tu NdefMessage
lleve un URI, ahora puedes usar el método de conveniencia 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, debes crear un filtro de intents para tu actividad usando el mismo esquema de URI para recibir el mensaje NDEF entrante.
También debes pasar un "registro de aplicación de Android" con tu NdefMessage
para garantizar que tu aplicación controle el mensaje NDEF entrante, incluso si otras aplicaciones filtran la misma acción de intent. Puedes crear un registro de aplicación para Android si llamas a createApplicationRecord()
y le pasas 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 (según el registro de la 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 para 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 instalada la aplicación, el sistema la inicia. Si no está instalada, Google Play se abre y dirige 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 algunos ejemplos de código 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 tecnología Android y otros tipos de dispositivos (de conformidad 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 Wi-Fi que te permiten descubrir otros dispositivos y conectarte a ellos cuando cada uno admite Wi-Fi P2P y, luego, comunicarse 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:
- Llama a
initialize()
para inicializar tu aplicación para conexiones P2P - Descubre dispositivos cercanos llamando a
discoverPeers()
- 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 devoluciones de llamada cuando una operación, como descubrir pares o conectarte a ellas, tiene éxito 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, las configuraciones de WPS que admite el dispositivo y mucho más. - 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. - La interfaz
WifiP2pManager.ConnectionInfoListener
te permite recibir información sobre la conexión actual. La devolución de llamada proporciona un objetoWifiP2pInfo
, que incluye información como si se formó un grupo y quién es su 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 tu 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 la conexión P2P cambió. De esta manera, se llevaEXTRA_WIFI_P2P_INFO
con un objetoWifiP2pInfo
yEXTRA_NETWORK_INFO
con un objetoNetworkInfo
.WIFI_P2P_STATE_CHANGED_ACTION
: El estado P2P cambió entre habilitado e 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 con perfiles de salud Bluetooth, por lo que puedes crear aplicaciones que usan Bluetooth para comunicarse con dispositivos de salud que admiten Bluetooth, como monitores de frecuencia cardíaca, medidores de sangre, termómetros y balanzas.
Al igual que con los dispositivos de perfiles 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 hayas adquirido el proxy del perfil de salud (el objeto BluetoothHealth
), la conexión a los 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 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 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 ella para escuchar las descripciones por 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 pueden hacerlo cuando el usuario navega con un pad direccional o una bola de seguimiento; para ello, lee la información que proporcionan android:contentDescription
y setContentDescription()
en un evento de desplazamiento simulado. Por lo tanto, ten en cuenta que debes proporcionar texto descriptivo para las vistas de tu aplicación, especialmente para ImageButton
, EditText
, ImageView
y otros widgets que podrían no contener texto descriptivo naturalmente.
Accesibilidad de las vistas
Si deseas 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 los 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 un evento de entrada, como un clic o colocar el cursor sobre un elemento, la vista respectiva recibe una notificación con una llamada a sendAccessibilityEvent()
. Antes, 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 del elemento, etcétera. 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 varios tipos que se deben propagar con información de texto, la vista recibe una llamada a
dispatchPopulateAccessibilityEvent()
, que difiere a la devolución de llamada deonPopulateAccessibilityEvent()
.Por lo general, las implementaciones personalizadas de
View
deben implementaronPopulateAccessibilityEvent()
para agregar contenido de texto adicional aAccessibilityEvent
si falta el textoandroid:contentDescription
o 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 que llegue a la vista raíz, que envía el evento aAccessibilityManager
consendAccessibilityEvent()
.
Además de los nuevos métodos 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 desvía 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 maneja el delegado vuelve a la vista para su comportamiento predeterminado. Esto te permite anular solo los métodos necesarios para cualquier vista determinada sin extender la clase View
.
Si deseas 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) con un conjunto de clases de utilidades que proporcionan 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 diversos eventos de accesibilidad se expandió significativamente a fin de permitir comentarios sobre accesibilidad más avanzados para los usuarios. En particular, los eventos se generan según la composición de 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 desarrollas un servicio de accesibilidad (como un lector de pantalla), puedes acceder a información de contenido adicional 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
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 para 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 se habilita o inhabilita la accesibilidad.getEnabledAccessibilityServiceList()
proporciona información sobre los servicios de accesibilidad que están habilitados actualmente.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 de corrector ortográfico y la app de 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 usarlo 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 incluyen metadatos, como el ícono, la etiqueta y el nombre del paquete del motor.
Cómo crear motores de texto a voz
Anteriormente, 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 crear motores 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 de onSynthesizeText()
en un servicio que extiende TextToSpeechService
. El sistema entrega este método dos objetos:
SynthesisRequest
: Contiene varios datos, incluidos el texto que se debe sintetizar, la configuración regional, la velocidad de la 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 transmisión de audio. 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 puedas usar para convertir tus motores de TTS antiguos al nuevo framework.
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 los 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 el uso según el tipo de conexión disponible.
Si tu aplicación realiza muchas transacciones de red, debes proporcionar parámetros de configuración que permitan a los usuarios controlar los hábitos de datos de tu app, como la frecuencia con la que sincroniza datos, si realiza cargas o descargas solo cuando el dispositivo está conectado a una red Wi-Fi, si se usan datos en roaming, etc. Con estos controles disponibles, es mucho menos probable que los usuarios inhabiliten el acceso de tu app a los datos precisamente cuando se acercan a sus límites.
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 el botón "Ver la configuración de la aplicación" que inicia tu actividad de preferencias 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 el valor "true". En su lugar, usa getActiveNetworkInfo()
. Antes de intentar 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 una conexión. Luego, puedes verificar otras propiedades de conexión, por ejemplo, si el dispositivo está en roaming o está conectado a Wi-Fi.
Empresas
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 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 termines, puedes 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 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 de dispositivos ahora pueden inhabilitar la cámara con setCameraDisabled()
y la propiedad USES_POLICY_DISABLE_CAMERA
(que se aplica 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 certificados y acceder a ellos 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 de 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 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
: Es un sensor de temperatura que proporciona la temperatura ambiente (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 rocío 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 una salida más fluida. Entre estos sensores se 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 optimizar 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 un teléfono celular se encuentra 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 coloca todos los elementos de acción en una barra separada en la parte inferior de la pantalla cuando esta es angosta.
Barra de acciones dividida
Si la barra de acciones incluye varios elementos de acción, no todos caberán 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 permite habilitar la "barra de acciones dividida" para que puedan aparecer más elementos de acción en una barra separada en la parte inferior de la pantalla. 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 esta sea 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 aparezcan las pestañas en la parte superior), habilita la barra de acciones divididas 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 a la izquierda 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 color o un elemento de diseño 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 elementos de acción. Un proveedor de acciones puede definir una vista de acciones, 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 manejar 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 al uso compartido 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 en el que se use 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 la contracción de 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 es contraíble, incluye la marca “collapseActionView"
en el atributo android:showAsAction
del elemento <item>
del archivo en formato XML del menú.
Para recibir devoluciones de llamada cuando una vista de acción alterna 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
respectivo.
Cuando creas una vista de acciones 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 "arriba" (pasa "verdadero" para que se comporte como un botón).setIcon()
ysetLogo()
te permiten definir el ícono o el logotipo de la barra de acciones en 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 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 jerarquía plana y no utiliza vistas intermedias, como filas de tablas, para proporcionar 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 manera secuencial en las filas y columnas de la cuadrícula.
La orientación de GridLayout
determina si los elementos secundarios secuenciales están distribuidos de forma predeterminada de forma horizontal o vertical. 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 muestras mediante GridLayout
.
Vista Textura
TextureView
es una vista nueva que te permite mostrar una transmisión de contenido, como un video o una escena 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 presionar) 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é activado y desactivado. El atributo android:text
también te permite colocar una etiqueta junto al interruptor.
Para ver un ejemplo con interruptores, consulta el archivo de diseño switches.xml y sus respectivas actividades de interruptores .
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 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ú. - 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 la configuración de Wi-Fi y Bluetooth.
Temas del sistema
El tema predeterminado para todas las aplicaciones orientadas a Android 4.0 (mediante la configuración de targetSdkVersion
o minSdkVersion
en “14"
o versiones posteriores) 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 esos temas 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 del menú, y establecer targetSdkVersion
en "14"
para aprovechar los comportamientos predeterminados más recientes del framework.
Controles para el nivel de visibilidad de la IU del sistema
Desde los inicios de Android, el sistema administra un componente de IU conocido como la barra de estado, que se encuentra en la parte superior de los teléfonos celulares para entregar información como la señal del proveedor, la hora y las notificaciones, entre otros. Android 3.0 agregó la barra del sistema para dispositivos tablet, que se encuentra 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 los elementos que tradicionalmente proporciona la barra de estado. En Android 4.0, el sistema proporciona un nuevo tipo de IU del sistema llamada barra de navegación. Podrías considerar la barra de navegación 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 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 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 la 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 para 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 mostrarse en cuanto el sistema recibe la entrada del usuario. Por lo tanto, este modo es útil principalmente para la reproducción de video y 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 tu 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 en tu actividad con cambios de visibilidad en la IU del sistema (por ejemplo, ocultar la barra de acciones o bien otros controles 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 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 con 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 permitir interacciones más enriquecidas mediante el uso de dispositivos de puntero (como un mouse o algún otro dispositivo que dirija un cursor en pantalla).
Para recibir eventos de desplazamiento en una vista, implementa View.OnHoverListener
y regístralo con setOnHoverListener()
. Cuando se produce un evento de colocar el cursor en la vista, el objeto de escucha recibe una llamada a onHover()
, lo que 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
debe mostrar el valor "true" a partir de onHover()
si controla el evento de colocar el cursor sobre él. Si el objeto de escucha muestra el valor falso, el evento de colocar el cursor sobre un elemento se enviará a la vista superior como de costumbre.
Si tu aplicación usa botones o algún otro widget que cambia 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 sobre el digitalizador, las aplicaciones reciben eventos de desplazamiento del mismo modo que lo harían cuando el puntero del mouse se mueve por la pantalla cuando no se presiona ningún botón.
Tu aplicación puede distinguir entre la entrada del dedo, el mouse, la pluma stylus y el 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 consultas 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 la pluma stylus se presionan mediante 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 adelantar del mouse se asignan automáticamente a las teclas KEYCODE_BACK
y KEYCODE_FORWARD
. Tu aplicación puede controlar estas teclas para admitir el botón del mouse según la navegación hacia atrás y hacia adelante.
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, y el ángulo de inclinación y 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 a los emisores establecer o obtener 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 y obtenga valores de la propiedad sin conocer los detalles de cuáles son los campos o métodos.
Por ejemplo, si deseas establecer el valor del campo bar
en el objeto foo
, debes hacerlo antes:
Kotlin
foo.bar = value
Java
foo.bar = value;
Si deseas llamar al método set para un campo privado subyacente bar
, antes harías esto:
Kotlin
foo.setBar(value)
Java
foo.setBar(value);
Sin embargo, si deseas pasar la instancia de foo
y que otro código configure el valor bar
, no hay manera de hacerlo en versiones anteriores a 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.).
La clase ObjectAnimator
también usa la clase Property
, de modo que puedes crear un ObjectAnimator
con un Property
, que es más rápido, más eficiente y más seguro de tipos que el enfoque basado en cadenas.
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
en “14"
o versiones posteriores. Por lo general, la aceleración de hardware da como resultado animaciones y desplazamientos más fluidos, y, en general, un mejor rendimiento y una respuesta a la interacción del usuario.
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 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 porque 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 “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 la 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 si se establece targetSdkVersion
o minSdkVersion
en “14"
o una versión posterior. Si has configurado 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 necesaria 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 facilita la prueba de las apps que usan
WebView
.
Navegador Android
La aplicación Navegador agrega las siguientes funciones para admitir aplicaciones web:
- Se actualizó el compilador JavaScript V8 para lograr un rendimiento más rápido.
- Además de otras mejoras importantes que se trasladaron de Android 3.0, ahora están disponibles para los teléfonos celulares:
- Compatibilidad con elementos de posición fija en todas las páginas
- Captura de contenido multimedia HTML
- Eventos de orientación del dispositivo
- Transformaciones de CSS en 3D
Permisos
Los siguientes son permisos nuevos:
ADD_VOICEMAIL
: Permite que un servicio de buzón de voz agregue mensajes de buzón 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. Dado que la plataforma de Android 3.x solo está disponible para dispositivos de pantalla grande, si desarrollaste apps 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 pasaste por alto 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 sobre fragmentos.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 del menú. Consulta la guía para desarrolladores sobre la barra de acciones.Loader
: Es un componente de 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 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 View 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 sencillas 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 puedes escribir en C (estándar C99), lo que proporciona el tipo de rendimiento que esperas de un entorno nativo, a la vez que permanece 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 de OpenGL para tu aplicación si configuras {android:hardwareAccelerated="true"} en el elemento
<application>
de tu manifiesto o para elementos<activity>
individuales. De esta manera, se obtienen animaciones y desplazamientos más fluidos, y un mejor rendimiento y una mejor respuesta a la interacción del usuario en general.Nota: Si configuras las opciones
minSdkVersion
otargetSdkVersion
de tu aplicación en"14"
o una versión posterior, la aceleración de hardware estará habilitada 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: 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 del dispositivo y el host 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, envío para hablar, conferencias 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 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 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 hacerlo por sus tamaños de pantalla generalizados (como grande o extragrande). Por ejemplo, esto es importante para ayudarte a distinguir entre un dispositivo de 5" y uno de 7", que tradicionalmente se agruparían como pantallas "grandes". Consulta la entrada de blog New Tools for Manage 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, llamado "nivel de API", permite que el sistema determine correctamente si una aplicación es compatible con él antes de instalarla.
Para usar las APIs de 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?