Android 4.1 API

Nivel de API: 16

Android 4.1 (JELLY_BEAN) es una progresión de la plataforma que ofrece y mejorar la experiencia del usuario. Agrega nuevas funciones para los usuarios y la app desarrolladores. Este documento proporciona una introducción a los conceptos más destacados APIs nuevas y útiles para desarrolladores de apps.

Como desarrollador de apps, Android 4.1 está disponible en el SDK Manager como una imagen del sistema que puedes se ejecutará en el emulador de Android y en una plataforma SDK en la cual puedes compilar tu app. Deberías descargue la imagen del sistema y la plataforma lo antes posible para compilar y probar su en Android 4.1.

Para optimizar mejor tu app para dispositivos con Android 4.1, haz lo siguiente: Debes configurar tu targetSdkVersion como "16", instálala en una imagen del sistema Android 4.1 probarlo y, luego, publicar una actualización con este cambio.

Tú puedes usar APIs en Android 4.1 y, al mismo tiempo, admitir versiones anteriores agregando condiciones a tu código que comprueben el nivel de API del sistema antes de la ejecución APIs no compatibles con tu minSdkVersion. Para obtener más información mantener la retrocompatibilidad, lee Cómo crear retrocompatibilidad más recientes.

Puedes encontrar más información sobre el funcionamiento de los niveles de API en Qué es la API nivel?

Componentes de la app

Servicios aislados

Si especificas android:isolatedProcess="true" en <service>, tu Service se ejecutará bajo su propio proceso aislado de ID de usuario que no tiene permisos propios.

Administración de la memoria

Las nuevas constantes ComponentCallbacks2, como TRIM_MEMORY_RUNNING_LOW y TRIM_MEMORY_RUNNING_CRITICAL, proporcionan el primer plano procesa más información sobre al estado de la memoria antes de que el sistema llame a onLowMemory().

El nuevo método getMyMemoryState(ActivityManager.RunningAppProcessInfo) te permite hacer lo siguiente: recuperar el estado de la memoria general.

Proveedores de contenido

Un nuevo método, acquireUnstableContentProviderClient(), te permite acceder a un ContentProviderClient que puede ser “inestable” para que tu app no falle si el proveedor de contenido. Resulta útil cuando interactúas con proveedores de contenido en un .

Fondos de pantalla animados

Nuevo protocolo de intents para iniciar directamente la actividad de vista previa del fondo animado de modo que puedas ayudar los usuarios pueden seleccionar fácilmente tu fondo animado sin forzarlos a salir. tu app y navega por el selector de fondo de pantalla de la pantalla principal.

Para iniciar el selector del fondo animado, llama a startActivity() con un Intent mediante ACTION_CHANGE_LIVE_WALLPAPER y un extra que especifica tu fondo animado ComponentName como una cadena en EXTRA_LIVE_WALLPAPER_COMPONENT.

Navegación de pila de aplicaciones

Android 4.1 facilita la implementación de patrones de diseño adecuados para la navegación hacia arriba. Solo debes agregar android:parentActivityName a cada elemento <activity> en tu archivo de manifiesto. El sistema usa esta información para abrir la actividad adecuada cuando el usuario presiona el botón Arriba de la barra de acciones (al mismo tiempo que finaliza la actividad actual). Entonces, si declara el android:parentActivityName de cada actividad, no necesitas el método onOptionsItemSelected() para controlar los clics eventos en el ícono de la aplicación de la barra de acciones, el sistema ahora controla ese evento y reanuda o crea la actividad adecuada.

Esto es particularmente útil para situaciones en las que el usuario ingresa una de las actividades de tu app. con un análisis detallado como una notificación o un intent desde diferente app (como se describe en la guía de diseño de Cómo navegar entre apps) Cuándo el usuario ingresa a tu actividad de esta manera, es posible que tu app no tenga naturalmente una pila de actividades que se pueden reanudar a medida que el usuario navega hacia arriba. Sin embargo, cuando proporcionas el atributo android:parentActivityName para tus actividades, el sistema reconoce si tu app ya contiene o no una pila de actividades de actividades superiores y, si no, construcciones una pila de actividades sintética que contiene todas las actividades principales.

