API de nível: 16
O Android 4.1 (JELLY_BEAN
)
é uma progressão da plataforma que oferece desempenho
melhor e experiência do usuário aprimorada. Ele adiciona novos recursos para usuários e desenvolvedores
de apps. Este documento fornece uma introdução às novas APIs mais notáveis e
úteis para desenvolvedores de apps.
Como desenvolvedor de apps, o Android 4.1 está disponível no SDK Manager como uma imagem do sistema que pode ser executada no Android Emulator e em uma plataforma do SDK em que você pode criar seu app. Faça o download da imagem do sistema e da plataforma o mais rápido possível para criar e testar seu app no Android 4.1.
Para otimizar melhor seu app para dispositivos com Android 4.1,
defina targetSdkVersion
como
"16"
, instale-o em uma imagem do sistema Android 4.1,
teste e publique uma atualização com essa mudança.
Você
pode usar APIs no Android 4.1 e, ao mesmo tempo, oferecer suporte a versões mais antigas, adicionando
condições ao código que verificam o nível da API do sistema antes de executar
APIs que não têm suporte da minSdkVersion
.
Para saber mais sobre
como manter a compatibilidade com versões anteriores, leia Como criar IUs
compatíveis com versões anteriores.
Para mais informações sobre como os níveis da API funcionam, consulte O que é nível da API?.
Componentes do app
Serviços isolados
Ao especificar android:isolatedProcess="true"
na tag
<service>
, o Service
será executado no
próprio processo isolado de ID do usuário que não tem permissões próprias.
Gerenciamento de memória
Novas constantes ComponentCallbacks2
, como TRIM_MEMORY_RUNNING_LOW
e TRIM_MEMORY_RUNNING_CRITICAL
, oferecem processos
em primeiro plano mais informações sobre
o estado da memória antes que o sistema chame onLowMemory()
.
O novo método getMyMemoryState(ActivityManager.RunningAppProcessInfo)
permite
recuperar o estado geral da memória.
Provedores de conteúdo
Um novo método, acquireUnstableContentProviderClient()
, permite acessar uma ContentProviderClient
que pode ser "instável" para que o app não falhe se
o provedor de conteúdo o fizer. Ele é útil ao interagir com provedores de conteúdo em um app
separado.
Planos fundo interativos
Novo protocolo de intent para iniciar diretamente a atividade de prévia do plano de fundo interativo para que você possa ajudar os usuários a selecionar facilmente o plano de fundo interativo sem forçá-los a sair do app e navegar pelo seletor de plano de fundo da tela inicial.
Para iniciar o seletor de plano de fundo interativo, chame startActivity()
com um Intent
usando
ACTION_CHANGE_LIVE_WALLPAPER
e um extra
que especifique o plano de fundo interativo ComponentName
como uma string em EXTRA_LIVE_WALLPAPER_COMPONENT
.
Navegação pela pilha de apps
O Android 4.1 facilita muito a implementação dos padrões de design adequados para a navegação para cima.
Basta adicionar o android:parentActivityName
a cada elemento <activity>
no
arquivo de manifesto. O sistema usa essas informações para abrir a atividade adequada quando o usuário
pressiona o botão "Para cima" na barra de ações, ao mesmo tempo que conclui a atividade atual. Portanto, se você
declarar o android:parentActivityName
para cada atividade, não vai ser necessário usar o método onOptionsItemSelected()
para processar eventos
de clique no ícone do app da barra de ações. O sistema agora vai processar esse evento e retomar ou
criar a atividade adequada.
Isso é particularmente útil em cenários em que o usuário insere uma das atividades do app
por uma intent de "análise detalhada", como em uma notificação ou uma intent
de outro app, conforme descrito no guia de design de Como navegar entre apps. Quando
o usuário insere a atividade dessa maneira, é possível que o app não tenha naturalmente uma backstack de
atividades que possa ser retomada à medida que o usuário navega. No entanto, quando você fornece o atributo android:parentActivityName
para as atividades, o sistema reconhece
se o app já contém uma backstack de atividades mãe e, caso contrário, constrói
uma backstack sintética que contém todas as atividades mãe.
Observação:quando o usuário insere uma atividade profunda no app e cria uma nova tarefa para o app, o sistema insere a pilha de atividades pai na tarefa. Dessa forma, pressionar o botão "Voltar" também navega de volta pela pilha de atividades mãe.
Quando o sistema cria uma backstack sintética para o app, ele cria uma Intent
básica para gerar uma nova instância de cada atividade mãe. Portanto, não há estado salvo para as atividades mãe, da maneira que você espera que o usuário navegue naturalmente por cada atividade. Se alguma das atividades pai normalmente mostrar uma interface dependente do
contexto do usuário, essa informação de contexto estará ausente, e você precisará fornecê-la quando o
usuário
navegar de volta pela pilha. Por exemplo, se o usuário estiver visualizando um álbum
em um app de música, navegar para cima pode levar a uma atividade que lista todos os álbuns de um gênero musical
escolhido. Nesse caso, se a pilha precisar ser criada, é necessário informar à atividade mãe
a que gênero o álbum atual pertence para que o pai possa mostrar a lista adequada
como se o usuário realmente tivesse vindo dessa atividade. Para entregar essas informações a uma atividade mãe
sintética, substitua o método onPrepareNavigateUpTaskStack()
. Isso
fornece um objeto TaskStackBuilder
que o sistema criou para
sintetizar as atividades pai. O TaskStackBuilder
contém objetos Intent
que o sistema usa para criar cada atividade mãe. Na
implementação do onPrepareNavigateUpTaskStack()
, você pode modificar a Intent
adequada para
adicionar outros dados que a atividade mãe possa usar para determinar o contexto e mostrar
a interface adequada.
Quando o sistema cria a TaskStackBuilder
, ele adiciona os objetos Intent
usados para criar as atividades mãe na ordem
lógica, começando pela parte de cima da árvore de atividades. Portanto, o último Intent
adicionado à matriz interna é o pai direto da atividade atual. Se
você quiser modificar o Intent
do pai da atividade, primeiro determine
o comprimento da matriz com getIntentCount()
e transmita esse
valor para editIntentAt()
.
Se a estrutura do app for mais complexa, há várias outras APIs disponíveis que permitem processar o comportamento da navegação para cima e personalizar totalmente a backstack sintética. Estas são algumas das APIs que oferecem maior controle:
onNavigateUp()
- Substitua essa opção para executar uma ação personalizada quando o usuário pressionar o botão "Para cima".
navigateUpTo(Intent)
- Chame para concluir a atividade atual e acessar a atividade indicada pelo
Intent
fornecido. Se a atividade existir na backstack, mas não for o pai mais próximo, todas as outras atividades entre a atividade atual e a especificada com o intent também serão concluídas. getParentActivityIntent()
- Chame isto para receber o
Intent
que iniciará o pai lógico da atividade atual. shouldUpRecreateTask(Intent)
- Chame este método para consultar se uma backstack sintética precisa ser criada para navegar para cima. Retorna verdadeiro se uma pilha sintética precisar ser criada e falso se a pilha apropriada já existir.
finishAffinity()
- Chame para concluir a atividade atual e todas as atividades mãe com a mesma
afinidade de tarefa encadeada à atividade atual.
Se você substituir os comportamentos padrão, como
onNavigateUp()
, chame esse método ao criar uma backstack sintética na navegação para cima. onCreateNavigateUpTaskStack
- Substitua essa opção se você precisar controlar totalmente como a pilha de tarefas sintética é criada. Se você quiser simplesmente adicionar mais dados às intents da backstack, substitua
onPrepareNavigateUpTaskStack()
.
No entanto, a maioria dos apps não precisa usar essas APIs ou implementar onPrepareNavigateUpTaskStack()
, mas pode alcançar o comportamento correto simplesmente
adicionando android:parentActivityName
a cada elemento <activity>
.
Multimídia
Codecs de mídia
A classe MediaCodec
fornece acesso a codecs de mídia de baixo nível para codificar
e decodificar sua mídia. É possível instanciar um MediaCodec
chamando createEncoderByType()
para codificar mídia ou chamar createDecoderByType()
para decodificar mídia. Cada um desses
métodos tem um tipo MIME para o tipo de mídia que você quer codificar ou decodificar, como "video/3gpp"
ou "audio/vorbis"
.
Com uma instância de MediaCodec
criada, você pode chamar configure()
para especificar propriedades como o formato de mídia ou
se o conteúdo é criptografado ou não.
Se você estiver codificando ou decodificando sua mídia, o restante do processo será o mesmo depois de
criar o MediaCodec
. Primeiro, chame getInputBuffers()
para receber uma matriz de objetos ByteBuffer
de entrada e getOutputBuffers()
para receber uma matriz de objetos ByteBuffer
de saída.
Quando estiver tudo pronto para codificar ou decodificar, chame dequeueInputBuffer()
para receber a posição do índice de ByteBuffer
(da matriz de buffers de entrada) que você precisa usar para alimentar a mídia de origem. Depois de preencher o ByteBuffer
com a mídia de origem, libere a propriedade
do buffer chamando queueInputBuffer()
.
Da mesma forma, para o buffer de saída, chame dequeueOutputBuffer()
para receber a posição do índice de ByteBuffer
em que você receberá os resultados. Depois de ler a saída de ByteBuffer
,
libere a propriedade chamando releaseOutputBuffer()
.
Para processar dados de mídia criptografados nos codecs, chame queueSecureInputBuffer()
em conjunto com as APIs MediaCrypto
, em vez do queueInputBuffer()
normal.
Para mais informações sobre como usar codecs, consulte a documentação MediaCodec
.
Gravar áudio no sinal
O novo método startRecording()
permite
que você inicie a gravação de áudio com base em um sinal definido por um MediaSyncEvent
.
O MediaSyncEvent
especifica uma sessão de áudio
(como uma definida por MediaPlayer
) que, quando concluída, aciona
o gravador de áudio para começar a gravar. Por exemplo, você pode usar essa funcionalidade para
reproduzir um tom de áudio que indique o início de uma sessão de gravação, e a gravação
começa automaticamente para que não seja necessário sincronizar manualmente o tom e o início
da gravação.
Faixas de texto com marcação de tempo
O MediaPlayer
agora processa faixas de texto em banda e fora de banda.
As faixas de texto em banda vêm como uma faixa de texto em uma fonte de mídia MP4 ou 3GPP. As faixas de texto fora de banda
podem ser adicionadas como uma origem de texto externa usando o método addTimedTextSource()
. Depois que todas as origens de faixa de texto
externas forem adicionadas, getTrackInfo()
precisará ser chamado para conferir
a lista atualizada de todas as faixas disponíveis em uma fonte de dados.
Para definir a faixa a ser usada com o MediaPlayer
,
chame selectTrack()
usando a posição
do índice da faixa que você quer usar.
Para receber uma notificação quando a faixa de texto estiver pronta para ser reproduzida, implemente a
interface MediaPlayer.OnTimedTextListener
e transmita-a
para setOnTimedTextListener()
.
Efeitos de áudio
A classe AudioEffect
agora é compatível com outros tipos de pré-processamento de áudio ao capturar áudio:
- O cancelamento de eco acústico (AEC, na sigla em inglês) com
AcousticEchoCanceler
remove a contribuição do sinal recebido da parte remota do sinal de áudio capturado. - O Controle automático de ganho (AGC, na sigla em inglês) com
AutomaticGainControl
normaliza automaticamente a saída do sinal capturado. - O supressor de ruído (NS, na sigla em inglês) com
NoiseSuppressor
remove o ruído de fundo do sinal capturado.
É possível aplicar esses efeitos de pré-processador ao áudio capturado com um AudioRecord
usando uma das subclasses
AudioEffect
.
Observação:não é garantido que todos os dispositivos ofereçam suporte a esses
efeitos. Portanto, sempre verifique a disponibilidade chamando isAvailable()
na classe de
efeito de áudio correspondente.
Reprodução sem intervalos
Agora você pode realizar a reprodução sem lacunas entre dois objetos
MediaPlayer
separados. A qualquer momento antes do primeiro MediaPlayer
terminar,
chame setNextMediaPlayer()
. O Android
vai tentar iniciar o segundo jogador assim que o primeiro parar.
Câmera
Movimento de foco automático
A nova interface Camera.AutoFocusMoveCallback
permite que você detecte
mudanças no movimento do foco automático. Você pode registrar sua interface com setAutoFocusMoveCallback()
. Em seguida, quando a câmera
estiver no modo de autofoco contínuo (FOCUS_MODE_CONTINUOUS_VIDEO
ou
FOCUS_MODE_CONTINUOUS_PICTURE
), você vai receber uma chamada
para onAutoFocusMoving()
,
que informa se o foco automático começou a se mover ou parou de se mover.
Sons da câmera
A classe MediaActionSound
oferece um conjunto simples de APIs para produzir
sons padrão emitidos pela câmera ou outras ações de mídia. Use essas APIs para tocar
o som adequado ao criar uma câmera estática ou de vídeo personalizada.
Para tocar um som, basta instanciar um objeto MediaActionSound
, chamar load()
para pré-carregar o som desejado e, no momento adequado, chamar play()
.
Conectividade
Android Beam
O Android BeamTM agora oferece suporte a grandes transferências de payload por Bluetooth. Quando você define os dados
que serão transferidos com o novo método setBeamPushUris()
ou com a nova interface de callback NfcAdapter.CreateBeamUrisCallback
, o Android
transfere a transferência de dados para o Bluetooth ou outro transporte alternativo para
atingir velocidades de transferência mais rápidas. Isso é especialmente útil para payloads grandes, como arquivos de imagem e
áudio, e não exige pareamento visível entre os dispositivos. Nenhum trabalho extra é necessário pelo
app para aproveitar as transferências por Bluetooth.
O método setBeamPushUris()
usa uma matriz de
objetos Uri
que especificam os dados que você quer transferir do app.
Como alternativa, você pode implementar a interface
NfcAdapter.CreateBeamUrisCallback
, que pode ser especificada para a atividade chamando setBeamPushUrisCallback()
.
Ao usar a
interface de callback, o sistema chama o método createBeamUris()
da interface quando o
usuário executa um compartilhamento com o Android Beam para que você possa definir os URIs a serem compartilhados no momento do compartilhamento.
Isso é útil caso os URIs a serem compartilhados possam variar de acordo com o contexto do usuário na
atividade. A chamada de setBeamPushUris()
é
útil quando os URIs a serem compartilhados não mudam e você pode defini-los com segurança antecipadamente.
Detecção de serviço de rede
O Android 4.1 adiciona suporte à descoberta de serviços baseada em DNS multicast, o que permite encontrar e se conectar a serviços oferecidos por dispositivos semelhantes por Wi-Fi, como dispositivos móveis, impressoras, câmeras, players de mídia e outros registrados na rede local.
O novo pacote android.net.nsd
contém as novas APIs que permitem transmitir serviços na rede local, descobrir dispositivos locais na rede e se conectar a dispositivos.
Para registrar seu serviço, primeiro crie um objeto NsdServiceInfo
e defina as várias propriedades dele com métodos como
setServiceName()
,
setServiceType()
e
setPort()
.
Em seguida, é necessário implementar o NsdManager.RegistrationListener
e transmiti-lo para registerService()
com o NsdServiceInfo
.
Para descobrir serviços na rede, implemente o NsdManager.DiscoveryListener
e transmita-o para discoverServices()
.
Quando o NsdManager.DiscoveryListener
recebe callbacks sobre os serviços
encontrados, é necessário resolver o serviço chamando
resolveService()
, transmitindo uma
implementação de NsdManager.ResolveListener
que recebe
um objeto NsdServiceInfo
que contém informações sobre o
serviço descoberto, permitindo iniciar a conexão.
Descoberta de serviços Wi-Fi P2P
As APIs de Wi-Fi P2P foram aprimoradas no Android 4.1 para oferecer suporte à descoberta de serviços de pré-associação no
WifiP2pManager
. Isso permite que você descubra e filtre dispositivos
próximos por serviços usando o Wi-Fi P2P antes de se conectar a um, enquanto a descoberta de
serviços de rede permite descobrir um serviço em uma rede conectada já existente (como uma rede
Wi-Fi local).
Para transmitir seu app como um serviço por Wi-Fi para que outros dispositivos possam descobrir
seu app e se conectar a ele, chame addLocalService()
com um objeto
WifiP2pServiceInfo
que descreva os serviços do seu app.
Para iniciar a descoberta de dispositivos próximos por Wi-Fi, primeiro você precisa decidir se vai
se comunicar usando o Bonjour ou o Upnp. Para usar o Bonjour, primeiro configure alguns listeners de callback com
setDnsSdResponseListeners()
, que usa WifiP2pManager.DnsSdServiceResponseListener
e WifiP2pManager.DnsSdTxtRecordListener
. Para usar o Upnp, chame
setUpnpServiceResponseListener()
, que usa um WifiP2pManager.UpnpServiceResponseListener
.
Antes de começar a descobrir serviços em dispositivos locais, você também precisa chamar addServiceRequest()
. Quando o WifiP2pManager.ActionListener
transmitido para esse método receber um
callback, você poderá começar a descobrir serviços em dispositivos locais chamando discoverServices()
.
Quando os serviços locais forem descobertos, você vai receber uma chamada de retorno para WifiP2pManager.DnsSdServiceResponseListener
ou WifiP2pManager.UpnpServiceResponseListener
, dependendo se você
se registrou para usar o Bonjour ou o Upnp. O callback recebido em ambos os casos contém um
objeto WifiP2pDevice
que representa o dispositivo de peering.
Uso da rede
O novo método isActiveNetworkMetered()
permite
verificar se o dispositivo está conectado a uma rede limitada. Ao verificar esse estado
antes de realizar transações intensivas de rede, você pode ajudar a gerenciar o uso de dados que pode gerar custos para os usuários e tomar
decisões informadas sobre se as transações serão feitas agora ou depois (como quando o
dispositivo for conectado ao Wi-Fi).
Acessibilidade
APIs de serviço de acessibilidade
O alcance das APIs de serviço de acessibilidade foi aumentado significativamente no Android 4.1. Agora,
é possível criar serviços que monitoram e respondem a mais eventos de entrada, como gestos complexos
usando onGesture()
e outros
eventos de entrada, por meio de adições às classes AccessibilityEvent
, AccessibilityNodeInfo
e AccessibilityRecord
.
Os serviços de acessibilidade também podem realizar ações em nome do usuário, incluindo clicar,
rolar e percorrer o texto usando performAction
e setMovementGranularities
. O método performGlobalAction()
também permite que os serviços executem ações como "Voltar", "Início" e abrir "Apps e notificações
recentes".
Navegação personalizável no app
Ao criar um app Android, agora você pode personalizar esquemas de navegação encontrando elementos
e widgets focalizáveis usando findFocus()
e focusSearch()
e definir o foco
com setAccessibilityFocused()
.
Widgets mais acessíveis
A nova classe android.view.accessibility.AccessibilityNodeProvider
permite
exibir visualizações personalizadas complexas aos serviços de acessibilidade, para que eles possam apresentar as informações de
maneira mais acessível. A android.view.accessibility.AccessibilityNodeProvider
permite que um widget
de usuário com conteúdo avançado, como uma grade de agenda, apresente uma estrutura semântica lógica para
serviços de acessibilidade totalmente separada da estrutura de layout do widget. Essa estrutura
semântica permite que os serviços de acessibilidade apresentem um modelo de interação mais útil para usuários
com deficiência visual.
Copiar e colar
Copiar e colar com intents
Agora é possível associar um objeto ClipData
a um Intent
usando o método setClipData()
.
Isso é útil principalmente ao usar uma intent para transferir vários URIs content:
para outro
aplicativo, como ao compartilhar vários documentos. Os URIs content:
fornecidos
dessa maneira também respeitarão as sinalizações da intent para oferecer acesso de leitura ou gravação, permitindo que você conceda
acesso a vários URIs em uma intent. Ao iniciar uma intent ACTION_SEND
ou ACTION_SEND_MULTIPLE
, os URIs fornecidos nela agora são
propagados automaticamente para ClipData
. Assim, o receptor pode ter
acesso a eles.
Suporte a estilos de HTML e string
A classe ClipData
agora é compatível com texto estilizado, como strings com estilo HTML ou Android. É possível adicionar texto com estilo HTML à ClipData
usando newHtmlText()
.
RenderScript
A funcionalidade de computação do Renderscript foi aprimorada com os seguintes recursos:
- Suporte a vários kernels dentro de um script.
- Suporte para leitura da alocação com amostras filtradas da computação em uma nova API de script
rsSample
. - Suporte a diferentes níveis de precisão de FP em
#pragma
. - Suporte para consultar mais informações de objetos RS de um script de computação.
- Várias melhorias de desempenho.
Novos pragmas também estão disponíveis para definir a precisão de ponto flutuante exigida pelos Renderscripts de computação. Isso permite ativar operações semelhantes às do NEON, como operações matemáticas de vetor rápido no caminho da CPU, que não seriam possíveis com o padrão IEEE 754-2008 completo.
Observação:o mecanismo gráfico experimental Renderscript foi descontinuado.
Animação
Animações de inicialização de atividades
Agora você pode iniciar um Activity
usando animações de zoom ou
suas animações personalizadas. Para especificar a animação desejada, use as APIs ActivityOptions
para criar um Bundle
que pode ser
transmitido a qualquer um dos
métodos que iniciam uma atividade, como startActivity()
.
A classe ActivityOptions
inclui um método diferente para cada
tipo de animação que você quer mostrar à medida que a atividade é aberta:
makeScaleUpAnimation()
- Cria uma animação que dimensiona a janela de atividade a partir de uma posição inicial especificada na tela e um tamanho inicial especificado. Por exemplo, a tela inicial no Android 4.1 usa isso ao abrir um app.
makeThumbnailScaleUpAnimation()
- Cria uma animação que dimensiona a janela de atividade começando de uma posição especificada e uma imagem de miniatura fornecida. Por exemplo, a janela "Apps recentes" no Android 4.1 usa isso para retornar a um app.
makeCustomAnimation()
- Cria uma animação definida pelos seus próprios recursos: uma que define a animação para a abertura da atividade e outra para a atividade que está sendo interrompida.
Animador de tempo
O novo TimeAnimator
oferece um mecanismo de callback simples com o TimeAnimator.TimeListener
, que envia notificações a cada frame da animação. Não há duração, interpolação ou definição de valor de objeto com este Animator. O callback do listener recebe informações para cada frame, incluindo o tempo total decorrido e o tempo decorrido desde o frame de animação anterior.
Interface do usuário
Notificações
No Android 4.1, é possível criar notificações com regiões de conteúdo maiores, visualizações de imagens grandes, vários botões de ação e prioridade configurável.
Estilos de notificação
O novo método setStyle()
permite especificar um dos três novos estilos para notificação, cada um oferecendo uma região de conteúdo maior. Para especificar o estilo da sua região de conteúdo grande, transmita para setStyle()
um dos seguintes objetos:
Notification.BigPictureStyle
- Para notificações que incluem um anexo de imagem grande.
Notification.BigTextStyle
- Para notificações que incluem muito texto, como um único e-mail.
Notification.InboxStyle
- Para notificações que incluem uma lista de strings, como snippets de vários e-mails.
Ações da notificação
Agora há suporte para até dois botões de ação que aparecem na parte de baixo da mensagem de notificação, independente de ela usar o estilo normal ou maior.
Para adicionar um botão de ação, chame addAction()
. Esse método usa três argumentos: um recurso drawable para um ícone,
texto para o botão e um PendingIntent
que define a ação
a ser executada.
Prioridades
Agora você pode sugerir ao sistema a importância da notificação para afetar a
ordem dela na lista, definindo
a prioridade com setPriority()
. Você
pode transmitir esse dos cinco níveis de prioridade diferentes definidos por constantes PRIORITY_*
na classe Notification
. O padrão é PRIORITY_DEFAULT
, e há dois níveis mais altos e dois mais baixos.
Notificações de alta prioridade são coisas que os usuários geralmente querem responder rapidamente, como uma nova mensagem instantânea, uma mensagem de texto ou um lembrete de evento iminente. Notificações de baixa prioridade são eventos como eventos da agenda expirados ou promoções de apps.
Controles da interface do sistema
O Android 4.0 (Ice Cream Sandwich) adicionou novas sinalizações para controlar a visibilidade dos elementos da IU do sistema, como para escurecer a aparência da barra do sistema ou fazê-la desaparecer completamente em celulares.
O Android 4.1 adiciona mais algumas flags que permitem um controle ainda maior da aparência dos elementos
da IU do sistema e do layout da atividade em relação a eles chamando setSystemUiVisibility()
e transmitindo as flags abaixo:
SYSTEM_UI_FLAG_FULLSCREEN
- Oculta a interface não essencial do sistema, como a barra de status.
Se a atividade usar a barra de ações no modo de sobreposição (ativando
android:windowActionBarOverlay
), essa sinalização também vai ocultar a barra de ação e fazer isso com uma animação coordenada ao ocultar e mostrar as duas. SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- Define o layout da atividade para usar a mesma área de tela disponível quando você
ativa
SYSTEM_UI_FLAG_FULLSCREEN
, mesmo que os elementos da interface do sistema ainda estejam visíveis. Embora partes do seu layout sejam sobrepostas pela IU do sistema, isso é útil se o app costuma ocultar e mostrar a IU do sistema comSYSTEM_UI_FLAG_FULLSCREEN
, porque evita que o layout se ajuste aos novos limites sempre que a IU do sistema é oculta ou exibida. SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- Define o layout da atividade para usar a mesma área de tela disponível quando você
ativou
SYSTEM_UI_FLAG_HIDE_NAVIGATION
(adicionado no Android 4.0), mesmo que os elementos da interface do sistema ainda estejam visíveis. Embora partes do seu layout sejam sobrepostas pela barra de navegação, isso é útil se o app costuma ocultar e mostrar a barra de navegação comSYSTEM_UI_FLAG_HIDE_NAVIGATION
, porque evita que o layout se ajuste aos novos limites sempre que a barra de navegação é oculta ou exibida. SYSTEM_UI_FLAG_LAYOUT_STABLE
- É recomendável adicionar essa flag se você estiver usando
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
e/ouSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
para garantir que, ao chamarfitSystemWindows()
em uma visualização, os limites definidos permaneçam consistentes em relação ao espaço de tela disponível. Ou seja, com essa flag definida,fitSystemWindows()
se comportará como se a visibilidade dos elementos da IU do sistema não fosse alterada, mesmo depois de você ocultar toda a IU do sistema.
Para ver mais discussões sobre as outras sinalizações de IU do sistema relacionadas, leia sobre as adicionadas no Android 4.0.
Visualizações remotas
GridLayout
e ViewStub
agora são visualizações remotas para que você possa usá-los em layouts de widgets de
apps e layouts personalizados de notificação.
Famílias de fontes
O Android 4.1 adiciona várias outras variantes do estilo de fonte Roboto, totalizando 10 variantes, e todas elas podem ser usadas por apps. Agora seus apps têm acesso ao conjunto completo de variantes leves e condensadas.
O conjunto completo de variantes de fontes Roboto disponíveis é:
- Regular
- Itálico
- Negrito
- Negrito e itálico
- Claro
- Itálico claro
- Normal condensado
- Itálico condensado
- Negrito condensado
- Negrito e itálico condensado
É possível aplicar qualquer um deles com o novo atributo fontFamily
em combinação com o atributo textStyle
.
Os valores aceitos para fontFamily
são:
"sans-serif"
para Roboto normal"sans-serif-light"
para Roboto Light"sans-serif-condensed"
para Roboto Condensed
Em seguida, é possível aplicar negrito e/ou itálico com os valores "bold"
e "italic"
de textStyle
. É possível aplicar as duas da seguinte maneira: android:textStyle="bold|italic"
.
Você também pode usar Typeface.create()
.
Por exemplo, Typeface.create("sans-serif-light", Typeface.NORMAL)
.
Framework de entrada
Vários dispositivos de entrada
A nova classe InputManager
permite que você consulte o
conjunto de dispositivos de entrada conectados no momento e se registre para receber uma notificação quando um novo dispositivo
for adicionado, modificado ou removido. Isso é particularmente útil se você está criando um jogo
que oferece suporte a vários jogadores e quer detectar quantos controles estão conectados
e quando há mudanças no número de controles.
É possível consultar todos os dispositivos de entrada conectados chamando
getInputDeviceIds()
. Isso retorna
uma matriz de números inteiros, cada um sendo um ID para um dispositivo de entrada diferente. Você pode chamar
getInputDevice()
para adquirir
um InputDevice
para um ID de dispositivo de entrada especificado.
Se você quiser ser informado quando novos dispositivos de entrada forem conectados, alterados ou desconectados,
implemente a interface InputManager.InputDeviceListener
e
registre-a com registerInputDeviceListener()
.
Vibrar para controladores de entrada
Se os dispositivos de entrada conectados tiverem os próprios recursos de vibração, agora será possível controlar
a vibração desses dispositivos usando as APIs Vibrator
existentes. Basta
chamar getVibrator()
na InputDevice
.
Permissões
Confira a seguir as novas permissões:
READ_EXTERNAL_STORAGE
- Fornece acesso de leitura protegido ao armazenamento externo. No Android 4.1, por padrão, todos os aplicativos ainda têm acesso de leitura. Isso será alterado em uma versão futura para exigir que os aplicativos solicitem explicitamente acesso de leitura usando essa permissão. Se o aplicativo já solicita acesso de gravação, ele também recebe acesso de leitura automaticamente. Há uma nova opção para ativar a restrição de acesso de leitura. Com ela, os desenvolvedores podem testar os aplicativos em relação a como o Android vai se comportar no futuro.
- android.Manifest.permission.READ_USER_DICTIONARY
- Permite que um aplicativo leia o dicionário do usuário. Isso só precisa ser exigido por um IME ou um editor de dicionário, como o app Configurações.
READ_CALL_LOG
- Permite que um aplicativo leia o registro de chamadas do sistema, que contém informações sobre chamadas recebidas e realizadas.
WRITE_CALL_LOG
- Permite que um aplicativo modifique o registro de chamadas do sistema armazenado no seu smartphone
- android.Manifest.permission.WRITE_USER_DICTIONARY
- Permite que um aplicativo grave no dicionário de palavras do usuário.
Recursos do dispositivo
O Android 4.1 inclui uma nova declaração de recurso para dispositivos dedicados
a exibir a interface do usuário em uma tela de televisão: FEATURE_TELEVISION
. Para declarar que o app exige
uma interface de televisão, declare esse recurso no arquivo de manifesto com o elemento <uses-feature>
:
<manifest ... > <uses-feature android:name="android.hardware.type.television" android:required="true" /> ... </manifest>
Esse recurso define "televisão" como uma experiência típica de televisão na sala de estar: exibida em uma tela grande, em que o usuário está sentado longe, e a forma predominante de entrada é algo como um botão direcional e geralmente não por toque ou mouse/apontador.