APIs do Android 4.0

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 em MAX_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:

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:

  1. Eles precisam estar vinculados a uma imagem de textura GL_TEXTURE_2D.
  2. 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:

  1. Chame EffectContext.createWithCurrentGlContext() no contexto do OpenGL ES 2.0.
  2. Use o EffectContext retornado para chamar EffectContext.getFactory(), que retorna uma instância de EffectFactory.
  3. Chame createEffect(), transmitindo um nome de efeito de @link android.media.effect.EffectFactory}, como EFFECT_FISHEYE ou EFFECT_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ão INTERNET. Se você usar MediaPlayer para reproduzir conteúdo da Internet, adicione a permissão INTERNET 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 um Surface 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, chame isVideoSnapshotSupported() 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() e setAutoWhiteBalanceLock() 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:

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 um WifiP2pDeviceList, da qual é possível recuperar um objeto WifiP2pDevice 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 objeto WifiP2pGroup, 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 objeto WifiP2pInfo, 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:

O sistema Android também transmite várias ações diferentes durante certos eventos de Wi-Fi P2P:

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 o BluetoothHealthCallback, 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 APIs BluetoothHealth.

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:

  1. Quando invocados, os métodos sendAccessibilityEvent() e sendAccessibilityEventUnchecked() são adiados para onInitializeAccessibilityEvent().

    Implementações personalizadas de View podem querer implementar onInitializeAccessibilityEvent() para anexar outras informações de acessibilidade ao AccessibilityEvent, 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.

  2. 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 callback onPopulateAccessibilityEvent().

    As implementações personalizadas de View geralmente precisam implementar onPopulateAccessibilityEvent() para adicionar mais conteúdo de texto ao AccessibilityEvent se o texto android:contentDescription estiver ausente ou insuficiente. Para adicionar mais descrições de texto à AccessibilityEvent, chame getText().add().

  3. Nesse ponto, o View transmite o evento para cima da hierarquia de visualização chamando requestSendAccessibilityEvent() na visualização mãe. Cada visualização mãe tem a chance de aumentar as informações de acessibilidade adicionando um AccessibilityRecord, até que ele chegue à visualização raiz, que envia o evento para a AccessibilityManager com sendAccessibilityEvent().

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:

  1. Ao receber um AccessibilityEvent de um aplicativo, chame AccessibilityEvent.getRecord() para recuperar um AccessibilityRecord específico (pode haver vários registros anexados ao evento).
  2. Na AccessibilityEvent ou em uma AccessibilityRecord individual, é possível chamar getSource() para extrair um objeto AccessibilityNodeInfo.

    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 objeto AccessibilityNodeInfo retornado de AccessibilityEvent descreve a origem do evento, enquanto a origem de um AccessibilityRecord descreve o predecessor da origem do evento.

  3. Com o AccessibilityNodeInfo, é possível consultar informações sobre ele, chamar getParent() ou getChild() 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:

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 chamar start() para indicar que está pronto para enviar o áudio e, em seguida, chamar audioAvailable(), transmitindo os dados de áudio em um buffer de bytes. Depois que o mecanismo tiver transmitido todo o áudio pelo buffer, chame done().

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() e setLogo() 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 de Activity 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 .

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ção STATUS_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ção STATUS_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:

Permissões

Confira a seguir as novas permissões:

Recursos do dispositivo

Estes são os novos recursos dos dispositivos:

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 a targetSdkVersion 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". Consulte android: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?