Nota: Cuando el usuario ingresa a una actividad profunda en tu app. se crea una tarea nueva para tu app y el sistema inserta la pila de actividades principales en la tarea. Por lo tanto, cuando se presiona el botón Atrás, también se navega hacia atrás en la pila de elementos superiores. de datos.

Cuando el sistema crea una pila de actividades sintética para tu app, compila un Intent básico para crear una instancia nueva de cada actividad superior. Así que no hay estado guardado para las actividades principales de la forma en que se espera que el usuario navegue de forma natural a través de cada actividad. Si alguna de las actividades superiores normalmente muestra una IU que depende el contexto del usuario, faltará esa información de contexto y usted debe entregarla cuando usuario navega hacia atrás a través de la pila. Por ejemplo, si el usuario está viendo un álbum. en una app de música, navegar hacia arriba podría llevarlos a una actividad que enumere todos los álbumes de la género musical. En este caso, si es necesario crear la pila, es necesario que informes al elemento superior a qué género pertenece el álbum actual para que el elemento principal pueda mostrar la lista adecuada como si el usuario proviene realmente de esa actividad. Para entregar esa información a un publicador superior sintético debes anular el método onPrepareNavigateUpTaskStack(). Esta te proporciona un objeto TaskStackBuilder que el sistema creó para... sintetizar las actividades principales. El TaskStackBuilder contiene objetos Intent que el sistema usa para crear cada actividad superior. En tu implementación de onPrepareNavigateUpTaskStack(), puedes modificar el Intent adecuado para Agregar datos adicionales que la actividad principal pueda usar para determinar el contexto adecuado y mostrarlo la IU adecuada.

Cuando el sistema crea el TaskStackBuilder, agrega los objetos Intent que se usan para crear las actividades superiores en su lógica desde la parte superior del árbol de actividades. Por lo tanto, el último Intent agregado al array interno es el elemento superior directo de la actividad actual. Si si quieres modificar el Intent del elemento superior de la actividad, primero determina la longitud del array con getIntentCount() y pásalo valor en editIntentAt().

Si la estructura de tu app es más compleja, hay muchas otras APIs. que te permiten controlar el comportamiento de la navegación hacia arriba y personalizar por completo la pila de actividades sintética. Algunas de las APIs que te ofrecen incluyen:

onNavigateUp()
Anula esta opción para realizar una acción personalizada cuando el usuario presione el botón Arriba.
navigateUpTo(Intent)
Llama a este método para finalizar la actividad actual e ir a la que indica la actividad Intent suministrados. Si la actividad existe en la pila de actividades, pero no es el elemento principal más cercano, todas las demás actividades entre la actividad actual y las la actividad especificada con el intent también finalizan.
getParentActivityIntent()
Llama a este método para obtener el Intent que iniciará la lógica superior de la actividad actual.
shouldUpRecreateTask(Intent)
Llama a esta opción para consultar si se debe crear una pila de actividades sintética para navegar arriba. Muestra el valor true si se debe crear una pila sintética y false si se trata de la pila adecuada. ya existe.
finishAffinity()
Llama a esta función para finalizar la actividad actual y todas las actividades principales con la misma afinidad de tareas que están encadenadas a la actividad actual. Si anulas los comportamientos predeterminados, como onNavigateUp(), debes llamar a este método cuando crear una pila de actividades sintética en la navegación hacia arriba
onCreateNavigateUpTaskStack
Anula esto si necesitas controlar por completo cómo se crea la pila de tareas sintética. Si solo deseas agregar datos adicionales a los intents de tu pila de actividades, debes anular onPrepareNavigateUpTaskStack()
.

Sin embargo, la mayoría de las apps no necesitan usar estas APIs ni implementar onPrepareNavigateUpTaskStack(), pero pueden lograr el comportamiento correcto con solo agregando android:parentActivityName a cada elemento <activity>.

Multimedia

Códecs de archivos multimedia

