Nível da API: 14
O Android 4.0 (ICE_CREAM_SANDWICH
)
é uma versão de plataforma principal que adiciona uma variedade de novos recursos para usuários e desenvolvedores
de apps. Além de todos os novos recursos e APIs discutidos abaixo, o Android 4.0 é uma versão de plataforma
importante porque leva o extenso conjunto de APIs e temas holográficos do Android 3.x
para telas menores. Como desenvolvedor de apps, agora você tem uma plataforma única e um framework de API unificado
que permite desenvolver e publicar seu aplicativo com um único APK que oferece uma
experiência do usuário otimizada para celulares, tablets e muito mais usando a mesma versão do
Android: Android 4.0 (nível 14 da API) ou mais recente.
Para desenvolvedores, a plataforma Android 4.0 está disponível como um componente para download do SDK do Android. A plataforma disponível para download inclui uma biblioteca Android e uma imagem do sistema, além de um conjunto de skins de emulador e muito mais. Para começar a desenvolver ou testar no Android 4.0, use o SDK Manager do Android para fazer o download da plataforma no seu SDK.
Visão geral da API
As seções abaixo fornecem uma visão geral técnica das novas APIs no Android 4.0.
APIs sociais no Provedor de contatos
As APIs de contato definidas pelo provedor ContactsContract
foram
estendidas para oferecer suporte a novos recursos voltados a redes sociais, como um perfil pessoal para o proprietário do dispositivo e
a capacidade de os usuários convidarem contatos individuais para as redes sociais instaladas no
dispositivo.
Perfil do usuário
O Android agora inclui um perfil pessoal que representa o proprietário do dispositivo, conforme definido pela
tabela ContactsContract.Profile
. Apps sociais que mantêm uma identidade
podem contribuir com os dados do perfil do usuário criando uma nova entrada ContactsContract.RawContacts
no ContactsContract.Profile
. Ou seja, os contatos brutos que representam o usuário do dispositivo não
pertencem à tabela de contatos brutos tradicional definida pelo URI ContactsContract.RawContacts
. Em vez disso, é preciso adicionar um contato bruto de perfil na
tabela em CONTENT_RAW_CONTACTS_URI
. Os contatos brutos nessa tabela são agregados em um único perfil visível ao usuário chamado "Eu".
Adicionar um novo contato bruto ao perfil exige a permissão android.Manifest.permission#WRITE_PROFILE. Da mesma forma, para ler a tabela de perfil, é necessário solicitar a permissão android.Manifest.permission#READ_PROFILE. No entanto, a maioria dos apps não precisa ler o perfil de usuário, mesmo ao contribuir com dados para ele. Ler o perfil do usuário é uma permissão confidencial, e os usuários não devem ser céticos em relação aos apps que a solicitam.
Intenção de convite
A ação da intent INVITE_CONTACT
permite que um app
invoque uma ação que indica que o usuário quer adicionar um contato a uma rede social. O app
que recebe o app o usa para convidar o contato especificado para essa
rede social. A maioria dos apps estará no receptor dessa operação. Por exemplo, o
app Pessoas integrado invoca a intent de convite quando o usuário seleciona "Adicionar conexão" para um
app social específico listado nos detalhes de contato da pessoa.
Para que seu app fique visível na lista "Adicionar conexão", ele precisa fornecer um adaptador de sincronização para
sincronizar dados de contato da sua rede social. Em seguida, indique ao sistema que seu
app responde à intent INVITE_CONTACT
adicionando o atributo inviteContactActivity
ao arquivo de configuração de sincronização do app, com um
nome totalmente qualificado da atividade que o sistema precisa iniciar ao enviar a intent de convite.
A atividade iniciada pode recuperar o URI do contato em questão nos dados
da intent e realizar o trabalho necessário para convidar esse contato para a rede ou adicionar a pessoa às
conexões do usuário.
Fotos grandes
O Android agora oferece suporte a fotos em alta resolução para seus contatos. Agora, quando você envia uma foto para um
registro de contato, o sistema a processa em uma miniatura de 96 x 96 (como antes) e uma
"foto de exibição" de 256 x 256 que é armazenada em um novo repositório de fotos baseado em arquivo. As dimensões exatas que o
sistema escolhe podem variar no futuro. É possível adicionar uma foto grande a um contato colocando uma foto grande
na coluna PHOTO
normal de uma
linha de dados, que o sistema processará na miniatura adequada e exibirá os registros
das fotos.
Entrar em contato com feedback de uso
As novas APIs ContactsContract.DataUsageFeedback
permitem rastrear
com que frequência o usuário usa métodos específicos de contato, como com que frequência o usuário usa
cada número de telefone ou endereço de e-mail. Essas informações ajudam a melhorar a classificação de cada método de contato associado a cada pessoa e fornecem melhores sugestões para entrar em contato com cada pessoa.
Provedor de agenda
Com as novas APIs Agenda, é possível ler, adicionar, modificar e excluir agendas, eventos, convidados, lembretes e alertas, que são armazenados no Provedor de Agenda.
Diversos aplicativos e widgets podem usar essas APIs para ler e modificar eventos da agenda. No entanto, alguns dos casos de uso mais interessantes são os adaptadores de sincronização que sincronizam a agenda do usuário de outros serviços com o provedor para oferecer um local unificado para todos os eventos do usuário. Por exemplo, os eventos do Google Agenda são sincronizados com o Provedor de Agenda pelo adaptador de sincronização do Google Agenda. Isso permite que esses eventos sejam visualizados com o app Agenda integrado ao Android.
O modelo de dados de agendas e informações relacionadas a eventos no Provedor de Agenda é definido por CalendarContract
. Todos os dados da agenda do usuário são armazenados em
várias tabelas definidas por várias subclasses de CalendarContract
:
- A tabela
CalendarContract.Calendars
contém as informações específicas da agenda. Cada linha nessa tabela contém os detalhes de uma única agenda, como nome, cor, informações de sincronização etc. - A tabela
CalendarContract.Events
contém informações específicas do evento. Cada linha nessa tabela contém as informações de um único evento, como título, local, horário de início, de término etc. O evento pode ocorrer uma vez ou se repetir várias vezes. Os participantes, lembretes e propriedades estendidas são armazenados em tabelas separadas e usam o_ID
do evento para vinculá-los ao evento. - A tabela
CalendarContract.Instances
contém os horários de início e término das ocorrências de um evento. Cada linha nesta tabela representa uma única ocorrência. Para eventos únicos, há um mapeamento individual de instâncias para eventos. Para eventos recorrentes, várias linhas são geradas automaticamente para corresponder às várias ocorrências desse evento. - A tabela
CalendarContract.Attendees
contém as informações dos participantes do evento. Cada linha representa um único convidado de um evento. Ela especifica o tipo de convidado que a pessoa é e a resposta da pessoa para o evento. - A tabela
CalendarContract.Reminders
contém os dados de alerta/notificação. Cada linha representa um único alerta de um evento. Um evento pode ter vários lembretes. O número de lembretes por evento é especificado emMAX_REMINDERS
, que é definido pelo adaptador de sincronização que tem a agenda especificada. Os lembretes são especificados em minutos antes do evento ser agendado e especificam um método de alarme, como usar um alerta, e-mail ou SMS para lembrar o usuário. - A tabela
CalendarContract.ExtendedProperties
contém campos de dados opacos usados pelo adaptador de sincronização. O provedor não realiza nenhuma ação com os itens dessa tabela, exceto os que são excluídos quando os eventos relacionados são excluídos.
Para acessar os dados da agenda de um usuário com o Provedor de agenda, seu aplicativo precisa solicitar
a permissão READ_CALENDAR
(para acesso de leitura) e
WRITE_CALENDAR
(para acesso de gravação).
Intent de evento
Se você quiser apenas adicionar um evento à agenda do usuário, use uma intent ACTION_INSERT
com os dados definidos por Events.CONTENT_URI
para iniciar uma atividade no app Agenda que crie novos eventos. O uso da intent não requer nenhuma
permissão, e você pode especificar detalhes do evento com os extras abaixo:
Events.TITLE
: nome do evento.CalendarContract.EXTRA_EVENT_BEGIN_TIME
: horário de início do evento em milissegundos a partir da épocaCalendarContract.EXTRA_EVENT_END_TIME
: horário de término do evento em milissegundos a partir da épocaEvents.EVENT_LOCATION
: local do evento.Events.DESCRIPTION
: descrição do eventoIntent.EXTRA_EMAIL
: endereços de e-mail das pessoas a serem convidadas.Events.RRULE
: a regra de recorrência do eventoEvents.ACCESS_LEVEL
: se o evento é privado ou públicoEvents.AVAILABILITY
: se o período desse evento permite que outros eventos sejam programados para o mesmo horário.
Provedor de correio de voz
O novo provedor de correio de voz permite que os aplicativos adicionem correios de voz ao dispositivo para apresentar todos os correios de voz do usuário em uma única apresentação visual. Por exemplo, é possível que um usuário tenha várias origens de correio de voz, como uma do provedor de serviços do smartphone e outras por VoIP ou outros serviços de voz alternativos. Esses apps podem usar as APIs do provedor de correio de voz para adicionar correios de voz ao dispositivo. O app integrado Telefone apresenta todos os correios de voz para o usuário em uma apresentação unificada. Embora o app Telefone do sistema seja o único que possa ler todos os correios de voz, cada app que fornece correios de voz pode ler aqueles adicionados ao sistema, mas não ler os correios de voz de outros serviços.
Como as APIs não permitem que apps de terceiros leiam todos os correios de voz do sistema, os únicos apps de terceiros que precisam usar as APIs são aqueles que têm correio de voz para entregar ao usuário.
A classe VoicemailContract
define o provedor de conteúdo do
Voicemail Provder. As subclasses VoicemailContract.Voicemails
e VoicemailContract.Status
fornecem tabelas em que os apps podem
inserir dados do correio de voz para armazenamento no dispositivo. Para ver um exemplo de app de provedor de correio de voz, consulte a Demonstração do provedor de correio de voz.
Multimídia
O Android 4.0 adiciona várias novas APIs para aplicativos que interagem com mídia como fotos, vídeos e músicas.
Efeitos de mídia
Um novo framework de efeitos de mídia permite aplicar vários efeitos visuais a imagens e vídeos. Por exemplo, os efeitos de imagem permitem corrigir olhos vermelhos, converter uma imagem para escala de cinza, ajustar o brilho, ajustar a saturação, girar uma imagem, aplicar um efeito olho de peixe e muito mais. O sistema executa todos os processamentos de efeitos na GPU para conseguir o desempenho máximo.
Para o desempenho máximo, os efeitos são aplicados diretamente às texturas do OpenGL. Portanto, seu aplicativo precisa ter um contexto OpenGL válido antes de usar as APIs de efeitos. As texturas em que você aplica efeitos podem ser de bitmaps, vídeos ou até mesmo da câmera. No entanto, existem certas restrições a que as texturas precisam atender:
- Eles precisam estar vinculados a uma imagem de textura
GL_TEXTURE_2D
. - Eles precisam conter pelo menos um nível de mipmap
Um objeto Effect
define um único efeito de mídia que pode ser aplicado a
um frame de imagem. O fluxo de trabalho básico para criar uma Effect
é o seguinte:
- Chame
EffectContext.createWithCurrentGlContext()
no contexto do OpenGL ES 2.0. - Use o
EffectContext
retornado para chamarEffectContext.getFactory()
, que retorna uma instância deEffectFactory
. - Chame
createEffect()
, transmitindo um nome de efeito de @link android.media.effect.EffectFactory}, comoEFFECT_FISHEYE
ouEFFECT_VIGNETTE
.
Para ajustar os parâmetros de um efeito, chame setParameter()
e transmita um nome e um valor de parâmetro. Cada tipo de efeito aceita
parâmetros diferentes, que são documentados com o nome do efeito. Por exemplo, EFFECT_FISHEYE
tem um parâmetro para o scale
da distorção.
Para aplicar um efeito a uma textura, chame apply()
no
Effect
e transmita a textura de entrada, a largura, a altura e a textura
de saída. A textura de entrada precisa estar vinculada a uma imagem de textura
GL_TEXTURE_2D
. Isso geralmente é feito chamando a função
glTexImage2D()
. Você pode fornecer vários níveis de mipmap. Se a textura de saída não tiver sido vinculada a uma
imagem de textura, ela será vinculada automaticamente pelo efeito como uma GL_TEXTURE_2D
e com um nível de mipmap (0), que terá o mesmo
tamanho da entrada.
Todos os efeitos listados em EffectFactory
têm suporte garantido.
No entanto, alguns outros efeitos disponíveis de bibliotecas externas não têm suporte de todos os dispositivos.
Portanto, primeiro é necessário verificar se o efeito desejado da biblioteca externa tem suporte chamando
isEffectSupported()
.
Cliente de controle remoto
O novo RemoteControlClient
permite que players de mídia ativem controles
de reprodução a partir de clientes de controle remoto, como a tela de bloqueio do dispositivo. Os players de mídia também podem expor
informações sobre a mídia que está sendo reproduzida no controle remoto, como informações
de faixas e capa do álbum.
Para ativar clientes de controle remoto para o player de mídia, instancie um RemoteControlClient
com o construtor dele, transmitindo um PendingIntent
que transmita ACTION_MEDIA_BUTTON
. A intent também precisa declarar o componente BroadcastReceiver
explícito no app que processa o evento ACTION_MEDIA_BUTTON
.
Para declarar quais entradas de controle de mídia o player pode processar, chame setTransportControlFlags()
no
RemoteControlClient
, transmitindo um conjunto de flags de FLAG_KEY_MEDIA_*
, como
FLAG_KEY_MEDIA_PREVIOUS
e FLAG_KEY_MEDIA_NEXT
.
Em seguida, registre seu RemoteControlClient
transmitindo-o para MediaManager.registerRemoteControlClient()
.
Após o registro, o broadcast receiver que você declarou quando instanciou o RemoteControlClient
vai receber eventos
ACTION_MEDIA_BUTTON
quando um botão for pressionado em um controle remoto. A intent recebida inclui o KeyEvent
para a tecla de mídia pressionada, que pode ser extraída da intent com getParcelableExtra(Intent.EXTRA_KEY_EVENT)
.
Para mostrar informações no controle remoto sobre a mídia em reprodução, chame editMetaData()
e adicione metadados ao RemoteControlClient.MetadataEditor
retornado. Você pode fornecer um bitmap para artes de mídia,
informações numéricas, como tempo decorrido, e informações de texto, como o título da faixa. Para mais informações sobre as chaves disponíveis, consulte as sinalizações METADATA_KEY_*
em MediaMetadataRetriever
.
Para conferir um exemplo de implementação, consulte o Random Music Player, que fornece uma lógica de compatibilidade para ativar o cliente de controle remoto em dispositivos Android 4.0 e, ao mesmo tempo, manter a compatibilidade com dispositivos até o Android 2.1.
Player de mídia
- O streaming de mídia on-line de
MediaPlayer
agora exige a permissãoINTERNET
. Se você usarMediaPlayer
para reproduzir conteúdo da Internet, adicione a permissãoINTERNET
ao manifesto. Caso contrário, a reprodução de mídia não funcionará a partir do Android 4.0. setSurface()
permite que você defina umSurface
para se comportar como o coletor de vídeo.setDataSource()
permite que você envie cabeçalhos HTTP adicionais com sua solicitação, o que pode ser útil para transmissões ao vivo HTTP(S)- A transmissão ao vivo de HTTP(S) agora respeita cookies HTTP nas solicitações
Tipos de mídia
O Android 4.0 adiciona suporte para:
- Protocolo de transmissão ao vivo HTTP/HTTPS versão 3
- Codificação de áudio AAC bruto ADTS
- Imagens WEBP
- Vídeo de Matroska
Para saber mais, consulte Formatos de mídia compatíveis.
Câmera
A classe Camera
agora inclui APIs para detectar rostos e controlar
áreas de foco e medição.
Detecção facial
Agora, os apps de câmera podem aprimorar as próprias habilidades com as APIs de detecção facial do Android, que não apenas detectam o rosto de uma pessoa, mas também características faciais específicas, como os olhos e a boca.
Para detectar rostos no aplicativo de câmera, registre um Camera.FaceDetectionListener
chamando setFaceDetectionListener()
. Em seguida, é possível iniciar
a superfície da câmera e começar a detectar rostos chamando startFaceDetection()
.
Quando o sistema detecta um ou mais rostos na cena da câmera, ele chama o callback onFaceDetection()
na
implementação de Camera.FaceDetectionListener
, incluindo uma matriz de
objetos Camera.Face
.
Uma instância da classe Camera.Face
fornece várias informações sobre
o rosto detectado, incluindo:
- Um
Rect
que especifica os limites do rosto em relação ao campo de visão atual da câmera. - Um número inteiro entre 1 e 100 que indica o nível de confiança do sistema de que o objeto é um rosto humano.
- Um ID exclusivo para que você possa rastrear vários rostos
- Vários objetos
Point
que indicam onde os olhos e a boca estão localizados
Observação:a detecção facial pode não ser compatível com alguns
dispositivos. Por isso, chame getMaxNumDetectedFaces()
e confira se o valor de retorno
é maior que zero. Além disso, alguns dispositivos podem não oferecer suporte à identificação de olhos e boca.
Nesse caso, os campos no objeto Camera.Face
serão nulos.
Áreas de foco e medição
Os apps de câmera agora podem controlar as áreas que a câmera usa para foco e para medir o
balanço de branco
e a exposição automática. Os dois recursos usam a nova classe Camera.Area
para especificar
a região da visualização atual da câmera que precisa ser focada ou limitada. Uma instância da classe Camera.Area
define os limites da área com um Rect
e o peso dela, representando o nível de importância dela, em relação a outras áreas em questão, com um número inteiro.
Antes de definir uma área de foco ou uma área de medição, chame getMaxNumFocusAreas()
ou getMaxNumMeteringAreas()
, respectivamente. Se eles retornarem zero, significa
que o dispositivo não oferece suporte ao recurso correspondente.
Para especificar as áreas de foco ou de medição a serem usadas, basta chamar setFocusAreas()
ou setMeteringAreas()
. Cada um usa uma List
de objetos Camera.Area
que indicam as áreas a serem consideradas
para foco ou medição. Por exemplo, você pode implementar um recurso que permite ao usuário definir a
área de foco tocando em uma área da visualização, que você traduz em um objeto Camera.Area
e solicita que a câmera centralize o foco nessa área da cena.
O foco ou a exposição nessa área é atualizado continuamente conforme a cena muda.
Foco automático contínuo para fotos
Agora você pode ativar o foco automático contínuo (CAF) ao tirar fotos. Para ativar o CAF no seu
app de câmera, transmita FOCUS_MODE_CONTINUOUS_PICTURE
para setFocusMode()
. Quando estiver tudo pronto para capturar
uma foto, chame autoFocus()
. Seu Camera.AutoFocusCallback
recebe imediatamente um callback para indicar se
o foco foi alcançado. Para retomar o CAF depois de receber o callback, chame cancelAutoFocus()
.
Observação:o foco automático contínuo também é compatível ao capturar
vídeos usando FOCUS_MODE_CONTINUOUS_VIDEO
, que foi
adicionado no nível 9 da API.
Outros recursos da câmera
- Ao gravar um vídeo, agora você pode chamar
takePicture()
para salvar uma foto sem interromper a sessão de vídeo. Antes de fazer isso, chameisVideoSnapshotSupported()
para ter certeza de que o hardware tem suporte. - Agora, você pode bloquear a exposição automática e o balanço de branco com
setAutoExposureLock()
esetAutoWhiteBalanceLock()
para evitar que essas propriedades mudem. - Agora você pode chamar
setDisplayOrientation()
enquanto a visualização da câmera está em execução. Antes, era possível chamar isso apenas antes de iniciar a visualização, mas agora é possível mudar a orientação a qualquer momento.
Intents de transmissão da câmera
Camera.ACTION_NEW_PICTURE
: indica que o usuário capturou uma nova foto. O app Câmera integrado invoca essa transmissão depois que uma foto é capturada, e apps de câmera de terceiros também precisam transmitir essa intent depois de capturar uma foto.Camera.ACTION_NEW_VIDEO
: indica que o usuário capturou um novo vídeo. O app Câmera integrado invoca essa transmissão depois que um vídeo é gravado, e apps de câmera de terceiros também precisam transmitir essa intent após capturar um vídeo.
Android Beam (envio NDEF com NFC)
O Android Beam é um novo recurso NFC que permite enviar mensagens NDEF de um dispositivo para outro (um processo também conhecido como "envio de NDEF"). A transferência de dados é iniciada quando dois dispositivos Android compatíveis com o Android Beam estão próximos (cerca de 4 cm), geralmente com as costas encostadas. Os dados dentro da mensagem NDEF podem conter qualquer dado que você queira compartilhar entre dispositivos. Por exemplo, o app Pessoas compartilha contatos, o YouTube compartilha vídeos, e o navegador compartilha URLs usando o Android Beam.
Para transmitir dados entre dispositivos usando o Android Beam, é necessário criar uma NdefMessage
que contenha as informações que você quer compartilhar enquanto a atividade estiver em
primeiro plano. Em seguida, transmita o NdefMessage
para o sistema de duas
maneiras:
- Defina um único
NdefMessage
para enviar durante a atividade:Chame
setNdefPushMessage()
a qualquer momento para definir a mensagem que você quer enviar. Por exemplo, você pode chamar esse método e transmitir a ele oNdefMessage
durante o métodoonCreate()
da atividade. Em seguida, sempre que o Android Beam for ativado com outro dispositivo enquanto a atividade estiver em primeiro plano, o sistema vai enviar aNdefMessage
para o outro dispositivo. - Defina o
NdefMessage
para enviar no momento em que o Android Beam for iniciado:Implemente
NfcAdapter.CreateNdefMessageCallback
, em que a implementação do métodocreateNdefMessage()
retorna oNdefMessage
que você quer enviar. Em seguida, transmita a implementação deNfcAdapter.CreateNdefMessageCallback
parasetNdefPushMessageCallback()
.Nesse caso, quando o Android Beam é ativado com outro dispositivo enquanto sua atividade está em primeiro plano, o sistema chama
createNdefMessage()
para extrair oNdefMessage
que você quer enviar. Isso permite definir oNdefMessage
para ser entregue somente quando o Android Beam for iniciado, caso o conteúdo da mensagem possa variar durante a vida útil da atividade.
Caso você queira executar um código específico depois que o sistema entregar a mensagem NDEF ao outro dispositivo, implemente NfcAdapter.OnNdefPushCompleteCallback
e defina-o com setNdefPushCompleteCallback()
. O sistema
chamará onNdefPushComplete()
quando a mensagem for entregue.
No dispositivo receptor, o sistema envia mensagens de push NDEF de maneira semelhante a tags NFC normais. O sistema invoca uma intent com a ação ACTION_NDEF_DISCOVERED
para iniciar uma atividade, com um URL ou um tipo MIME definido de acordo com a primeira NdefRecord
da NdefMessage
. Para a atividade que você quer
responder, é possível declarar filtros de intent para os URLs ou tipos MIME importantes para seu app. Para mais informações sobre o envio de tags, consulte o guia para desenvolvedores de NFC.
Se você quiser que NdefMessage
contenha um URI, agora poderá usar o método
de conveniência createUri
para construir um novo NdefRecord
com base em uma string ou um objeto Uri
. Se o URI for um formato especial que você quer que seu aplicativo também receba durante um evento do Android Beam, crie um filtro de intent para sua atividade usando o mesmo esquema de URI para receber a mensagem NDEF recebida.
Você também precisa transmitir um "registro de aplicativo Android" com o NdefMessage
para garantir que o aplicativo processe a mensagem NDEF recebida, mesmo que outros aplicativos filtrem a mesma ação da intent. É possível criar um registro de app Android
chamando createApplicationRecord()
e transmitindo
o nome do pacote do app. Quando o outro dispositivo recebe a mensagem NDEF com o registro do aplicativo e vários aplicativos contêm atividades que processam a intent especificada, o sistema sempre entrega a mensagem à atividade no seu aplicativo, com base no registro correspondente. Se o dispositivo de destino não tiver o app instalado, o
sistema vai usar o registro do app Android para iniciar o Google Play e direcionar o usuário ao
app para fazer a instalação.
Se o aplicativo não usa APIs NFC para realizar mensagens push NDEF, o Android oferece um comportamento padrão: quando seu aplicativo está em primeiro plano em um dispositivo e o Android Beam é invocado com outro dispositivo Android, o outro dispositivo recebe uma mensagem NDEF com um registro de aplicativo Android que identifica seu aplicativo. Se o dispositivo receptor tiver o aplicativo instalado, o sistema o iniciará. Se não estiver, o Google Play será aberto e levará o usuário ao seu aplicativo para instalá-lo.
Você pode ler mais sobre o Android Beam e outros recursos de NFC no guia do desenvolvedor Noções básicas de NFC. Para conferir alguns exemplos de código que usam o Android Beam, consulte a Demonstração do Beam do Android.
Wi-Fi P2P
O Android agora oferece suporte a conexões Wi-Fi ponto a ponto (P2P) entre dispositivos com tecnologia Android e outros tipos (em conformidade com o programa de certificação Wi-Fi DirectTM da Wi-Fi Alliance) sem um ponto de acesso ou conexão de Internet. O framework do Android oferece um conjunto de APIs de Wi-Fi P2P que permitem descobrir e se conectar a outros dispositivos quando cada um oferece suporte ao Wi-Fi P2P. Depois, é possível se comunicar por uma conexão rápida em distâncias muito maiores do que uma conexão Bluetooth.
Um novo pacote, android.net.wifi.p2p
, contém todas as APIs para realizar conexões
ponto a ponto com Wi-Fi. A classe principal com que você precisa trabalhar é a WifiP2pManager
, que pode ser adquirida chamando getSystemService(WIFI_P2P_SERVICE)
. O WifiP2pManager
inclui APIs que permitem:
- Inicialize seu aplicativo para conexões P2P chamando
initialize()
. - Ligue para
discoverPeers()
e descubra dispositivos por perto - Inicie uma conexão P2P chamando
connect()
. - E muito mais
Várias outras interfaces e classes também são necessárias, como:
- A interface
WifiP2pManager.ActionListener
permite que você receba callbacks quando uma operação como descobrir pares ou conectar-se a eles for bem-sucedida ou falhar. WifiP2pManager.PeerListListener
permite que você receba informações sobre pares descobertos. O callback fornece umWifiP2pDeviceList
, da qual é possível recuperar um objetoWifiP2pDevice
para cada dispositivo dentro do alcance e receber informações como nome, endereço, tipo de dispositivo, configurações WPS com suporte e muito mais.- A interface
WifiP2pManager.GroupInfoListener
permite que você receba informações sobre um grupo P2P. O callback fornece um objetoWifiP2pGroup
, que fornece informações do grupo, como o proprietário, o nome da rede e a senha longa. - A interface
WifiP2pManager.ConnectionInfoListener
permite que você receba informações sobre a conexão atual. O callback fornece um objetoWifiP2pInfo
, que contém informações, por exemplo, se um grupo foi formado e quem é o proprietário dele.
Para usar as APIs de Wi-Fi P2P, seu aplicativo precisa solicitar as seguintes permissões de usuário:
ACCESS_WIFI_STATE
CHANGE_WIFI_STATE
INTERNET
, embora seu app não se conecte tecnicamente à Internet, a comunicação com pares Wi-Fi P2P com soquetes Java padrão requer permissão de Internet.
O sistema Android também transmite várias ações diferentes durante certos eventos de Wi-Fi P2P:
WIFI_P2P_CONNECTION_CHANGED_ACTION
: o estado da conexão P2P mudou. Isso carregaEXTRA_WIFI_P2P_INFO
com um objetoWifiP2pInfo
eEXTRA_NETWORK_INFO
com um objetoNetworkInfo
.WIFI_P2P_STATE_CHANGED_ACTION
: o estado P2P mudou entre ativado e desativado. Ele carregaEXTRA_WIFI_STATE
comWIFI_P2P_STATE_DISABLED
ouWIFI_P2P_STATE_ENABLED
.WIFI_P2P_PEERS_CHANGED_ACTION
: a lista de dispositivos de peering mudou.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION
: os detalhes deste dispositivo mudaram.
Consulte a documentação do WifiP2pManager
para mais informações. Consulte também o aplicativo de exemplo Demonstração do Wi-Fi P2P.
Dispositivos de saúde Bluetooth
O Android agora oferece suporte a dispositivos com perfil de saúde Bluetooth. Assim, é possível criar aplicativos que usam o Bluetooth para se comunicar com dispositivos de saúde compatíveis com Bluetooth, como monitores de frequência cardíaca, medidores de sangue, termômetros e balanças.
Assim como nos dispositivos com perfil de fone de ouvido e A2DP comuns, você precisa chamar getProfileProxy()
com um BluetoothProfile.ServiceListener
e o tipo de perfil HEALTH
para estabelecer uma conexão com o objeto de proxy
de perfil.
Depois de adquirir o proxy do perfil de saúde (o objeto BluetoothHealth
), a conexão e a comunicação com dispositivos de saúde pareados envolvem estas novas
classes do Bluetooth:
BluetoothHealthCallback
: você precisa estender essa classe e implementar os métodos de callback para receber atualizações sobre mudanças no estado de registro do aplicativo e no estado do canal Bluetooth.BluetoothHealthAppConfiguration
: durante callbacks para oBluetoothHealthCallback
, você vai receber uma instância desse objeto, que fornece informações de configuração sobre o dispositivo de integridade Bluetooth disponível, que você precisa usar para executar várias operações, como iniciar e encerrar conexões com as APIsBluetoothHealth
.
Para mais informações sobre como usar o perfil de saúde do Bluetooth, consulte a documentação de BluetoothHealth
.
Acessibilidade
O Android 4.0 melhora a acessibilidade para usuários com deficiência visual com o novo modo de exploração por toque e APIs estendidas que permitem fornecer mais informações sobre o conteúdo de visualização ou desenvolver serviços avançados de acessibilidade.
Modo Explorar por toque
Usuários com perda de visão agora podem explorar a tela tocando e arrastando um dedo pela
tela para ouvir descrições de voz do conteúdo. Como o modo de exploração por toque funciona como um
cursor virtual, ele permite que os leitores de tela identifiquem o texto descritivo da mesma forma que os leitores
de tela fazem quando o usuário navega com um botão direcional ou trackball, lendo as informações fornecidas
por android:contentDescription
e setContentDescription()
em um evento "passar o cursor" simulado. Portanto,
considere que você precisa fornecer um texto descritivo para as visualizações do
aplicativo, especialmente para ImageButton
, EditText
,
ImageView
e outros widgets que podem não conter texto
descritivo natural.
Acessibilidade para visualizações
Para melhorar as informações disponíveis para os serviços de acessibilidade, como leitores de tela, você pode
implementar novos métodos de callback para eventos de acessibilidade nos seus componentes View
personalizados.
É importante observar primeiro que o comportamento do método sendAccessibilityEvent()
mudou no Android
4.0. Assim como na versão anterior do Android, quando o usuário ativa os serviços de acessibilidade no dispositivo
e ocorre um evento de entrada, como um clique ou o cursor, a respectiva visualização é notificada com uma chamada para
sendAccessibilityEvent()
. Anteriormente, a
implementação de sendAccessibilityEvent()
inicializava
um AccessibilityEvent
e o enviava para AccessibilityManager
. O novo comportamento envolve alguns outros métodos de callback
que permitem que a visualização e os pais adicionem mais informações contextuais ao evento:
- Quando invocados, os métodos
sendAccessibilityEvent()
esendAccessibilityEventUnchecked()
são adiados paraonInitializeAccessibilityEvent()
.Implementações personalizadas de
View
podem querer implementaronInitializeAccessibilityEvent()
para anexar outras informações de acessibilidade aoAccessibilityEvent
, mas também chamar a superimplementação para fornecer informações padrão, como a descrição de conteúdo padrão, o índice de itens e muito mais. No entanto, não adicione mais conteúdo de texto nesse callback, que será feito em seguida. - Depois de inicializado, se o evento for um dos vários tipos que precisam ser preenchidos com informações
de texto, a visualização receberá uma chamada para
dispatchPopulateAccessibilityEvent()
, que é adiada para o callbackonPopulateAccessibilityEvent()
.As implementações personalizadas de
View
geralmente precisam implementaronPopulateAccessibilityEvent()
para adicionar mais conteúdo de texto aoAccessibilityEvent
se o textoandroid:contentDescription
estiver ausente ou insuficiente. Para adicionar mais descrições de texto àAccessibilityEvent
, chamegetText()
.add()
. - Nesse ponto, o
View
transmite o evento para cima da hierarquia de visualização chamandorequestSendAccessibilityEvent()
na visualização mãe. Cada visualização mãe tem a chance de aumentar as informações de acessibilidade adicionando umAccessibilityRecord
, até que ele chegue à visualização raiz, que envia o evento para aAccessibilityManager
comsendAccessibilityEvent()
.
Além dos novos métodos acima, que são úteis ao estender a classe View
, também é possível interceptar esses callbacks de eventos em qualquer View
estendendo AccessibilityDelegate
e definindo-o na visualização com
setAccessibilityDelegate()
.
Quando você faz isso, cada método de acessibilidade na visualização adia a chamada para o método correspondente
no delegado. Por exemplo, quando a visualização recebe uma chamada para onPopulateAccessibilityEvent()
, ela é transmitida para o
mesmo método no View.AccessibilityDelegate
. Todos os métodos não processados pelo
delegado são retornados diretamente à visualização para o comportamento padrão. Isso permite substituir apenas
os métodos necessários para qualquer visualização sem estender a classe View
.
Se você quiser manter a compatibilidade com versões do Android anteriores à 4.0 e, ao mesmo tempo, oferecer suporte às novas APIs de acessibilidade, faça isso com a versão mais recente da Biblioteca de Suporte v4 (no Pacote de compatibilidade, r4) usando um conjunto de classes de utilitários que fornecem as novas APIs de acessibilidade em um design compatível com versões anteriores.
Serviços de acessibilidade
Se você estiver desenvolvendo um serviço de acessibilidade, as informações sobre vários eventos de acessibilidade foram significativamente expandidas para permitir um feedback mais avançado para os usuários. Em particular, os eventos são gerados com base na composição da visualização, fornecendo melhores informações de contexto e permitindo que os serviços de acessibilidade percorram hierarquias de visualização para receber mais informações de visualização e lidar com casos especiais.
Se você estiver desenvolvendo um serviço de acessibilidade (como um leitor de tela), poderá acessar mais informações de conteúdo e transferir hierarquias de visualização com o seguinte procedimento:
- Ao receber um
AccessibilityEvent
de um aplicativo, chameAccessibilityEvent.getRecord()
para recuperar umAccessibilityRecord
específico (pode haver vários registros anexados ao evento). - Na
AccessibilityEvent
ou em umaAccessibilityRecord
individual, é possível chamargetSource()
para extrair um objetoAccessibilityNodeInfo
.Um
AccessibilityNodeInfo
representa um único nó do conteúdo da janela em um formato que permite consultar informações de acessibilidade sobre esse nó. O objetoAccessibilityNodeInfo
retornado deAccessibilityEvent
descreve a origem do evento, enquanto a origem de umAccessibilityRecord
descreve o predecessor da origem do evento. - Com o
AccessibilityNodeInfo
, é possível consultar informações sobre ele, chamargetParent()
ougetChild()
para percorrer a hierarquia de visualização e até mesmo adicionar visualizações filhas ao nó.
Para que o aplicativo se publique no sistema como um serviço de acessibilidade, ele
precisa declarar um arquivo de configuração XML correspondente a AccessibilityServiceInfo
. Para saber mais sobre como criar um
serviço de acessibilidade, consulte AccessibilityService
e SERVICE_META_DATA
para saber mais sobre a configuração XML.
Outras APIs de acessibilidade
Se você tiver interesse no estado de acessibilidade do dispositivo, o AccessibilityManager
tem algumas novas APIs, como:
AccessibilityManager.AccessibilityStateChangeListener
é uma interface que permite receber um callback sempre que a acessibilidade é ativada ou desativada.getEnabledAccessibilityServiceList()
fornece informações sobre quais serviços de acessibilidade estão ativados no momento.isTouchExplorationEnabled()
informa se o modo de exploração por toque está ativado.
Serviços de corretor ortográfico
Um novo framework de corretor ortográfico permite que os apps criem verificadores ortográficos de maneira semelhante ao
framework do método de entrada (para IMEs). Para criar um novo corretor ortográfico, é necessário implementar um serviço que
estende
SpellCheckerService
e estenda a classe SpellCheckerService.Session
para fornecer sugestões de ortografia com base
no texto fornecido pelos métodos de callback da interface. Nos métodos de callback SpellCheckerService.Session
, é necessário retornar as sugestões de ortografia como objetos SuggestionsInfo
.
Os aplicativos com um serviço de corretor ortográfico precisam declarar a permissão BIND_TEXT_SERVICE
conforme exigido pelo serviço.
O serviço também precisa declarar um filtro de intent com <action
android:name="android.service.textservice.SpellCheckerService" />
como a ação da intent e
incluir um elemento <meta-data>
que declare informações de configuração para o corretor
ortográfico.
Confira o app de exemplo Ortografia do serviço e o exemplo do app de cliente do Corretor ortográfico (link em inglês) para conferir o código de exemplo.
Mecanismos de conversão de texto em voz
As APIs de conversão de texto em voz (TTS) do Android foram significativamente estendidas para permitir que os aplicativos implementem mecanismos de TTS personalizados com mais facilidade, enquanto os aplicativos que querem usar um mecanismo TTS têm algumas novas APIs para selecionar um mecanismo.
Como usar mecanismos de conversão de texto em voz
Nas versões anteriores do Android, você podia usar a classe TextToSpeech
para realizar operações de conversão de texto em voz (TTS) usando o mecanismo TTS fornecido pelo sistema ou definir um
mecanismo personalizado usando setEngineByPackageName()
. No Android 4.0, o método setEngineByPackageName()
foi
descontinuado, e agora você pode especificar o mecanismo a ser usado com um novo construtor TextToSpeech
, que aceita o nome do pacote de um mecanismo de TTS.
Também é possível consultar os mecanismos de TTS disponíveis usando getEngines()
. Esse método retorna uma lista de objetos TextToSpeech.EngineInfo
, que incluem metadados como o ícone,
o rótulo e o nome do pacote do mecanismo.
Como criar mecanismos de conversão de texto em voz
Anteriormente, os mecanismos personalizados exigiam que o mecanismo fosse criado usando um arquivo principal nativo não documentado. No Android 4.0, há um conjunto completo de APIs de estrutura para a criação de mecanismos TTS.
A configuração básica requer uma implementação de TextToSpeechService
que
responda à intent INTENT_ACTION_TTS_SERVICE
. O
trabalho principal para um mecanismo de TTS acontece durante o callback onSynthesizeText()
em um serviço
que estende TextToSpeechService
. O sistema entrega dois objetos
do método:
SynthesisRequest
: contém vários dados, incluindo o texto a sintetizar, a localidade, a taxa de fala e o tom de voz.SynthesisCallback
: é a interface pela qual o mecanismo TTS envia os dados de fala resultantes como streaming de áudio. Primeiro, o mecanismo precisa chamarstart()
para indicar que está pronto para enviar o áudio e, em seguida, chamaraudioAvailable()
, transmitindo os dados de áudio em um buffer de bytes. Depois que o mecanismo tiver transmitido todo o áudio pelo buffer, chamedone()
.
Agora que o framework é compatível com uma API verdadeira para a criação de mecanismos TTS, o suporte para implementação de código nativo foi removido. Procure uma postagem do blog sobre uma camada de compatibilidade que pode ser usada para converter seus mecanismos de TTS antigos para o novo framework.
Para ver um exemplo de mecanismo de TTS usando as novas APIs, consulte o app de exemplo Mecanismo de conversão de texto em voz.
Uso da rede
O Android 4.0 oferece aos usuários visibilidade precisa da quantidade de dados de rede que os aplicativos estão usando. O app Configurações oferece controles que permitem aos usuários gerenciar limites definidos para o uso de dados de rede e até mesmo desativar o uso de dados em segundo plano para apps individuais. Para evitar que os usuários desativem o acesso do app a dados em segundo plano, desenvolva estratégias para usar a conexão de dados com eficiência e ajustar o uso de acordo com o tipo de conexão disponível.
Se o aplicativo realiza muitas transações de rede, é preciso fornecer configurações do usuário que
permitam que os usuários controlem os hábitos relacionados a dados, como a frequência com que o app sincroniza dados, se é necessário fazer uploads/downloads somente quando estiver usando Wi-Fi, se devem usar dados em roaming etc. Com esses
controles disponíveis, é muito menos provável que os usuários desativem o acesso do app aos dados quando
se aproximarem dos limites, já que poderão controlar a quantidade de dados que o app usa.
Se você fornecer uma atividade de preferências com essas configurações, inclua na declaração
do manifesto um filtro de intent para a ação
ACTION_MANAGE_NETWORK_USAGE
. Por exemplo:
<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>
Esse filtro de intent indica ao sistema que essa é a atividade que controla o uso de dados do seu aplicativo. Assim, quando o usuário inspeciona a quantidade de dados que seu app está usando no app Configurações, um botão "Ver configurações do aplicativo" fica disponível e inicia sua atividade de preferência para que o usuário possa refinar a quantidade de dados que o app usa.
Esteja ciente também de que getBackgroundDataSetting()
agora
foi descontinuado e sempre retorna verdadeiro. Em vez disso, use getActiveNetworkInfo()
. Antes de tentar qualquer transação
de rede, sempre chame getActiveNetworkInfo()
para acessar o NetworkInfo
que representa a rede atual e consulte isConnected()
para verificar se o dispositivo tem uma
conexão. Você pode verificar outras propriedades de conexão, como se o dispositivo está
em roaming ou conectado ao Wi-Fi.
Empresarial
O Android 4.0 expande as capacidades para aplicativos corporativos com os recursos a seguir.
Serviços de VPN
O novo VpnService
permite que os apps criem a própria VPN (rede
privada virtual), executada como uma Service
. Um serviço de VPN cria uma interface para uma
rede virtual com as próprias regras de endereço e roteamento e executa todas as leituras e gravações com um
descritor de arquivo.
Para criar um serviço de VPN, use VpnService.Builder
, que permite especificar o endereço de rede, o servidor DNS, a rota da rede e muito mais. Quando concluído, você pode estabelecer a
interface chamando establish()
, que retorna um ParcelFileDescriptor
.
Como um serviço de VPN pode interceptar pacotes, há implicações de segurança. Dessa forma, se você
implementar VpnService
, seu serviço precisará exigir o BIND_VPN_SERVICE
para garantir que somente o sistema possa se vincular a ele (somente
o sistema recebe essa permissão, e os apps não podem solicitá-la). Para usar o serviço de VPN,
os usuários precisam ativá-lo manualmente nas configurações do sistema.
Políticas do dispositivo
Os apps que gerenciam as restrições do dispositivo agora podem desativar a câmera usando setCameraDisabled()
e a propriedade USES_POLICY_DISABLE_CAMERA
, que é aplicada com um elemento <disable-camera />
no arquivo de configuração da política.
Gerenciamento de certificados
A nova classe KeyChain
fornece APIs que permitem importar e acessar
certificados no armazenamento de chaves do sistema. Os certificados simplificam a instalação de certificados
do cliente (para validar a identidade do usuário) e de autoridades certificadoras (para
verificar a identidade do servidor). Aplicativos como navegadores da Web ou clientes de e-mail podem acessar os certificados instalados para autenticar usuários nos servidores. Consulte a documentação do KeyChain
para mais informações.
Sensores do dispositivo
Dois novos tipos de sensor foram adicionados ao Android 4.0:
TYPE_AMBIENT_TEMPERATURE
: um sensor de temperatura que informa a temperatura do ambiente (ambiente) em graus Celsius.TYPE_RELATIVE_HUMIDITY
: sensor de umidade que fornece a umidade relativa do ambiente (ambiente) como uma porcentagem.
Se um dispositivo tiver sensores TYPE_AMBIENT_TEMPERATURE
e TYPE_RELATIVE_HUMIDITY
, você poderá usá-los para calcular o ponto de orvalho
e a umidade absoluta.
O sensor de temperatura anterior, TYPE_TEMPERATURE
, foi
descontinuado. Use o sensor TYPE_AMBIENT_TEMPERATURE
.
Além disso, os três sensores sintéticos do Android foram bastante aprimorados, e agora eles têm menor
latência e resultados mais suaves. Esses sensores incluem o sensor de gravidade (TYPE_GRAVITY
), o sensor vetorial de rotação (TYPE_ROTATION_VECTOR
) e o sensor de aceleração linear (TYPE_LINEAR_ACCELERATION
). Os sensores aprimorados dependem do sensor do giroscópio
para melhorar a saída. Assim, os sensores aparecem apenas em dispositivos que têm giroscópio.
Barra de ações
A ActionBar
foi atualizada para oferecer suporte a vários novos comportamentos O mais
importante é que o sistema gerencia corretamente o tamanho e a configuração da barra de ações ao ser executada em
telas menores para fornecer uma experiência do usuário ideal em todos os tamanhos de tela. Por exemplo,
quando a tela é estreita (como quando um celular está na orientação retrato), as guias de navegação
da barra de ações aparecem em uma "barra empilhada", que aparece diretamente abaixo da barra de ações principal. Você também
pode ativar uma "barra de ações dividida", que coloca todos os itens em uma barra separada na parte de baixo
da tela quando a tela é estreita.
Dividir barra de ações
Se a barra de ações incluir vários itens de ação, nem todos eles vão caber na
barra de ação em uma tela estreita, então o sistema vai colocar mais itens no menu flutuante. No entanto, o Android 4.0
permite ativar a "barra de ações de divisão" para que mais itens de ação possam aparecer em uma
barra separada na parte de baixo da tela. Para ativar a barra de ações dividida, adicione android:uiOptions
com "splitActionBarWhenNarrow"
à tag
<application>
ou
às tags <activity>
individuais
no arquivo de manifesto. Quando ativada, o sistema adiciona outra barra na parte de baixo da
tela para todos os itens de ação quando ela está estreita. Nenhum item aparece na barra de ações
principal.
Se você quiser usar as guias de navegação fornecidas pelas APIs ActionBar.Tab
,
mas não precisar da barra de ação principal na parte de cima (para que apenas as guias apareçam na parte de cima), ative
a barra de ações dividida conforme descrito acima e chame setDisplayShowHomeEnabled(false)
para desativar o
ícone do aplicativo na barra de ações. Sem nada restante na barra de ações principal, ela
desaparece. Só resta as guias de navegação na parte de cima e as ações necessárias na
parte de baixo da tela.
Estilos de barra de ações
Caso você queira aplicar um estilo personalizado à barra de ações, use as novas propriedades de estilo backgroundStacked
e backgroundSplit
para aplicar um drawable
de plano de fundo ou uma cor à barra empilhada e à barra dividida, respectivamente. Também é possível definir esses estilos no
tempo de execução com setStackedBackgroundDrawable()
e setSplitBackgroundDrawable()
.
Provedor de ações
A nova classe ActionProvider
permite que você crie um gerenciador especializado para
ações. Um provedor de ações pode definir uma visualização de ação, um comportamento padrão e um submenu
para cada item de ação a que está associado. Para criar um item de ação que tenha
comportamentos dinâmicos (como uma visualização de ação variável, uma ação padrão ou um submenu), estender ActionProvider
é uma boa solução para criar um componente reutilizável, em vez de
processar as várias transformações de item de ação no fragmento ou na atividade.
Por exemplo, ShareActionProvider
é uma extensão da ActionProvider
que facilita a ação de "compartilhamento" na barra de ações. Em vez de usar
um item de ação tradicional que invoca a intent ACTION_SEND
, você pode
usar esse provedor de ações para apresentar uma visualização de ação com uma lista suspensa de aplicativos que processam
a intent ACTION_SEND
. Quando o usuário seleciona um aplicativo para usar
para a ação, o ShareActionProvider
se lembra dessa seleção e a disponibiliza
na visualização de ação para um acesso mais rápido ao compartilhamento com esse app.
Para declarar um provedor de ações para um item de ação, inclua o atributo android:actionProviderClass
no elemento <item>
do menu de opções da atividade, com o nome da classe do provedor
de ações como o valor. Por exemplo:
<item android:id="@+id/menu_share" android:title="Share" android:showAsAction="ifRoom" android:actionProviderClass="android.widget.ShareActionProvider" />
No método de callback onCreateOptionsMenu()
da atividade, extraia uma instância do provedor de ações no item de menu e defina a
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 um exemplo que usa ShareActionProvider
, consulte ActionBarShareActionProviderActivity no ApiDemos.
Visualizações de ação recolhíveis
As ações necessárias que fornecem uma visualização de ação agora podem alternar entre o estado de visualização de ação e
o estado tradicional do item de ação. Antes, apenas o SearchView
era compatível com o
recolhimento quando usado como uma visualização de ação, mas agora você pode adicionar uma visualização de ação para qualquer item de ação e
alternar entre o estado expandido (a visualização de ação está visível) e o estado recolhido (o item de ação está
visível).
Para declarar que um item de ação que contém uma visualização de ação pode ser recolhido, inclua a sinalização “collapseActionView"
no atributo android:showAsAction
do elemento <item>
no arquivo XML do menu.
Para receber callbacks quando uma visualização de ação alternar entre expandida e recolhida, registre uma
instância de MenuItem.OnActionExpandListener
com o respectivo MenuItem
chamando setOnActionExpandListener()
. Normalmente, isso precisa ser feito durante o callback onCreateOptionsMenu()
.
Para controlar uma visualização de ações recolhíveis, você pode chamar collapseActionView()
e expandActionView()
no
respectivo MenuItem
.
Ao criar uma visualização de ações personalizadas, você também pode implementar a nova interface CollapsibleActionView
para receber callbacks quando a visualização for expandida e
recolhida.
Outras APIs para a barra de ações
setHomeButtonEnabled()
permite especificar se o ícone/logotipo se comporta como um botão para navegar para a página inicial ou "para cima" (transmita "verdadeiro" para que ele se comporte como um botão).setIcon()
esetLogo()
permitem que você defina o ícone ou o logotipo da barra de ações no tempo de execução.Fragment.setMenuVisibility()
permite ativar ou desativar a visibilidade dos itens do menu "opções" declarados pelo fragmento. Isso será útil se o fragmento tiver sido adicionado à atividade, mas não estiver visível. Portanto, os itens de menu vão ficar ocultos.FragmentManager.invalidateOptionsMenu()
permite invalidar o menu de opções de atividade durante vários estados do ciclo de vida do fragmento em que o uso do método equivalente deActivity
pode não estar disponível.
Interface do usuário e visualizações
O Android 4.0 apresenta uma variedade de novas visualizações e outros componentes de IU.
GridLayout
GridLayout
é um novo grupo de visualizações que coloca visualizações filhas em uma grade retangular. Ao contrário de TableLayout
, GridLayout
depende de uma hierarquia
simples e não usa visualizações intermediárias, como linhas da tabela, para fornecer estrutura.
Em vez disso, os filhos especificam quais linhas e colunas devem ocupar (as células podem abranger várias
linhas e/ou colunas) e, por padrão, são dispostos sequencialmente nas linhas e colunas da grade.
A orientação GridLayout
determina se os filhos sequenciais são dispostos, por
padrão, na horizontal ou vertical. O espaço entre filhos pode ser especificado usando
instâncias da nova visualização Space
ou definindo os parâmetros de margem relevantes
nos filhos.
Consulte ApiDemos (link em inglês)
para ver exemplos usando GridLayout
.
TextureView
TextureView
é uma nova visualização que permite mostrar um stream de conteúdo, como
um vídeo ou uma cena OpenGL. Embora seja semelhante ao SurfaceView
, o TextureView
é único porque se comporta como uma visualização normal, em vez de criar uma
janela separada, para que você possa tratá-la como qualquer outro objeto View
. Por exemplo,
é possível aplicar transformações, animá-las usando ViewPropertyAnimator
ou
ajustar a opacidade com setAlpha()
.
TextureView
só funciona em uma janela acelerada por hardware.
Para mais informações, consulte a documentação do TextureView
.
Alternar widget
O novo widget Switch
é um botão de alternância de dois estados que os usuários podem arrastar para um
lado ou para o outro (ou simplesmente tocar) para alternar uma opção entre dois estados.
Você pode usar os atributos android:textOn
e android:textOff
para especificar o texto
que aparece na chave na configuração de ativação e desativação. O atributo android:text
também
permite colocar um rótulo ao lado da chave.
Para ver um exemplo que usa chaves, consulte o arquivo de layout switches.xml e a respectiva atividade Switches .
Menus pop-up
O Android 3.0 introduziu PopupMenu
para criar menus contextuais curtos que aparecem
em um ponto de fixação que você especifica, geralmente no ponto do item selecionado. O Android 4.0 estende
a PopupMenu
com alguns recursos úteis:
- Agora você pode inflar facilmente o conteúdo de um menu pop-up de um recurso de menu XML com
inflate()
, transmitindo o ID do recurso de menu. - Agora você também pode criar um
PopupMenu.OnDismissListener
que receba um callback quando o menu é dispensado.
Preferências
Uma nova classe abstrata TwoStatePreference
serve como base para
preferências que fornecem uma opção de seleção de dois estados. A nova SwitchPreference
é uma extensão do TwoStatePreference
que fornece um widget Switch
na
visualização de preferência para permitir que os usuários ativem ou desativem uma configuração sem a necessidade de abrir outra
tela de preferência ou caixa de diálogo. Por exemplo, o app Configurações usa um SwitchPreference
para as configurações de Wi-Fi e Bluetooth.
Temas do sistema
O tema padrão para todos os aplicativos destinados ao Android 4.0 (ao definir targetSdkVersion
ou
minSdkVersion
como
“14"
ou mais recente) agora é o
tema "padrão do dispositivo": Theme.DeviceDefault
. Pode ser
o tema escuro do Holo ou um tema escuro diferente definido pelo dispositivo específico.
A família de temas Theme.Holo
não muda
de um dispositivo para outro quando a mesma versão do Android é executada. Se você aplicar explicitamente
qualquer um dos temas Theme.Holo
às suas atividades, poderá
ter certeza de que esses temas não vão mudar de personagem em dispositivos diferentes dentro da mesma
versão da plataforma.
Se você quiser que seu app se misture com o tema geral do dispositivo (por exemplo, quando diferentes OEMs
fornecem temas padrão distintos para o sistema), aplique temas explicitamente da família Theme.DeviceDefault
.
Botão do menu "Opções"
A partir do Android 4.0, você notará que os celulares não exigem mais um botão físico de menu. No entanto, não é necessário se preocupar com isso se o aplicativo atual fornece um menu de opções e espera que haja um botão "Menu". Para garantir que os apps existentes continuem funcionando conforme o esperado, o sistema oferece um botão de menu na tela para apps criados para versões mais antigas do Android.
Para melhorar a experiência do usuário, apps novos e atualizados precisam usar ActionBar
para fornecer acesso aos itens de menu e definir targetSdkVersion
como
"14"
para aproveitar os comportamentos padrão mais recentes do framework.
Controles de visibilidade da interface do sistema
Desde os primórdios do Android, o sistema gerenciava um componente de IU conhecido como barra de status, que fica na parte de cima dos dispositivos móveis para fornecer informações como o sinal da operadora, o horário, as notificações e assim por diante. O Android 3.0 adicionou a barra do sistema para tablets, que fica na parte de baixo da tela para fornecer controles de navegação do sistema (Início, Voltar e assim por diante) e também uma interface para elementos tradicionalmente fornecidos pela barra de status. No Android 4.0, o sistema oferece um novo tipo de interface, chamado barra de navegação. Você pode considerar a barra de navegação uma versão reajustada da barra do sistema projetada para celulares. Ela fornece controles de navegação para dispositivos que não têm contrapartes de hardware para navegar no sistema, mas não inclui a interface de notificação e os controles de configuração da barra do sistema. Dessa forma, um dispositivo que fornece a barra de navegação também tem a barra de status na parte de cima.
Até hoje, é possível ocultar a barra de status em celulares usando a sinalização FLAG_FULLSCREEN
. No Android 4.0, as APIs que controlam
a visibilidade da barra do sistema foram atualizadas para refletir melhor o comportamento da barra do sistema
e da barra de navegação:
- A sinalização
SYSTEM_UI_FLAG_LOW_PROFILE
substitui a sinalizaçãoSTATUS_BAR_HIDDEN
. Quando definida, essa flag ativa o modo de "baixo perfil" para a barra do sistema ou de navegação. Os botões de navegação esmaecem e outros elementos da barra do sistema também ficam ocultos. Ativar essa opção é útil para criar jogos mais imersivos sem distrair os botões de navegação do sistema. - A flag
SYSTEM_UI_FLAG_VISIBLE
substitui a sinalizaçãoSTATUS_BAR_VISIBLE
para solicitar que a barra do sistema ou de navegação fique visível. - O
SYSTEM_UI_FLAG_HIDE_NAVIGATION
é uma nova flag que solicita que a barra de navegação fique completamente oculta. Isso funciona apenas para a barra de navegação usada por alguns celulares (ela não oculta a barra de sistema em tablets). A barra de navegação retorna à visualização assim que o sistema recebe entrada do usuário. Esse modo é útil principalmente para a reprodução de vídeos ou outros casos em que a tela inteira é necessária, mas a entrada do usuário não é necessária.
É possível definir cada uma dessas flags para a barra do sistema e de navegação chamando setSystemUiVisibility()
em qualquer visualização na atividade. O
gerenciador de janelas combina (ou junto) todas as flags de todas as visualizações na janela e
as aplica à interface do sistema, desde que a janela tenha foco de entrada. Quando a janela perde o foco
de entrada (o usuário sai do app ou uma caixa de diálogo aparece), as flags deixam de ter efeito.
Da mesma forma, se você remover essas visualizações da hierarquia, as sinalizações delas não serão mais aplicadas.
Para sincronizar outros eventos na sua atividade com mudanças de visibilidade na interface do sistema (por
exemplo, ocultar a barra de ações ou outros controles de interface quando a interface do sistema ficar oculta), registre um
View.OnSystemUiVisibilityChangeListener
para receber uma notificação quando a visibilidade
da barra do sistema ou da barra de navegação mudar.
Consulte a classe OverscanActivity para ver uma demonstração de diferentes opções de IU do sistema.
Framework de entrada
O Android 4.0 adiciona suporte a eventos de passar cursor e novos eventos do botão do mouse e da stylus.
Eventos de passagem de cursor
A classe View
agora oferece suporte a eventos de "passar o cursor" para permitir interações mais avançadas
com o uso de dispositivos ponteiro, como mouse ou outros dispositivos que acionem um cursor
na tela.
Para receber eventos de passar o cursor em uma visualização, implemente o View.OnHoverListener
e
registre-o com setOnHoverListener()
. Quando ocorre um evento
de passagem de cursor na visualização, seu listener recebe uma chamada para onHover()
, fornecendo o View
que
recebeu o evento e um MotionEvent
que descreve o tipo de evento de passagem de cursor
que ocorreu. O evento de passar o cursor pode ser um dos seguintes:
O View.OnHoverListener
vai retornar "true" de onHover()
se processar o evento de passar o cursor. Se o
listener retornar "false", o evento de passar o cursor será enviado para a visualização mãe normalmente.
Se o aplicativo usa botões ou outros widgets que mudam a aparência com base no
estado atual, agora você pode usar o atributo android:state_hovered
em um drawable de lista de estados para
fornecer um drawable de segundo plano diferente quando um cursor passa sobre a visualização.
Para ver uma demonstração dos novos eventos de passar o cursor, consulte a classe Hover no ApiDemos.
Eventos do botão do mouse e da stylus
O Android agora oferece APIs para receber entradas de um dispositivo de entrada com stylus, como um periférico de tablet digitalizador ou uma tela touchscreen compatível com stylus.
A entrada da stylus opera de maneira semelhante à entrada por toque ou mouse. Quando a stylus está em contato com o digitalizador, os apps recebem eventos de toque exatamente como receberiam quando um dedo é usado para tocar na tela. Quando a stylus passa o cursor sobre o digitalizador, os aplicativos recebem eventos de passar o cursor da mesma forma que fariam quando um ponteiro do mouse estava sendo movido pela tela quando nenhum botão foi pressionado.
O aplicativo pode diferenciar entradas de dedo, mouse, stylus e borracha consultando o
"tipo de ferramenta" associado a cada ponteiro em uma MotionEvent
usando getToolType()
. Os tipos de ferramenta definidos atualmente são: TOOL_TYPE_UNKNOWN
, TOOL_TYPE_FINGER
,
TOOL_TYPE_MOUSE
, TOOL_TYPE_STYLUS
e TOOL_TYPE_ERASER
. Ao consultar o tipo de ferramenta, o aplicativo
pode escolher processar a entrada da stylus de diferentes maneiras, usando a entrada do dedo ou do mouse.
O aplicativo também pode consultar quais botões do mouse ou da stylus são pressionados ao consultar o "estado do
botão" de um MotionEvent
usando getButtonState()
. Os estados do botão definidos no momento são: BUTTON_PRIMARY
, BUTTON_SECONDARY
, BUTTON_TERTIARY
, BUTTON_BACK
e BUTTON_FORWARD
. Por conveniência, os botões "Voltar" e "Avançar" do mouse são
mapeados automaticamente para as teclas KEYCODE_BACK
e KEYCODE_FORWARD
. Seu aplicativo pode processar essas teclas para oferecer suporte
à navegação para voltar e avançar, usando o botão do mouse.
Além de medir com precisão a posição e a pressão de um contato, alguns dispositivos de entrada da stylus
também informam a distância entre a ponta da stylus e o digitalizador, o ângulo de inclinação
e o ângulo de orientação da stylus. Seu aplicativo pode consultar essas informações usando getAxisValue()
, com os códigos de eixo AXIS_DISTANCE
, AXIS_TILT
e AXIS_ORIENTATION
.
Para uma demonstração de tipos de ferramenta, estados de botão e os novos códigos de eixo, consulte a classe TouchPaint no ApiDemos.
Propriedades
A nova classe Property
oferece uma maneira rápida, eficiente e fácil de especificar uma
propriedade em qualquer objeto que permita aos autores da chamada definir/receber valores de forma genérica em objetos de destino. Ela também permite a funcionalidade de transmitir referências de campo/método, além de permitir que o código defina/receba valores da propriedade sem conhecer os detalhes dos campos/métodos.
Por exemplo, se você quisesse definir o valor do campo bar
no objeto foo
, faria
isso anteriormente:
Kotlin
foo.bar = value
Java
foo.bar = value;
Se você quiser chamar o setter de um campo particular bar
subjacente, faria
isso anteriormente:
Kotlin
foo.setBar(value)
Java
foo.setBar(value);
No entanto, se você quiser transmitir a instância foo
e ter outro código para definir o valor
bar
, não será possível fazer isso em versões anteriores ao Android 4.0.
Com a classe Property
, é possível declarar um objeto Property
BAR
na classe Foo
para definir o campo na instância foo
da
classe Foo
desta forma:
Kotlin
BAR.set(foo, value)
Java
BAR.set(foo, value);
A classe View
agora aproveita a classe Property
para
permitir que você defina vários campos, como propriedades de transformação adicionadas no Android 3.0 (ROTATION
, ROTATION_X
, TRANSLATION_X
etc.).
A classe ObjectAnimator
também usa a classe Property
,
para que você possa criar um ObjectAnimator
com um Property
, que é mais rápido, eficiente e mais seguro de tipo do que a abordagem baseada
em strings.
Aceleração de hardware
No Android 4.0 e versões mais recentes, a aceleração de hardware para todas as janelas será ativada por padrão se o
aplicativo tiver definido targetSdkVersion
ou
minSdkVersion
como
“14"
ou mais recente. A aceleração de hardware geralmente resulta em animações mais suaves, rolagem
mais suave e melhor desempenho e resposta gerais à interação do usuário.
Se necessário, você pode desativar manualmente a aceleração de hardware com o atributo hardwareAccelerated
para elementos <activity>
individuais ou para o elemento
<application>
. Como alternativa, você pode desativar a aceleração de hardware para visualizações individuais chamando setLayerType(LAYER_TYPE_SOFTWARE)
.
Para saber mais sobre aceleração de hardware, incluindo uma lista de operações de desenho sem suporte, consulte o documento Aceleração de hardware.
Mudanças de JNI
Nas versões anteriores do Android, as referências locais de JNI não eram identificadores indiretos. O Android usava ponteiros diretos. Isso não era um problema, desde que o coletor de lixo não movesse objetos, mas parecia funcionar porque era possível escrever um código com bugs. No Android 4.0, o sistema agora usa referências indiretas para detectar esses bugs.
Os detalhes das referências locais da JNI estão descritos em "Referências locais e globais" nas Dicas de JNI. No Android 4.0, o CheckJNI foi aprimorado para detectar esses erros. Assista ao Blog de desenvolvedores Android (link em inglês) para ver uma próxima postagem sobre erros comuns com referências de JNI e como você pode corrigi-los.
Essa mudança na implementação de JNI afeta apenas apps destinados ao Android 4.0 ao definir
targetSdkVersion
ou minSdkVersion
como “14"
ou mais recente. Se você definir esses atributos com qualquer valor menor,
as referências locais JNI se comportarão da mesma forma que nas versões anteriores.
WebKit
- WebKit atualizado para a versão 534.30
- Suporte a fontes índicas (devanágari, bengali e tâmil, incluindo o suporte a caracteres complexos
necessário para combinar glifos) no
WebView
e no navegador integrado. - Suporte a fontes etíopes, georgianas e armênias no
WebView
e no navegador integrado. - O suporte ao WebDriver facilita
o teste de apps que usam
WebView
,
Navegador Android
O aplicativo Navegador adiciona os seguintes recursos para ser compatível com aplicativos da web:
- O compilador JavaScript V8 foi atualizado para um desempenho mais rápido.
- Além disso, outras melhorias importantes transferidas do Android
3.0 agora estão disponíveis para celulares:
- Suporte para elementos de posição fixa em todas as páginas
- Captura de mídia HTML
- Eventos de orientação do dispositivo
- Transformações 3D do CSS
Permissões
Confira a seguir as novas permissões:
ADD_VOICEMAIL
: permite que um serviço de correio de voz adicione mensagens de correio de voz ao dispositivo.BIND_TEXT_SERVICE
: um serviço que implementaSpellCheckerService
precisa exigir essa permissão para si mesmo.BIND_VPN_SERVICE
: um serviço que implementaVpnService
precisa exigir essa permissão para si mesmo.- android.Manifest.permission#READ_PROFILE: fornece acesso de leitura ao provedor
ContactsContract.Profile
. - android.Manifest.permission#WRITE_PROFILE: fornece acesso de gravação ao provedor
ContactsContract.Profile
.
Recursos do dispositivo
Estes são os novos recursos dos dispositivos:
FEATURE_WIFI_DIRECT
: declara que o aplicativo usa Wi-Fi para comunicações ponto a ponto.
Para ter uma visão detalhada de todas as mudanças da API no Android 4.0 (nível 14 da API), consulte o Relatório de diferenças da API.
APIs anteriores
Além de tudo que foi mencionado acima, o Android 4.0 naturalmente oferece suporte a todas as APIs de versões anteriores. Como a plataforma Android 3.x está disponível apenas para dispositivos de tela grande, se você tem desenvolvido principalmente para celulares, talvez não conheça todas as APIs adicionadas ao Android nestas versões recentes.
Confira algumas das APIs mais importantes que você talvez tenha perdido que agora também estão disponíveis em dispositivos móveis:
- Android 3.0
-
Fragment
: um componente de framework que permite separar elementos distintos de uma atividade em módulos independentes que definem a própria interface e o próprio ciclo de vida. Consulte o guia do desenvolvedor sobre fragmentos.ActionBar
: uma substituição da barra de título tradicional na parte de cima da janela de atividades. Ela inclui o logotipo do aplicativo no canto esquerdo e oferece uma nova interface para itens de menu. Consulte o guia para desenvolvedores sobre a barra de ações.Loader
: um componente do framework que facilita o carregamento assíncrono de dados em combinação com componentes de interface para carregar dados dinamicamente sem bloquear a linha de execução principal. Consulte o guia do desenvolvedor de Carregadores.- Área de transferência do sistema: os aplicativos podem copiar e colar dados (além de apenas texto) na área de transferência do sistema. Os dados cortados podem ser texto simples, um URI ou um intent. Consulte o guia para desenvolvedores sobre Copiar e colar.
- Arrastar e soltar: um conjunto de APIs integradas ao framework de visualização que facilita as operações de arrastar e soltar. Consulte o guia do desenvolvedor sobre Arrastar e soltar.
- Um novo framework de animação flexível permite animar propriedades arbitrárias de qualquer objeto (visualização, drawable, fragmento, objeto ou qualquer outro item) e definir aspectos de animação, como duração, interpolação, repetição e muito mais. O novo framework torna as animações no Android mais simples do que nunca. Consulte o guia do desenvolvedor sobre Animação de propriedade.
- Gráficos do RenderScript e mecanismo de computação: o RenderScript oferece uma API de computação e renderização de gráficos 3D de alto desempenho no nível nativo, que você programa no nível C (padrão C99), fornecendo o tipo de desempenho esperado de um ambiente nativo, mantendo a portabilidade em várias CPUs e GPUs. Consulte o guia do desenvolvedor do RenderScript.
- Gráficos 2D com aceleração de hardware: agora é possível ativar o renderizador OpenGL para seu
aplicativo definindo {android:hardwareAccelerated="true"} no elemento
<application>
do elemento de manifesto ou para elementos<activity>
individuais. Isso resulta em animações mais suaves, rolagem mais uniforme e melhor desempenho geral e resposta à interação do usuário.Observação:se você definir a
minSdkVersion
ou atargetSdkVersion
do seu app como"14"
ou mais recente, a aceleração de hardware será ativada por padrão. - E muito, muito mais. Consulte as notas da Plataforma Android 3.0 para mais informações.
- Android 3.1
-
- APIs USB: novas APIs avançadas para integrar periféricos conectados a aplicativos Android. As APIs são baseadas em uma pilha USB e serviços integrados à plataforma, incluindo suporte a interações de host e dispositivo USB. Consulte o guia do desenvolvedor sobre Host e acessórios USB.
- APIs MTP/PTP: os aplicativos podem interagir diretamente com câmeras conectadas e outros dispositivos PTP para receber notificações quando dispositivos forem conectados e removidos, gerenciar arquivos e o armazenamento nesses dispositivos e transferir arquivos e metadados para eles. A API MTP implementa o subconjunto PTP
(Protocolo de transferência de imagens) da especificação MTP (Protocolo de transferência de mídia). Consulte a
documentação do
android.mtp
. - APIs de RTP: o Android expõe uma API à pilha do protocolo de transporte em tempo real (RTP, na sigla em inglês) integrada,
que os aplicativos podem usar para gerenciar o streaming de dados on demand ou interativo. Em particular, apps
que oferecem VoIP, push-to-talk, conferência e streaming de áudio podem usar a API para iniciar
sessões e transmitir ou receber fluxos de dados por qualquer rede disponível. Consulte a documentação do
android.net.rtp
. - Suporte a joysticks e outras entradas de movimento genéricas.
- Consulte as notas da Plataforma Android 3.1 para ver muitas outras APIs novas.
- Android 3.2
-
- As novas telas oferecem suporte a APIs que oferecem mais controle sobre como os aplicativos são exibidos em diferentes tamanhos de tela. A API amplia o modelo de suporte à tela com a capacidade de segmentar com precisão intervalos de tamanho de tela específicos por dimensões, medidas em unidades de pixel de densidade independente (como 600 dp ou 720 dp de largura), em vez de por tamanhos de tela generalizados (como grande ou extragrande). Por exemplo, isso é importante para ajudar a distinguir entre dispositivos de 5 e 7, que tradicionalmente seriam agrupados como telas "grandes". Consulte a postagem do blog, New Tools for Managing Screen Sizes.
- Novas constantes de
<uses-feature>
para declarar requisitos de orientação de tela em modo paisagem ou retrato. - A configuração de "tamanho da tela" do dispositivo agora muda durante uma mudança na orientação
da tela. Se o app for direcionado ao nível 13 da API ou mais recente, será necessário processar a mudança de configuração
"screenSize"
se você também quiser processar a mudança de configuração"orientation"
. Consulteandroid:configChanges
para mais informações. - Consulte as notas da Plataforma Android 3.2 para ver outras APIs novas.
Nível de API
A API do Android 4.0 recebe um identificador de números inteiros (14), armazenado no próprio sistema. Esse identificador, chamado de "nível da API", permite que o sistema determine corretamente se um aplicativo é compatível com o sistema antes da instalação.
Para usar as APIs introduzidas no Android 4.0, é necessário compilar o
aplicativo em uma plataforma Android com suporte ao nível 14 da API ou
mais recente. Dependendo das suas necessidades, talvez você também precise adicionar um
atributo android:minSdkVersion="14"
ao
elemento
<uses-sdk>
.
Para mais informações, leia O que é o nível da API?