La clase MediaCodec proporciona acceso a códecs multimedia de bajo nivel para la codificación. y decodificar tu contenido multimedia. Puedes crear una instancia de MediaCodec llamando a createEncoderByType() para codificar contenido multimedia o llamar a createDecoderByType() para decodificar contenido multimedia. Cada uno de estos toman un tipo de MIME para el tipo de contenido multimedia que quieres codificar o decodificar, como "video/3gpp" o "audio/vorbis".

Con una instancia de MediaCodec creada, puedes llamar a configure() para especificar propiedades como el formato multimedia o si el contenido está encriptado o no.

Ya sea que estés codificando o decodificando tu contenido multimedia, el resto del proceso es el mismo después de crea el MediaCodec. Primero, llama a getInputBuffers() para obtener un array de entrada ByteBuffer. y getOutputBuffers() para obtener un array de objetos ByteBuffer de salida.

Cuando tengas todo listo para codificar o decodificar, llama a dequeueInputBuffer() para obtener la posición del índice de ByteBuffer (a partir del array de búferes de entrada) que debes usar para el feed en tu fuente. medios de comunicación. Después de completar el ByteBuffer con el contenido multimedia de origen, libera la propiedad. del búfer llamando a queueInputBuffer().

Del mismo modo para el búfer de salida, llama a dequeueOutputBuffer() para obtener la posición del índice de ByteBuffer. en la que recibirás los resultados. Después de leer el resultado de ByteBuffer, haz lo siguiente: llamar a releaseOutputBuffer() para liberar la propiedad.

Puedes controlar los datos de contenido multimedia encriptados en los códecs si llamas a queueSecureInputBuffer() junto con las APIs de MediaCrypto, en lugar del queueInputBuffer() normal

Para obtener más información sobre cómo usar códecs, consulta la documentación de MediaCodec.

Grabación de audio al momento de la grabación

El nuevo método startRecording() permite que inicies una grabación de audio basada en una indicación definida por una MediaSyncEvent. MediaSyncEvent especifica una sesión de audio. (como uno definido por MediaPlayer), que cuando se completa, se activa la grabadora de audio para comenzar a grabar. Por ejemplo, puedes usar esta funcionalidad para reproducir un tono de audio que indique el comienzo de una sesión de grabación comienza automáticamente para que no tengas que sincronizar manualmente el tono y el comienzo de la grabación.

Pistas de texto temporizado

MediaPlayer ahora controla pistas de texto dentro y fuera de banda. Las pistas de texto en banda aparecen como pistas de texto dentro de una fuente multimedia MP4 o 3GPP. Texto fuera de banda se pueden agregar pistas como una fuente de texto externa a través del método addTimedTextSource(). Después de todo el texto externo fuentes de pistas, se debe llamar a getTrackInfo() para obtener la lista actualizada de todos los segmentos disponibles en una fuente de datos.

Para configurar el segmento para usar con el MediaPlayer, debes hacer lo siguiente: llama a selectTrack() con el índice posición para la pista que quieres usar.

Si deseas recibir una notificación cuando la pista de texto esté lista para reproducirse, implementa el Interfaz y pase de MediaPlayer.OnTimedTextListener a setOnTimedTextListener().

Efectos de audio

La clase AudioEffect ahora admite audio adicional tipos de procesamiento previo cuando se captura audio:

  • Cancelador de eco acústico (AEC) con AcousticEchoCanceler quita la contribución de la señal recibida de la parte remota de la señal de audio capturada.
  • Control automático de ganancia (AGC) con AutomaticGainControl normaliza automáticamente la salida de la señal capturada.
  • supresor de ruido (NS) con NoiseSuppressor quita el ruido de fondo de la señal capturada.

Puedes aplicar estos efectos del preprocesador en el audio capturado con un AudioRecord a través de uno de los AudioEffect. subclases de contenedores.

Nota: No se garantiza que todos los dispositivos admitan por lo que siempre debes verificar la disponibilidad llamando a isAvailable() en la ruta de efectos de audio.

Reproducción sin interrupciones

Ahora puedes realizar una reproducción sin interrupciones entre dos MediaPlayer. En cualquier momento antes de que termine tu primer MediaPlayer, llama a setNextMediaPlayer() y a Android intenta iniciar el segundo jugador en el momento en que se detiene el primero.

Router de contenido multimedia Las nuevas APIs de MediaRouter, MediaRouteActionProvider y MediaRouteButton proporcionan IU y mecanismos estándar para elegir dónde reproducir contenido multimedia

Cámara

Movimiento de enfoque automático

La nueva interfaz Camera.AutoFocusMoveCallback te permite escuchar para realizar cambios en el movimiento de enfoque automático. Puedes registrar tu interfaz con setAutoFocusMoveCallback(). Luego, cuando la cámara esté en modo de enfoque automático continuo (FOCUS_MODE_CONTINUOUS_VIDEO o FOCUS_MODE_CONTINUOUS_PICTURE), recibirás una llamada a onAutoFocusMoving(), que indica si el enfoque automático ha comenzado a moverse o si dejó de hacerlo.

Sonidos de la cámara

La clase MediaActionSound proporciona un conjunto simple de APIs para producir sonidos estándar generados por la cámara y otras acciones multimedia. Debes usar estas APIs para jugar el sonido adecuado al construir una cámara fija o de video personalizada.

Para reproducir un sonido, simplemente crea una instancia de un objeto MediaActionSound, llama load() para precargar el sonido deseado y, luego, en el un momento adecuado, llama a play().

Conectividad

Android Beam

Android BeamTM ahora admite transferencias de cargas útiles grandes por Bluetooth. Cuando defines los datos para transferir con el nuevo setBeamPushUris() o la nueva interfaz de devolución de llamada NfcAdapter.CreateBeamUrisCallback, Android pasar la transferencia de datos a Bluetooth o a otro transporte alternativo para lograr velocidades de transferencia más rápidas. Esto es especialmente útil para cargas útiles de imagen y archivos de audio y no requiere una vinculación visible entre los dispositivos. No se requiere ningún trabajo adicional para tu aplicación para aprovechar las transferencias por Bluetooth.

El método setBeamPushUris() toma un array de Objetos Uri que especifican los datos que deseas transferir desde tu app Como alternativa, puedes implementar NfcAdapter.CreateBeamUrisCallback que puedes especificar para tu actividad llamando a setBeamPushUrisCallback().

Cuando uses de devolución de llamada, el sistema llama al método createBeamUris() de la interfaz cuando la el usuario ejecuta un elemento compartido con Android Beam para que puedas definir los URI que se compartirán en el momento del uso compartido. Esto es útil si los URIs que se compartirán pueden variar según el contexto del usuario dentro del de actividad, mientras que llamar a setBeamPushUris() es es útil cuando los URIs que se deben compartir no cambian y puedes definirlos con seguridad de manera anticipada.

Detección del servicio de red

Android 4.1 agrega compatibilidad con el descubrimiento de servicios basados en DNS multicast, lo que te permite encontrar y conectarse a servicios ofrecidos por dispositivos similares a través de Wi-Fi, como dispositivos móviles, impresoras, cámaras, reproductores multimedia y otros dispositivos que estén registrados en la red local.

El nuevo paquete android.net.nsd contiene las nuevas APIs que te permiten realizar las siguientes acciones: transmitir servicios en la red local, descubrir dispositivos locales en la red y conectarse a los dispositivos.

Para registrar tu servicio, primero debes crear un NsdServiceInfo objeto y define las diversas propiedades de tu servicio con métodos como setServiceName(), setServiceType() y setPort()

Luego, debes implementar NsdManager.RegistrationListener. y pásala a registerService(). con tu NsdServiceInfo.

Para descubrir servicios en la red, implementa NsdManager.DiscoveryListener y pásalo a discoverServices().

Cuando tu NsdManager.DiscoveryListener recibe devoluciones de llamada sobre servicios encontrado, debes resolver el servicio llamando resolveService(), pásale un implementación de NsdManager.ResolveListener que recibe un objeto NsdServiceInfo que contiene información sobre el del servicio detectado, lo que te permite iniciar la conexión.

Detección de servicio P2P Wi-Fi

Las API P2P Wi-Fi están mejoradas en Android 4.1 para admitir la detección de servicios de asociación previa en WifiP2pManager Esto te permite descubrir y filtrar lugares cercanos dispositivos por servicios que usan Wi-Fi P2P antes de conectarse a uno, mientras el servicio de red La detección te permite descubrir un servicio en una red conectada existente (como una red Wi-Fi local). red).

Para transmitir tu app como un servicio por Wi-Fi, de modo que otros dispositivos puedan detectar tu app y te conectas a ella, llama a addLocalService() con un WifiP2pServiceInfo que describe los servicios de tu app.

Para iniciar la detección de dispositivos cercanos a través de Wi-Fi, primero debes decidir si de comunicarse mediante Bonjour o Upnp. Para usar Bonjour, primero configura algunos objetos de escucha de devolución de llamada con setDnsSdResponseListeners(), que toma un WifiP2pManager.DnsSdServiceResponseListener y un WifiP2pManager.DnsSdTxtRecordListener. Para usar Upnp, llama a setUpnpServiceResponseListener(), que toma un WifiP2pManager.UpnpServiceResponseListener.

Antes de comenzar a descubrir servicios en dispositivos locales, también debes llamar a addServiceRequest(). Cuando el WifiP2pManager.ActionListener que pasas a este método recibe un devolución de llamada exitosa, podrás comenzar a descubrir servicios en dispositivos locales llamando a discoverServices().

Cuando se detecten servicios locales, recibirás una devolución de llamada a WifiP2pManager.DnsSdServiceResponseListener o WifiP2pManager.UpnpServiceResponseListener, dependiendo de si para utilizar Bonjour o Upnp. La devolución de llamada recibida en cualquier caso contiene un Un objeto WifiP2pDevice que representa el dispositivo de intercambio de tráfico

Uso de red

El nuevo método isActiveNetworkMetered() te permite hacer lo siguiente: Verificar si el dispositivo está conectado a una red de uso medido Verificando este estado antes de realizar transacciones de red intensivas, puedes ayudar a administrar el uso de datos que podría costarles dinero a tus usuarios tomar decisiones informadas sobre si realizar las transacciones ahora o más tarde (como cuando se conecta a la red Wi-Fi).

Accesibilidad

APIs del servicio de accesibilidad

El alcance de las APIs del servicio de accesibilidad se aumentó de forma significativa en Android 4.1. Ahora te permite compilar servicios que supervisan y responden más eventos de entrada, como gestos complejos usando onGesture() y otros eventos de entrada a través de adiciones a las clases AccessibilityEvent, AccessibilityNodeInfo y AccessibilityRecord.

Los servicios de accesibilidad también pueden realizar acciones en nombre del usuario, como hacer clic, desplazarse y revisar el texto con performAction y setMovementGranularities El método performGlobalAction() también permite que los servicios realicen acciones como Atrás, Inicio y abrir Reciente Apps y notificaciones.

Navegación personalizable en la app

Cuando compilas una app para Android, puedes personalizar los esquemas de navegación y widgets de entrada con findFocus() y focusSearch(), y establece el foco usando setAccessibilityFocused().

Widgets más accesibles

La nueva clase android.view.accessibility.AccessibilityNodeProvider te permite hacer lo siguiente: mostrar vistas personalizadas complejas a los servicios de accesibilidad para que puedan presentar la información de forma de una forma más accesible. android.view.accessibility.AccessibilityNodeProvider le permite a un usuario con contenido avanzado, como una cuadrícula de calendario, para presentar una estructura semántica lógica para servicios de accesibilidad que son completamente independientes de la estructura de diseño del widget. Esta semántica de accesibilidad permite que los servicios de accesibilidad presenten un modelo de interacción más útil para los usuarios que persona con discapacidad visual.

Copiar y pegar

Cómo copiar y pegar con intents

Ahora puedes asociar un objeto ClipData con un Intent usando el método setClipData(). Esto es muy útil cuando se usa un intent para transferir múltiples URI de content: a otro aplicaciones, como cuando se comparten varios documentos. Los URI de content: proporcionados también respetará las marcas del intent para ofrecer acceso de lectura o escritura, lo que te permite otorgar acceso a varios URI en un intent. Cuando se inicia un intent ACTION_SEND o ACTION_SEND_MULTIPLE, los URI suministrados en el intent ahora son se propaga automáticamente a ClipData para que el receptor pueda tener el acceso que se les otorgó.

Compatibilidad con HTML y estilos de cadena

La clase ClipData ahora admite texto con estilo (ya sea como HTML o Android con estilo cadenas). Puedes agregar texto con estilo HTML a ClipData con newHtmlText().

RenderScript

Se mejoró la funcionalidad de procesamiento de Renderscript con las siguientes características:

  • Compatibilidad con varios kernels dentro de una secuencia de comandos
  • Compatibilidad con la lectura de la asignación con muestras filtradas de Compute en una nueva API de secuencia de comandos rsSample
  • Se agregó compatibilidad con diferentes niveles de precisión de FP en #pragma.
  • Compatibilidad con la consulta de información adicional de objetos RS desde una secuencia de comandos de cómputos.
  • Se realizaron varias mejoras de rendimiento.

También hay nuevos pragmas disponibles para definir la precisión de punto flotante requerida por tu procesar Renderscripts. Permite habilitar operaciones similares a NEON, como operaciones matemáticas de vectores rápidos. en la ruta de la CPU que no serían posibles con el estándar IEEE 754-2008 completo.

Nota: El motor de gráficos experimental Renderscript ahora es obsoleto.

Animación

Animaciones para iniciar la actividad

Ahora puedes iniciar un Activity con animaciones de zoom o tus propias animaciones personalizadas. Para especificar la animación que deseas, usa las APIs de ActivityOptions para compilar un Bundle que puedas y, luego, pasarlo a cualquiera de métodos que inician una actividad, como startActivity().

La clase ActivityOptions incluye un método diferente para cada uno tipo de animación que puedes querer mostrar cuando se abre tu actividad:

makeScaleUpAnimation()
Crea una animación que escala verticalmente la ventana de actividad a partir de un inicio especificado. posición en la pantalla y un tamaño inicial especificado. Por ejemplo, la pantalla de inicio en Android 4.1 lo usa cuando se abre una app.
makeThumbnailScaleUpAnimation()
Crea una animación que escala verticalmente la ventana de actividad a partir de un valor especificado y una imagen en miniatura. Por ejemplo, la ventana Aplicaciones recientes en Android 4.1 lo usa cuando regresa a una app.
makeCustomAnimation()
Crea una animación definida por tus propios recursos, una que define la animación del el inicio de la actividad y otro para la que se está deteniendo.

Animación de tiempo

El nuevo TimeAnimator proporciona una devolución de llamada simple. mecanismo con el TimeAnimator.TimeListener que notifica en cada fotograma de la animación. Con este Animator, no se establece ningún valor de duración, interpolación ni objeto. La devolución de llamada del objeto de escucha recibe información para cada fotograma, incluida el tiempo total que transcurrió desde el fotograma de animación anterior.

Interfaz de usuario

Notificaciones

En Android 4.1, puedes crear notificaciones con regiones de contenido más grandes, vistas previas de imágenes grandes, varios botones de acción y una prioridad configurable.

Estilos de notificaciones

El nuevo método setStyle() te permite especificar uno de los tres estilos nuevos para la notificación, que cada uno ofrece una región de contenido más grande. Para especifica el estilo de tu región de contenido grande y pasa uno de los siguientes objetos a setStyle():

Notification.BigPictureStyle
Para notificaciones que incluyen una imagen adjunta grande.
Notification.BigTextStyle
Para las notificaciones que incluyen mucho texto, como un solo correo electrónico.
Notification.InboxStyle
Para notificaciones que incluyen una lista de cadenas, como fragmentos de varios correos electrónicos
Acciones de la notificación

Ahora es compatible con hasta dos botones de acción que aparecen en la parte inferior de de notificación, ya sea que la notificación tenga el estilo normal o más grande.

Para agregar un botón de acción, llama a addAction(). Este método adopta tres argumentos: un recurso de elementos de diseño para un ícono, texto del botón y un PendingIntent que define la acción para perfrom.

Prioridades

Ahora puedes indicarle al sistema qué importancia tiene tu notificación para afectar las notificaciones en la lista estableciendo la prioridad con setPriority(). Tú puedes pasar uno de los cinco niveles de prioridad diferentes definidos por constantes PRIORITY_*. en la clase Notification El valor predeterminado es PRIORITY_DEFAULT, y hay dos niveles más altos y dos niveles más bajos.

Las notificaciones de prioridad alta son elementos que el usuario suele responder rápido como un nuevo mensaje instantáneo, un mensaje de texto o un recordatorio inminente de un evento. Prioridad baja como eventos de calendario vencidos o promociones de apps.

Controles para la IU del sistema

Android 4.0 (Ice Cream Sandwich) agregó nuevas marcas para controlar la visibilidad de la IU del sistema. elementos, como atenuar la apariencia de la barra del sistema o hacer que desaparezca por completo en los teléfonos celulares. Android 4.1 agrega algunas marcas más que te permiten controlar aún más la apariencia del sistema Elementos de la IU y el diseño de tu actividad en relación con ellos llamando a setSystemUiVisibility(). y pasa las siguientes marcas:

SYSTEM_UI_FLAG_FULLSCREEN
Oculta la IU del sistema que no es crítica (como la barra de estado). Si tu actividad usa la barra de acciones en el modo de superposición (por habilita android:windowActionBarOverlay), esta marca también oculta la barra de acciones con una animación coordinada cuando se ocultan y se muestran.
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
Establece el diseño de tu actividad para usar la misma área de pantalla que está disponible cuando habilitó SYSTEM_UI_FLAG_FULLSCREEN incluso si los elementos de la IU del sistema siguen siendo visibles. Si bien las partes de tu diseño se superpondrán con el del sistema operativo, esto es útil si tu app suele ocultar y mostrar la IU del sistema con SYSTEM_UI_FLAG_FULLSCREEN, ya que evita que el diseño ajustar a los nuevos límites de diseño cada vez que la IU del sistema se oculta o aparece.
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
Establece el diseño de tu actividad para usar la misma área de pantalla que está disponible cuando habilitado SYSTEM_UI_FLAG_HIDE_NAVIGATION (agregado en Android 4.0) incluso si los elementos de la IU del sistema siguen siendo visibles. Si bien algunas partes del diseño estarán superpuesta por el barra de navegación, es útil si tu app a menudo oculta y muestra la barra de navegación con SYSTEM_UI_FLAG_HIDE_NAVIGATION, ya que evita que tu diseño se ajusta a los nuevos límites de diseño cada vez que la barra de navegación se oculta o aparece.
SYSTEM_UI_FLAG_LAYOUT_STABLE
Te recomendamos que agregues esta marca si usas SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN o SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION para asegurarte de que cuando llames fitSystemWindows() en una vista que y límites definidos permanecen coherentes con respecto al espacio de pantalla disponible. Es decir, con esta marca establecida, fitSystemWindows() se comportará como si no cambiara la visibilidad de los elementos de la IU del sistema incluso después de ocultar toda la IU del sistema.

Para obtener más información sobre las otras marcas relacionadas de la IU del sistema, lee lo siguiente: las que se agregaron en Android 4.0.

Vistas remotas

GridLayout y ViewStub ahora son vistas remotas, por lo que puedes usarlas en los diseños de tu widgets de apps y diseños personalizados de notificaciones.

Familias de fuentes

En Android 4.1, se agregan varias variantes más del estilo de fuente Roboto para un total de 10 variantes. y las apps pueden usarlos. Ahora tus apps tienen acceso al conjunto completo de funciones variantes condensadas.

El conjunto completo de variantes de fuentes Roboto disponibles es el siguiente:

  • Frecuente
  • Cursiva
  • Negrita
  • Negrita-cursiva
  • Claro
  • Cursiva claro
  • Regular condensada
  • Cursiva condensada
  • Negrita condensada
  • Negrita-cursiva condensada

Puedes aplicar cualquiera de estas con la nueva fontFamily en combinación con el atributo textStyle.

Los valores admitidos para fontFamily son los siguientes:

  • "sans-serif" para Roboto normal
  • "sans-serif-light" para Roboto Light
  • "sans-serif-condensed" para Roboto Condensed

Luego, puedes aplicar negrita o cursiva con los valores textStyle "bold" y "italic". Puedes aplicar ambos de la siguiente manera: android:textStyle="bold|italic".

También puedes usar Typeface.create(). Por ejemplo, Typeface.create("sans-serif-light", Typeface.NORMAL).

Marco de trabajo de entrada

Varios dispositivos de entrada

La nueva clase InputManager te permite realizar consultas al conjunto de dispositivos de entrada conectados actualmente y se registran para recibir una notificación cuando un dispositivo nuevo se agrega, cambia o quita. Esto es particularmente útil si creas un juego compatible con varios jugadores y quieres detectar cuántos controles están conectados y cuando haya cambios en la cantidad de controles.

Puedes consultar todos los dispositivos de entrada conectados llamando getInputDeviceIds() Esto devuelve un array de números enteros, cada uno de los cuales es un ID para un dispositivo de entrada diferente. Luego, puedes llamar getInputDevice() para adquirir un InputDevice para un ID de dispositivo de entrada especificado

Si quieres recibir un aviso cuando se conecten, cambien o desconecten nuevos dispositivos de entrada, haz lo siguiente: implementarás la interfaz InputManager.InputDeviceListener y regístralo con registerInputDeviceListener().

Vibrar para controladores de entrada

Si los dispositivos de entrada conectados tienen su propia función de vibración, ahora puedes controlar la vibración de esos dispositivos con las APIs de Vibrator existentes simplemente llamando a getVibrator() en InputDevice.

Permisos

Los siguientes son permisos nuevos:

READ_EXTERNAL_STORAGE
Proporciona acceso de lectura protegido al almacenamiento externo. En Android 4.1, de de forma predeterminada, todas las aplicaciones aún tienen lectura el acceso a los datos. Esto se modificará en una versión futura para requerir que las aplicaciones soliciten explícitamente acceso de lectura con este permiso. Si tu aplicación ya solicita acceso de escritura, acceso de lectura automáticamente. Hay una nueva opción para desarrolladores para activar el acceso de lectura restricción, para que los desarrolladores prueben sus aplicaciones con el comportamiento que tendrán Android en la en el futuro.
android.Manifest.permission.READ_USER_DICTIONARY
Permite que una aplicación lea el diccionario del usuario. Esto solo debería ser necesario para una un IME o un editor de diccionario, como la app de Configuración.
READ_CALL_LOG
Permite que una aplicación lea el registro de llamadas del sistema que contiene información sobre la llamadas entrantes y salientes.
WRITE_CALL_LOG
Permite que una aplicación modifique el registro de llamadas del sistema almacenado en el teléfono
android.Manifest.permission.WRITE_USER_DICTIONARY
Permite que una aplicación escriba en el diccionario de palabras del usuario.

Funciones del dispositivo

Android 4.1 incluye una nueva declaración de función para dispositivos dedicados para mostrar la interfaz de usuario en una pantalla de televisión: FEATURE_TELEVISION. Para declarar que tu app requiere una interfaz de televisión, declara esta función en tu archivo de manifiesto con el elemento <uses-feature>:

<manifest ... >
    <uses-feature android:name="android.hardware.type.television"
                  android:required="true" />
    ...
</manifest>

Esta función define "televisión" una experiencia típica en una sala de estar. se muestran en una pantalla grande, en la que el usuario está sentado lejos, y la forma dominante de es como un pad direccional y, por lo general, no a través del tacto mouse/puntero-dispositivo.