APIs do Android 4.0

Nível da API: 14

O Android 4.0 (ICE_CREAM_SANDWICH) é uma versão importante da plataforma 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 é um importante lançamento da plataforma, pois traz o extenso conjunto de APIs e temas Holographic do Android 3.x para telas menores. Como desenvolvedor de apps, agora você tem uma plataforma e um framework de API unificados que permite desenvolver e publicar seu aplicativo com um único APK que fornece uma experiência do usuário otimizada para celulares, tablets e muito mais, ao executar 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 do SDK do Android para download. A plataforma para download inclui uma biblioteca e uma imagem do sistema Android, além de um conjunto de skins de emulador e mais. Para começar a desenvolver ou testar no Android 4.0, use o Android SDK Manager 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 estendido para oferecer suporte a novos recursos sociais, como um perfil pessoal para o proprietário do dispositivo e os usuários podem convidar 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. Os apps sociais que mantêm a identidade do usuário podem contribuir com os dados do perfil dele 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 tradicional de contatos brutos definida pelo URI ContactsContract.RawContacts. Em vez disso, adicione um contato bruto de perfil na tabela em CONTENT_RAW_CONTACTS_URI. Bruto contatos nesta tabela são agregados em um único perfil visível ao usuário chamado "Eu".

Adicionar um novo contato bruto ao perfil exige o android.Manifest.permission#WRITE_PROFILE. Da mesma forma, para ler da tabela de perfis, você precisa solicitar a permissão android.Manifest.permission#READ_PROFILE. No entanto, a maioria dos apps não precisa ler o perfil do usuário, mesmo quando contribuem com dados para o perfil. A leitura do perfil do usuário é uma permissão sensível, e os usuários podem ser céticos em relação aos apps que a solicitam.

Intent de convite

A ação da intent INVITE_CONTACT permite que um app para invocar uma ação que indique que o usuário quer adicionar um contato a uma rede social. O app que recebe o aplicativo o utiliza para convidar o contato especificado para aquela rede social. A maioria dos apps vai receber essa 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 de uma pessoa.

Para que seu app apareça na lista "Adicionar conexão", ele precisa fornecer um adaptador de sincronização para sincronizar as informações de contato da sua rede social. Em seguida, indique ao sistema que o 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 extrair o URI do contato em questão dos 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 os 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 em uma "foto de exibição" de 256 x 256 que é armazenada em um novo armazenamento de fotos baseado em arquivos. As dimensões exatas que o sistema escolhe podem variar no futuro. Para adicionar uma foto grande a um contato, coloque uma foto na coluna PHOTO normal de uma linha de dados, que o sistema processará na miniatura e na foto de exibição apropriadas registros.

Feedback de uso do contato

As novas APIs ContactsContract.DataUsageFeedback permitem acompanhar a frequência com que o usuário usa métodos específicos de contato com as pessoas, como a frequência com que ele usa cada número de telefone ou endereço de e-mail. Essas informações ajudam a melhorar a classificação de cada contato associado a cada pessoa e fornecer melhores sugestões para entrar em contato com cada uma delas.

Provedor de agenda

As novas APIs de agenda permitem ler, adicionar, modificar e excluir agendas, eventos, participantes, lembretes e alertas, que são armazenados no provedor de agenda.

Vários apps e widgets podem usar essas APIs para ler e modificar eventos da agenda. No entanto, alguns dos casos de uso mais interessantes são adaptadores de sincronização que sincronizam a agenda do usuário de outros serviços de agenda com o provedor de agenda para oferecer um local unificado para todos os eventos do usuário. Os eventos do Google Agenda, por exemplo, são sincronizados com o Provedor de Agenda pela o Adaptador de sincronização do Google Agenda, permitindo que esses eventos sejam visualizados com a interface de usuário Agenda.

O modelo de dados para agendas e informações relacionadas a eventos no provedor de agenda é definido por CalendarContract. Todos os dados de calendário 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 informações imprecisas ou inadequadas. Cada linha nessa tabela contém os detalhes de uma única agenda, como nome, cor, dados 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 do evento, local, horário de início, horário de término etc. O evento pode ocorrer uma vez ou repetir várias vezes. Os participantes, lembretes e propriedades estendidas são armazenados em tabelas e use 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 nessa tabela representa uma única ocorrência. Para eventos de ocorrência única, há um mapeamento 1:1 de instâncias para eventos. Para eventos recorrentes, várias linhas são gerados automaticamente para corresponder às várias ocorrências daquele evento.
  • A tabela CalendarContract.Attendees contém as informações dos participantes ou convidados do evento. Cada linha representa um único convidado de um evento. Ele especifica o tipo de convidado que 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 possui a agenda em questão. Os lembretes são especificados em minutos antes de o evento ser programado e especificar 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 nos itens desta tabela, exceto excluir quando os eventos relacionados forem excluídos.

Para acessar os dados de um usuário com o provedor de agenda, o app precisa solicitar a permissão READ_CALENDAR (para acesso de leitura) e WRITE_CALENDAR (para acesso de gravação).

Intenção 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 aplicativo Agenda que cria novos eventos. O uso da intent não requer permissão e você pode especificar detalhes do evento com os seguintes extras:

Provedor de correio de voz

O novo Provedor de correio de voz permite que os aplicativos adicionem mensagens de voz ao dispositivo, a fim de 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 um do provedor de serviços do telefone e outros de VoIP ou outra voz alternativa serviços. Esses apps podem usar as APIs Voicemail Provider para adicionar mensagens de voz ao dispositivo. O app Phone integrado apresenta todos os correios de voz ao usuário de forma unificada. Embora o app Telefone do sistema seja o único que pode ler todos os correios de voz, cada app que fornece correios de voz pode ler os que foram adicionados ao sistema, mas não pode ler correios de voz de outros serviços.

Como as APIs atualmente não permitem que apps de terceiros leiam todas as mensagens de voz do sistema, os únicos apps de terceiros que devem usar as APIs de mensagens de voz são aqueles que têm mensagens de voz para enviar ao usuário.

A classe VoicemailContract define o provedor de conteúdo para o provedor de correio de voz. As subclasses VoicemailContract.Voicemails e VoicemailContract.Status fornecem tabelas em que os apps podem inserir dados de correio de voz para armazenamento no dispositivo. Para obter um exemplo de um aplicativo de provedor de correio de voz, consulte o Provedor de correio de voz Demonstração.

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 em escala de cinza ajuste o brilho, ajuste a saturação, gire uma imagem, aplique um efeito olho de peixe e muito mais. O o sistema executa todo o processamento de efeitos na GPU para atingir o desempenho máximo.

Para o máximo desempenho, os efeitos são aplicados diretamente às texturas OpenGL. Portanto, seu aplicativo precisa ter um contexto OpenGL válido antes de usar as APIs de efeitos. As texturas a que você aplica efeitos podem ser de bitmaps, vídeos ou até mesmo da câmera. No entanto, há algumas restrições que as texturas precisam atender:

  1. Eles precisam estar vinculados a uma imagem de textura GL_TEXTURE_2D.
  2. Elas precisam conter pelo menos um nível de mipmap

Um objeto Effect define um único efeito de mídia que pode ser aplicado um frame de imagem. O fluxo de trabalho básico para criar um 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 em uma textura, chame apply() na Effect e transmita a textura de entrada, a largura e a altura dela e a textura de saída. A textura de entrada precisa ser vinculada a uma imagem de textura GL_TEXTURE_2D, geralmente 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 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 efeitos adicionais disponíveis em bibliotecas externas não têm suporte de todos os dispositivos. Portanto, primeiro verifique se o efeito desejado da biblioteca externa tem suporte chamando isEffectSupported().

Cliente de controle remoto

O novo RemoteControlClient permite que os players de mídia ativem os controles de reprodução 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 para exibição no controle remoto, como informações da faixa e arte do álbum.

Para ativar clientes de controle remoto para o player de mídia, instancie um RemoteControlClient com o construtor, transmitindo um PendingIntent que transmite 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 seu player pode processar, chame setTransportControlFlags() nos seus RemoteControlClient, transmitindo um conjunto de sinalizações FLAG_KEY_MEDIA_*, como: FLAG_KEY_MEDIA_PREVIOUS e FLAG_KEY_MEDIA_NEXT.

Em seguida, registre seu RemoteControlClient, transmitindo-o para MediaManager.registerRemoteControlClient(). Depois de registrado, o broadcast receiver que você declarou quando instanciou o RemoteControlClient receberá ACTION_MEDIA_BUTTON quando um botão é 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 exibir informações no controle remoto sobre a reprodução de mídia, chame editMetaData() e adicione metadados ao RemoteControlClient.MetadataEditor. Você pode fornecer um bitmap para a arte da mídia, informações numéricas, como o tempo decorrido, e informações de texto, como o título da faixa. Para Para mais informações sobre chaves disponíveis, consulte as sinalizações METADATA_KEY_* em MediaMetadataRetriever.

Para conferir um exemplo de implementação, consulte o Player de música aleatória, que oferece uma lógica de compatibilidade que ativa o cliente de controle remoto em dispositivos Android 4.0 e continua oferecendo suporte a dispositivos com o Android 2.1.

Player de mídia

  • O streaming de mídia on-line de MediaPlayer agora requer a permissão INTERNET. Se você usar MediaPlayer para reproduzir conteúdo da Internet, adicione o parâmetro INTERNET permissão 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: envie cabeçalhos HTTP adicionais com sua solicitação, o que pode ser útil para transmissão ao vivo HTTP(S)
  • As transmissões ao vivo HTTP(S) agora respeitam os cookies HTTP nas solicitações

Tipos de mídia

O Android 4.0 adiciona suporte a:

  • Protocolo de transmissão ao vivo HTTP/HTTPS versão 3
  • Codificação de áudio AAC RAW ADTS
  • Imagens WEBP
  • Vídeo da Matroska

Para mais informações, 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

Os apps de câmera agora podem melhorar as funcionalidades com as APIs de detecção facial do Android, que não apenas detectam o rosto de um sujeito, mas também características faciais específicas, como olhos e boca.

Para detectar rostos no aplicativo de câmera, é necessário registrar um Camera.FaceDetectionListener chamando setFaceDetectionListener(). Em seguida, você pode começar a superfície da câmera e comece a detectar rostos chamando startFaceDetection().

Quando o sistema detecta um ou mais rostos na cena da câmera, ele chama o callback onFaceDetection() na sua 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:

  • Uma Rect que especifica os limites do rosto em relação ao campo de visão atual
  • 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 estão os olhos e a boca localizada

Observação:a detecção facial pode não estar disponível em alguns dispositivos. Portanto, verifique chamando getMaxNumDetectedFaces() e garanta que o retorno é maior do que zero. Além disso, alguns dispositivos podem não oferecer suporte à identificação de olhos e boca. Nesse caso, esses 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 o 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 medida. Uma instância da classe Camera.Area define os limites da área com um Rect e o peso da área, representando o nível de importância dela. em relação a outras áreas em consideração, por um número inteiro.

Antes de definir uma área de foco ou de medição, chame getMaxNumFocusAreas() ou getMaxNumMeteringAreas(), respectivamente. Se o valor for zero, o dispositivo não terá suporte ao recurso correspondente.

Para especificar as áreas de foco ou medição a serem usadas, chame setFocusAreas() ou setMeteringAreas(). Cada um deles usa um 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 permita ao usuário definir a área de foco tocando em uma área da visualização, que é então traduzida para um objeto Camera.Area e solicita que a câmera se concentre nessa área da cena. O foco ou a exposição nessa área vão ser atualizados continuamente à medida que a cena muda.

Foco automático contínuo para fotos

Agora você pode ativar o foco automático contínuo (CAF, na sigla em inglês) ao tirar fotos. Para ativar o CAF na sua 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 e manter 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 durante a captura vídeo, usando FOCUS_MODE_CONTINUOUS_VIDEO, que foi adicionados no nível 9 da API.

Outros recursos da câmera

  • Durante a gravação de vídeos, agora você pode chamar takePicture() para salvar uma foto sem interromper a sessão. Antes de fazer isso, você deve chame isVideoSnapshotSupported() para garantir que o hardware oferece suporte a ele.
  • Agora você pode bloquear a exposição automática e o equilíbrio de branco com setAutoExposureLock() e setAutoWhiteBalanceLock() para evitar essas propriedades sejam alteradas.
  • Agora você pode chamar setDisplayOrientation() enquanto a visualização da câmera está em execução. Antes, era possível chamar isso de antes de iniciar a visualização, mas agora é possível alterar a orientação a qualquer momento.

Intents de transmissão de câmera

  • Camera.ACTION_NEW_PICTURE: Isso indica que o usuário tirou uma nova foto. O app Câmera integrado invoca transmitir depois que uma foto é capturada e apps de câmera de terceiros também precisam transmitir essa intent depois de capturar a foto.
  • Camera.ACTION_NEW_VIDEO: Isso indica que o usuário capturou um novo vídeo. O app Câmera integrado invoca transmitida após a gravação de um vídeo, e apps de câmera de terceiros também precisam transmitir essa intent após a captura de um vídeo.

Android Beam (Envio NDEF com NFC)

O Android Beam é um novo recurso de NFC que permite enviar mensagens NDEF de um dispositivo para outro (um processo também conhecido como "NDEF Push"). A transferência de dados é iniciada quando dois Dispositivos com tecnologia Android compatíveis com o Android Beam estão próximos (cerca de 4 cm), geralmente com suas costas se encostando. Os dados na 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 está em primeiro plano. Em seguida, transmita o NdefMessage para o sistema em uma das duas formas. maneiras:

Caso você queira executar algum código específico depois que o sistema tiver enviado sua mensagem NDEF ao outro dispositivo, implemente NfcAdapter.OnNdefPushCompleteCallback e defina-a com setNdefPushCompleteCallback(). O sistema vai chamar onNdefPushComplete() quando a mensagem for entregue.

No dispositivo receptor, o sistema envia mensagens push NDEF de maneira semelhante às tags NFC normais. O sistema invoca uma intent com o ACTION_NDEF_DISCOVERED para iniciar uma atividade, com um URL ou um tipo MIME definido de acordo com o primeiro NdefRecord no NdefMessage. Para a atividade que você quer responder, é possível declarar filtros de intents para os URLs ou tipos MIME que interessam ao seu app. Para mais informações sobre o envio de tags, consulte o guia do desenvolvedor sobre NFC.

Se você quiser que seu NdefMessage carregue um URI, agora terá a conveniência método 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 o app também receba durante um evento do Android Beam, crie um filtro de intent para a atividade usando o mesmo esquema de URI para receber a mensagem NDEF recebida.

Você também deve transmitir um "registro de aplicativo Android" com seu dispositivo NdefMessage em para garantir que seu aplicativo processe a mensagem NDEF recebida, mesmo se outros os aplicativos são filtrados para a mesma ação de intent. É possível criar um registro de aplicativo Android chamando createApplicationRecord(), transmitindo o nome do pacote do seu aplicativo. 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 envia a mensagem para a atividade no seu app com base no registro do aplicativo correspondente. Se o dispositivo de destino não tem seu aplicativo instalado no momento, o sistema usa o registro do aplicativo Android para iniciar o Google Play e levar o usuário ao para instalá-lo.

Se o aplicativo não usar APIs NFC para realizar mensagens push NDEF, o Android vai oferecer um comportamento padrão: quando o aplicativo estiver em primeiro plano em um dispositivo e o Android Beam for invocado com outro dispositivo Android, o outro dispositivo vai receber uma mensagem NDEF com um registro de aplicativo Android que identifica seu aplicativo. Se o dispositivo receptor tiver o instalado, o sistema o inicia; Se não estiver instalado, o Google Play será aberto e levará o usuário ao seu aplicativo para instalá-lo.

Leia mais sobre o Android Beam e outros recursos de NFC no guia para desenvolvedores Conceitos básicos de NFC. Para conferir alguns exemplos de código que usam o Android Beam, consulte a Demonstração do Android Beam.

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 de dispositivo (em conformidade com o padrão Wi-Fi DirectTM programa de certificação) sem um ponto de acesso ou uma conexão com a Internet. O framework do Android oferece um conjunto de APIs Wi-Fi P2P que permitem descobrir e se conectar a outros dispositivos quando cada um deles oferece suporte ao Wi-Fi P2P e, em seguida, se comunicar por uma conexão rápida em distâncias muito mais longas que uma conexão Bluetooth.

Um novo pacote, android.net.wifi.p2p, contém todas as APIs para execução ponto a ponto com uma conexão Wi-Fi. A classe principal com que você precisa trabalhar é WifiP2pManager, que pode ser adquirida chamando getSystemService(WIFI_P2P_SERVICE). O WifiP2pManager inclui APIs que permitem:

Várias outras interfaces e classes também são necessárias, como:

  • A interface WifiP2pManager.ActionListener permite receber retornos de chamada quando uma operação como descobrir pares ou se conectar a eles tiver êxito ou falhar.
  • interface WifiP2pManager.PeerListListener permite receber informações sobre colegas descobertos. O callback fornece um WifiP2pDeviceList, em que é possível extrair um objeto WifiP2pDevice para cada dispositivo dentro do alcance e receber informações como o nome, o endereço, o tipo de dispositivo, as configurações do WPS com suporte e muito mais.
  • A interface WifiP2pManager.GroupInfoListener permite receber informações sobre um grupo P2P. O callback fornece um objeto WifiP2pGroup, que fornece informações do grupo, como proprietário, nome da rede e senha.
  • 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 como, por exemplo, se um grupo foi formada e quem é o proprietário do grupo.

Para usar as APIs de Wi-Fi P2P, seu app precisa solicitar as seguintes permissões de usuário:

  • ACCESS_WIFI_STATE
  • CHANGE_WIFI_STATE
  • INTERNET (embora seu app não se conecte tecnicamente com a Internet, a comunicação com conexões Wi-Fi P2P por meio de soquetes Java padrão requer conexão permissão).

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

Consulte a documentação do WifiP2pManager para mais informações. Além disso, olhe para Demonstração de Wi-Fi P2P aplicativo de exemplo.

Dispositivos de saúde com Bluetooth

O Android agora oferece suporte a dispositivos com o Perfil de saúde Bluetooth. Assim, você pode 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 fone de ouvido e com perfil A2DP, é necessário chamar getProfileProxy() com um BluetoothProfile.ServiceListener e o tipo de perfil HEALTH para estabelecer uma conexão com o perfil. objeto de proxy.

Após adquirir o proxy do perfil de saúde (o BluetoothHealth objeto), a conexão e a comunicação com dispositivos de saúde pareados envolvem as seguintes novas Classes de Bluetooth:

  • BluetoothHealthCallback: você precisa estender essa classe e implementar a para receber atualizações sobre alterações no estado de registro do aplicativo e 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 saúde Bluetooth disponível, que você precisa usar para realizar várias operações, como iniciar e encerrar conexões com as APIs BluetoothHealth.

Para mais informações sobre o uso do Perfil de saúde 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 da visualização ou desenvolver serviços de acessibilidade avançados.

Modo de exploração por toque

Agora, os usuários com perda de visão podem tocar e arrastar um dedo pela tela para ouvir descrições por voz do conteúdo. Como o modo de navegaçã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 podem 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. Então, considere que este é um lembrete de que você deve fornecer texto descritivo para as visualizações em seu aplicativo, especialmente para ImageButton, EditText, ImageView e outros widgets que podem não conter naturalmente descrições em textos.

Acessibilidade para visualizações

Para melhorar as informações disponíveis para serviços de acessibilidade, como leitores de tela, é possível implementar novos métodos de callback para eventos de acessibilidade nos componentes View personalizados.

É importante observar 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 passar o cursor, a respectiva visualização é notificada com uma chamada para sendAccessibilityEvent(). Antes, a implementação de sendAccessibilityEvent() inicializava um AccessibilityEvent e o enviava para AccessibilityManager. O novo comportamento envolve alguns callbacks que permitem que a visualização e os pais dela adicionem mais informações contextuais ao evento:

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

    As implementações personalizadas de View podem querer implementar onInitializeAccessibilityEvent() para anexar outras informações de acessibilidade ao AccessibilityEvent, mas também precisam 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 conteúdo de texto extra nesse callback. Isso acontece a seguir.

  2. Depois de inicializado, se o evento for de um dos vários tipos que precisam ser preenchidos com texto informação, a visualização recebe uma chamada para dispatchPopulateAccessibilityEvent(), que segue para onPopulateAccessibilityEvent() o retorno de chamada.

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

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

Além dos novos métodos acima, que são úteis para estender a classe View, você também pode interceptar esses callbacks de evento em qualquer View estendendo AccessibilityDelegate e o definindo na visualização com setAccessibilityDelegate(). Ao fazer 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 a passa para o mesmo método no View.AccessibilityDelegate. Todos os métodos não tratados pelo o delegado serão retornados diretamente para a visualização para o comportamento padrão. Isso permite modificar apenas os métodos necessários para qualquer visualização sem estender a classe View.

Para manter a compatibilidade com versões do Android anteriores à 4.0 as novas APIs de acessibilidade, você pode fazer isso com a versão mais recente do suporte v4 biblioteca (no Pacote de compatibilidade, r4) usando um conjunto de classes de utilitários que fornecem as novas APIs de acessibilidade em um ambiente do projeto.

Serviços de acessibilidade

Se você estiver desenvolvendo um serviço de acessibilidade, as informações sobre vários eventos de acessibilidade foi significativamente expandida para oferecer feedback mais avançado sobre acessibilidade para os usuários. Em particular, os eventos são gerados com base na composição da visualização, fornecendo informações de contexto melhores 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 com o seguinte procedimento:

  1. Ao receber uma AccessibilityEvent de um aplicativo, chame AccessibilityEvent.getRecord() para recuperar uma AccessibilityRecord específica. Pode haver vários registros anexados ao evento.
  2. Em AccessibilityEvent ou em um AccessibilityRecord individual, você pode chamar getSource() para recuperar 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 do evento fonte.

  3. Com o AccessibilityNodeInfo, é possível consultar informações sobre isso, chame getParent() ou getChild() para percorrer a visualização. e até mesmo adicionar visualizações filhas ao nó.

Para que seu aplicativo publique a si mesmo no sistema como um serviço de acessibilidade, ele precisa declarar um arquivo de configuração XML que corresponda a AccessibilityServiceInfo. Para mais informações sobre como criar um serviço de acessibilidade, consulte AccessibilityService e SERVICE_META_DATA para informações 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 verificação ortográfica

Um novo framework de corretor ortográfico permite que os aplicativos criem verificadores ortográficos de forma semelhante à de método de entrada (IMEs). Para criar um novo verificador ortográfico, implemente um serviço que estenda 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 verificação ortográfica 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 precisa incluir um elemento <meta-data> que declare informações de configuração para o feitiço; verificador de segurança.

Veja o exemplo serviço de verificação ortográfica e amostra cliente do Corretor Ortográfico para ver 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 ampliadas para permitir que os aplicativos implementem mecanismos TTS personalizados com mais facilidade. Além disso, 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 uma 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 TTS.

Também é possível consultar os mecanismos TTS disponíveis com 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

Antes, os mecanismos personalizados exigiam que o mecanismo fosse criado usando um cabeçalho nativo não documentado. . No Android 4.0, há um conjunto completo de APIs de framework para criar mecanismos de TTS.

A configuração básica requer uma implementação de TextToSpeechService que responde à intent INTENT_ACTION_TTS_SERVICE. O o trabalho principal de um mecanismo de TTS acontece durante o callback onSynthesizeText() em um serviço. que estende TextToSpeechService. O sistema fornece este método dois objetos:

  • SynthesisRequest: contém vários dados, incluindo o texto a ser sintetizado, a localidade, a taxa de fala e o tom de voz.
  • SynthesisCallback: é a interface em que o mecanismo de TTS entrega os dados de fala resultantes como streaming de áudio. Primeiro, o mecanismo precisa chamar start() para indicar que ele está pronto para transmitir o áudio e, em seguida, chamar audioAvailable(), transmitindo os dados de áudio em um buffer de bytes. Depois que o mecanismo transmitir todo o áudio pela buffer, chame done().

Agora que o framework oferece suporte a uma API verdadeira para criar mecanismos TTS, o suporte para o código nativo foi removida. Procure uma postagem do blog sobre uma camada de compatibilidade que você pode usar para converter seus antigos mecanismos TTS para a nova estrutura.

Para ver um exemplo de mecanismo de TTS que usa as novas APIs, consulte o app de exemplo Text to Speech Engine.

Uso da rede

O Android 4.0 oferece aos usuários visibilidade precisa da quantidade de dados de rede usados por seus aplicativos. 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 seu acesso do app aos dados em segundo plano, desenvolva estratégias para usar esses dados de maneira eficiente e ajuste o uso de acordo com o tipo de conexão disponível.

Se o seu aplicativo executa muitas transações de rede, você deve fornecer configurações de usuário que permitem que os usuários controlem os hábitos de dados do seu app, como a frequência com que ele sincroniza os dados, realizar uploads/downloads somente quando estiver em Wi-Fi, usar dados em roaming etc. Com esses disponíveis, é muito menos provável que os usuários desativem o acesso do app aos dados quando elas se aproximam dos limites, porque podem controlar com precisão a quantidade de dados que seu aplicativo usa. Se você fornecer uma atividade de preferência com essas configurações, inclua-as no manifesto. um filtro de intent para a ACTION_MANAGE_NETWORK_USAGE à ação. 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 intents indica ao sistema que se trata da atividade que controla e o uso de dados do seu app. Assim, quando o usuário inspeciona a quantidade de dados que o app está usando no app Configurações, um botão "View application settings" fica disponível e inicia a atividade de preferência para que o usuário refine a quantidade de dados que o app usa.

Além disso, tenha em mente que getBackgroundDataSetting() foi descontinuado e sempre retorna "true". Use getActiveNetworkInfo(). Antes de tentar qualquer rede transações, sempre chame getActiveNetworkInfo() para acessar o NetworkInfo, que representa a rede atual, e consultar isConnected() para verificar se o dispositivo tem uma conexão com a Internet. Em seguida, é possível verificar outras propriedades da conexão, como se o dispositivo está em roaming ou conectado a uma rede Wi-Fi.

Enterprise

O Android 4.0 expande os recursos para aplicativos empresariais com os recursos a seguir.

Serviços de VPN

O novo VpnService permite que os aplicativos criem as próprias VPNs (Virtual rede privada), em execução como um 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 arquivos.

Para criar um serviço de VPN, use VpnService.Builder, que permite especificar o endereço da rede, o servidor DNS, a rota de rede e muito mais. Quando terminar, você poderá estabelecer a interface chamando establish(), que retorna um ParcelFileDescriptor.

Como um serviço de VPN pode interceptar pacotes, há implicações de segurança. Portanto, se você implementar VpnService, seu serviço precisará exigir BIND_VPN_SERVICE para garantir que apenas o sistema possa se vincular a ele. Somente o sistema recebe essa permissão. 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 aplicativos que gerenciam as restrições de dispositivos agora podem desativar a câmera usando setCameraDisabled() e a propriedade USES_POLICY_DISABLE_CAMERA (aplicada com um elemento <disable-camera /> no arquivo de configuração da política).

Gerenciamento de certificados

A nova classe KeyChain oferece APIs que permitem importar e acessar certificados no repositório de chaves do sistema. Os certificados simplificam a instalação de certificados de cliente (para validar a identidade do usuário) e de autoridade de certificação (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 em servidores. Consulte a documentação do KeyChain para mais informações.

Sensores do dispositivo

Dois novos tipos de sensor foram adicionados no Android 4.0:

  • TYPE_AMBIENT_TEMPERATURE: um sensor de temperatura que fornece a temperatura ambiente (do local) em graus Celsius.
  • TYPE_RELATIVE_HUMIDITY: um sensor de umidade que fornece a umidade relativa do ambiente (ambiente) em porcentagem.

Se um dispositivo tiver sensores TYPE_AMBIENT_TEMPERATURE e TYPE_RELATIVE_HUMIDITY, eles poderão ser usados para calcular o ponto de condensação e a umidade absoluta.

O sensor de temperatura anterior, TYPE_TEMPERATURE, foi descontinuada. Use o sensor TYPE_AMBIENT_TEMPERATURE como alternativa.

Além disso, os três sensores sintéticos do Android foram bastante aprimorados, com latência menor e saída mais suave. Entre eles estão o sensor de gravidade (TYPE_GRAVITY), o sensor de vetor de rotação (TYPE_ROTATION_VECTOR) e o sensor de aceleração linear (TYPE_LINEAR_ACCELERATION). Os sensores aprimorados dependem do giroscópio para melhorar a saída, de modo que os sensores só apareçam em dispositivos com giroscópio.

Barra de ações

O ActionBar foi atualizado para oferecer suporte a vários novos comportamentos. Mais importante, o sistema gerencia o tamanho e a configuração da barra de ações de forma elegante ao ser executado em telas menores para oferecer uma experiência do usuário ideal em todos os tamanhos de tela. Por exemplo, quando a tela é estreita (como quando um dispositivo está na orientação retrato), as guias de navegação da barra de ações aparecem em uma "barra empilhada", diretamente abaixo da barra de ações principal. Você pode também ativar a "barra de ações dividida", que coloca todos os itens de ação em uma barra separada na parte inferior da tela quando ela estiver estreita.

Barra de ações dividida

Se a barra de ações incluir vários itens de ação, nem todos eles caberão na barra de ações em uma tela estreita. Por isso, o sistema vai colocar mais deles no menu flutuante. No entanto, o Android 4.0 permite ativar a "barra de ações dividida" para que mais itens de ação possam aparecer na tela em uma barra separada na parte de baixo da tela. Para ativar a barra de ações de divisão, adicione android:uiOptions com "splitActionBarWhenNarrow" aos seus <application> ou uma tag tags <activity> individuais no arquivo de manifesto. Quando ativada, o sistema adiciona uma barra adicional na parte de baixo da tela para todos os itens de ação quando a tela é estreita. Nenhum item de ação 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ções principal na parte superior (você quer que apenas as guias apareçam na parte superior), depois ative a barra de ações dividida conforme descrito acima e também chamar setDisplayShowHomeEnabled(false) para desativar o ícone do aplicativo na barra de ações. Sem nada na barra de ações principal, desaparece e só resta as guias de navegação na parte superior e as ações necessárias na parte inferior da tela.

Estilos da barra de ações

Se você quiser 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. Você também pode definir esses estilos em de execução com setStackedBackgroundDrawable() e setSplitBackgroundDrawable().

Provedor de ações

A nova classe ActionProvider permite criar um gerenciador especializado para itens de ação. Um provedor de ações pode definir uma visualização de ação, um comportamento de ação padrão e um submenu para cada item de ação ao qual está associado. Quando você quiser criar um item de ação com comportamentos dinâmicos (como uma visualização de ação variável, ação padrão ou submenu), estender ActionProvider é uma boa solução para criar um componente reutilizável, em vez de processar as várias transformações de itens de ação no fragmento ou na atividade;

Por exemplo, o ShareActionProvider é uma extensão de ActionProvider que facilita uma ação de "compartilhar" na barra de ações. Em vez de usar o item de ação tradicional que invoca a intent ACTION_SEND, você pode usar esse provedor de ação para apresentar uma visualização de ação com uma lista suspensa de apps que processam a intent ACTION_SEND. Quando o usuário seleciona um aplicativo para a ação, ShareActionProvider lembra dessa seleção e a fornece na visualização de ações para acesso mais rápido ao compartilhamento com o aplicativo.

Para declarar um provedor de ações para um item de ação, inclua o android:actionProviderClass Atributo no elemento <item> do menu de opções da sua atividade, com o nome da classe da ação provedor como o valor. Exemplo:

<item android:id="@+id/menu_share"
      android:title="Share"
      android:showAsAction="ifRoom"
      android:actionProviderClass="android.widget.ShareActionProvider" />

Nos onCreateOptionsMenu() da sua atividade método de callback, recupere uma instância do provedor de ações a partir do item de menu e defina o 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 conferir um exemplo de uso da ShareActionProvider, consulte ActionBarShareActionProviderActivity nas ApiDemos.

Visualizações de ação recolhíveis

Os itens de ação que fornecem uma visualização de ação agora podem alternar entre o estado de visualização e o estado de item de ação tradicional. Anteriormente, apenas o SearchView oferecia suporte ao colapso quando usado como uma ActionView, mas agora é possível adicionar uma ActionView a qualquer item de ação e alternar entre o estado aberto (a ActionView está visível) e fechado (o item de ação está visível).

Para declarar que um item de ação que contém uma visualização de ações pode ser recolhido, inclua a flag “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 um instância de MenuItem.OnActionExpandListener com o respectivo MenuItem chamando setOnActionExpandListener(). Normalmente, isso é feito durante o callback onCreateOptionsMenu().

Para controlar uma visualização de ação recolhível, chame collapseActionView() e expandActionView(): o respectivo MenuItem.

Ao criar uma visualização de ação personalizada, você também pode implementar a nova interface CollapsibleActionView para receber callbacks quando a visualização for expandida e recolhido.

Outras APIs para a action bar

  • setHomeButtonEnabled() permite especificar se o ícone/logotipo se comporta como um botão para navegar para a tela inicial ou "para cima" (transmita "true" 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 durante a execução.
  • Fragment.setMenuVisibility() permite ativar ou desativar a visibilidade dos itens do menu de opções declarados pelo fragmento. Isso é útil se o fragmento foi adicionado à atividade, mas não está visível. Portanto, os itens de menu precisam ser 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 várias visualizações novas e outros componentes da interface.

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 um e não usa visualizações intermediárias, como linhas de tabela, para fornecer estrutura. Em vez disso, os filhos especificam quais linhas e colunas devem ocupar (as células podem abranger vários 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 horizontalmente ou verticalmente por padrão. O espaço entre os filhos pode ser especificado usando instâncias da nova visualização Space ou definindo os parâmetros de margem relevantes nos filhos.

Consulte ApiDemos para conferir exemplos de uso de GridLayout.

TextureView

TextureView é uma nova visualização que permite exibir um stream de conteúdo, como um vídeo ou uma cena OpenGL. Embora semelhante a SurfaceView, TextureView é exclusivo porque se comporta como uma visualização normal, em vez de criar uma janela separada. Assim, você pode tratá-lo como qualquer outro objeto View. Por exemplo, é possível aplicar transformações, animar usando ViewPropertyAnimator ou ajustar a opacidade com setAlpha().

O TextureView só funciona em uma janela com aceleração de hardware.

Para mais informações, consulte a documentação TextureView.

Alternar widget

O novo widget Switch é uma alternância de dois estados que os usuários podem arrastar para um lado ou o outro (ou simplesmente tocar) para alternar uma opção entre dois estados.

É possível usar os atributos android:textOn e android:textOff para especificar o texto que vai aparecer no interruptor quando ele estiver na configuração "ativado" e "desativado". O atributo android:text também permite que você coloque um marcador ao lado do interruptor.

Para um exemplo de uso de switches, consulte o arquivo de layout switches.xml. e as respectivas chaves atividade.

O Android 3.0 introduziu PopupMenu para criar menus contextuais curtos que aparecem em um ponto de âncora especificado (geralmente no ponto do item selecionado). O Android 4.0 estende-se o PopupMenu com alguns recursos úteis:

Preferências

Uma nova classe abstrata TwoStatePreference serve como base para preferências que fornecem uma opção de seleção de dois estados. O novo SwitchPreference é uma extensão do TwoStatePreference que fornece um widget Switch na de preferência para permitir que os usuários ativem ou desativem uma configuração sem precisar abrir 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 de todos os aplicativos destinados ao Android 4.0 (configurando targetSdkVersion ou minSdkVersion para “14" ou mais recente) agora é o tema "padrão do dispositivo": Theme.DeviceDefault. Isso 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 ao executar a mesma versão do Android. Se você explicitamente aplicar qualquer um dos Theme.Holo temas às suas atividades, você pode tenha certeza de que esses temas não mudarão de caractere em diferentes dispositivos dentro da mesma uma versão da plataforma.

Se você quiser que o app se misture com o tema geral do dispositivo (por exemplo, quando diferentes OEMs fornecer temas padrão diferentes para o sistema), aplique temas da família Theme.DeviceDefault de forma explícita.

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 há necessidade de se preocupar com isso se seu aplicativo existente oferece um menu "opções" e espera que haja uma Botão de menu. Para garantir que os apps atuais continuem funcionando como esperado, o sistema oferece um botão "Menu" na tela para apps projetados para versões mais antigas do Android.

Para ter a melhor experiência do usuário, os 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 gerencia um componente de IU conhecido como status localizada na parte superior dos dispositivos móveis para fornecer informações como a operadora sinal, horário, notificações, etc. O Android 3.0 adicionou a barra do sistema para tablets dispositivos, localizados na parte inferior da tela para fornecer controles de navegação do sistema (página inicial, Back e assim por diante), além de uma interface para elementos tradicionalmente fornecidos pela barra de status. No Android 4.0, o sistema oferece um novo tipo de interface do sistema chamado barra de navegação. Você pode considerar a barra de navegação uma versão ajustada da barra do sistema projetada para telefones. Ela oferece controles de navegação para dispositivos que não têm hardware para navegar pelo sistema, mas deixa de fora a interface de usuário de notificação e os controles de configuração da barra do sistema. Assim, um dispositivo que oferece a barra de navegação também tem a barra de status na parte de cima.

Até hoje, você pode 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 definido, esse flag ativa o perfil restrito para a barra do sistema ou barra de navegação. Os botões de navegação escurecem e outros elementos na barra do sistema também ficam ocultos. Ativando Isso é útil para criar jogos mais imersivos sem distração para a navegação do sistema. botões.
  • A flag SYSTEM_UI_FLAG_VISIBLE substitui a flag 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 a barra de navegação fica totalmente oculta. Isso funciona apenas para a barra de navegação usada por alguns aparelhos. Ela não oculta a barra do sistema em tablets. A barra de navegação volta a aparecer assim que o sistema recebe a entrada do usuário. Por isso, esse modo é útil principalmente para reprodução de vídeo ou outros casos em que a tela inteira é necessária, mas a entrada do usuário é não é obrigatório.

É possível definir cada uma dessas flags para a barra do sistema e a barra de navegação chamando setSystemUiVisibility() em qualquer visualização na atividade. O gerenciador de janelas combina (OU-juntos) todas as flags de todas as visualizações na janela e as aplica à interface do sistema, desde que a janela tenha o 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 flags 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 da interface quando a interface do sistema é oculta), registre um View.OnSystemUiVisibilityChangeListener para receber notificações quando a visibilidade da barra do sistema ou da barra de navegação mudar.

Consulte a classe OverscanActivity para conferir uma demonstração das diferentes opções de interface do sistema.

Framework de entrada

O Android 4.0 adiciona suporte a eventos de passagem de cursor e novos eventos de stylus e botão do mouse.

Eventos ao passar o cursor

A classe View agora oferece suporte a eventos de "passar o cursor" para permitir interações mais ricas com o uso de dispositivos apontadores (como um mouse ou outros dispositivos que acionam um cursor na tela).

Para receber eventos de passagem do cursor em uma visualização, implemente o View.OnHoverListener e registre-o com setOnHoverListener(). Quando um usuário passa o cursor evento ocorre na visualização, o listener recebe uma chamada para onHover(), fornecendo o View que recebeu o evento e um MotionEvent que descreve o tipo de evento de passar o cursor que ocorreu. O evento de passar o cursor pode ser um dos seguintes:

A View.OnHoverListener retornará "true" em onHover() se processar o evento ao passar o cursor. Se as listener retornar falso, e o evento de passar o cursor será enviado à visualização pai como de costume.

Se o aplicativo usa botões ou outros widgets que mudam de aparência com base no estado atual, agora é possível usar o atributo android:state_hovered em um drawable de lista de estados para fornecer um drawable de plano de fundo diferente quando um cursor passa sobre a visualização.

Para ver uma demonstração dos novos eventos de passar o cursor, consulte a classe Passar cursor na ApiDemos.

Eventos de stylus e botão do mouse

O Android agora oferece APIs para receber entradas de um dispositivo de entrada de stylus, como um periférico de tablet digitalizador ou uma tela touchscreen com suporte a stylus.

A entrada da stylus opera de maneira semelhante à entrada por toque ou mouse. Quando a stylus estiver em contato Com o digitalizador, os aplicativos recebem eventos de toque da mesma forma que receberiam quando um dedo é usado para toque no visor. Quando a stylus está pairada com o digitalizador, os aplicativos recebem eventos de pairamento da mesma forma que fariam quando um ponteiro do mouse estivesse sendo movido pela tela sem que nenhum botão fosse pressionado.

Seu aplicativo pode distinguir entre entradas de dedo, mouse, stylus e borracha consultando o "tipo de ferramenta" associadas 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 processar a entrada da stylus de maneiras diferentes da entrada do dedo ou do mouse.

Seu aplicativo também pode consultar quais botões do mouse ou da stylus são pressionados no botão “ estado" 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. Para sua conveniência, os botões de avançar e voltar do mouse são mapeados automaticamente para as teclas KEYCODE_BACK e KEYCODE_FORWARD. Seu aplicativo pode lidar com essas chaves para dar suporte botão do mouse com base na navegação para trás e para frente.

Além de medir com precisão a posição e a pressão de um contato, alguns dispositivos de entrada com 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. O aplicativo pode consultar essas informações usando getAxisValue() com os códigos de eixo AXIS_DISTANCE, AXIS_TILT e AXIS_ORIENTATION.

Para conferir uma demonstração de tipos de ferramentas, estados de botão e os novos códigos de eixo, consulte a classe TouchPaint em ApiDemos.

Propriedades

A nova classe Property oferece uma maneira rápida, eficiente e fácil de especificar uma propriedade em qualquer objeto que permita que os autores da chamada definam/recebam valores genéricos em objetos de destino. Ele também permite a funcionalidade de transmitir referências de campo/método e permite que o código defina/extraia valores da propriedade sem saber os detalhes dos campos/métodos.

Por exemplo, se quiser definir o valor do campo bar no objeto foo, você precisa fazer isso anteriormente:

Kotlin

foo.bar = value

Java

foo.bar = value;

Se você quisesse chamar o setter de um campo particular subjacente bar, faria anteriormente faça isto:

Kotlin

foo.setBar(value)

Java

foo.setBar(value);

No entanto, se você quiser transmitir a instância foo e definir outro código como bar, não há como fazer isso antes do Android 4.0.

Usando a classe Property, é possível declarar um objeto Property BAR na classe Foo para definir o campo na instância foo da classe Foo, como este:

Kotlin

BAR.set(foo, value)

Java

BAR.set(foo, value);

A classe View agora aproveita a classe Property para permitem que você defina vários campos, como propriedades de transformação que foram adicionadas no Android 3.0 (ROTATION, ROTATION_X, TRANSLATION_X etc.).

A classe ObjectAnimator também usa o Property para criar uma ObjectAnimator com uma Property, que é mais rápida, eficiente e segura do que as strings abordagem humilde.

Aceleração de hardware

A partir do Android 4.0, a aceleração de hardware para todas as janelas é ativada por padrão aplicativo tiver definido targetSdkVersion ou minSdkVersion para “14" ou superior. A aceleração de hardware geralmente resulta em animações mais suaves, rolagem e desempenho geral e melhor desempenho e resposta à interação do usuário.

Se necessário, você pode desativar manualmente a aceleração de hardware com o hardwareAccelerated. atributo para elementos <activity> individuais ou o <application> . Você também pode desativar a aceleração de hardware para visualizações individuais chamando setLayerType(LAYER_TYPE_SOFTWARE).

Para mais informações sobre a aceleração de hardware, incluindo uma lista de desenhos incompatíveis das operações, consulte a Informações Acceleration.

Mudanças de JNI

Nas versões anteriores do Android, as referências locais de JNI não eram identificadores indiretos. Android usado ponteiros diretos. Isso não era um problema, desde que o coletor de lixo não movia os objetos, mas parecia funcionar, porque possibilitou escrever códigos 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" em Dicas de JNI. No Android 4.0, O CheckJNI foi aprimorado para detectar esses erros. Confira o Blog de desenvolvedores Android para conferir uma próxima postagem sobre erros comuns com referências JNI e como corrigi-los.

Essa alteração na implementação da JNI afeta apenas aplicativos direcionados ao Android 4.0, configurando a targetSdkVersion ou a minSdkVersion para “14" ou superior. Se você definir esses atributos com valores mais baixos, então as referências locais de JNI se comportam da mesma forma que nas versões anteriores.

WebKit

  • O WebKit foi atualizado para a versão 534.30
  • Suporte a fontes índicas (Devanagari, bengali e tâmil, incluindo o suporte a caracteres complexos necessário para combinar glifos) no WebView e no navegador integrado
  • Suporte a fontes em etíope, georgiano e armênio no WebView e no navegador integrado
  • A compatibilidade com WebDriver torna o teste de apps que usam WebView

Navegador Android

O aplicativo Navegador adiciona os seguintes recursos para oferecer suporte a aplicativos da Web:

Permissões

Estas são as novas permissões:

Recursos do dispositivo

Confira a seguir os novos recursos do dispositivo:

Para obter uma visão detalhada de todas as mudanças de API no Android 4.0 (nível de API 14), consulte o Relatório de diferenças da API.

APIs anteriores

Além de tudo o que foi mencionado acima, o Android 4.0 oferece suporte natural a todas as APIs das versões anteriores. Como a plataforma Android 3.x está disponível apenas para dispositivos de tela grande, se você tem desenvolvido principalmente para smartphones, talvez não conheça todas as APIs adicionadas ao Android nas versões mais recentes.

Confira algumas das APIs mais importantes que já estão disponíveis em celulares também:

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 ciclo de vida. Consulte a Fragmentos.
  • ActionBar: uma substituição para a barra de título tradicional na parte de cima da janela de atividade. Ele inclui o logotipo do aplicativo no canto esquerdo e oferece uma nova interface para itens de menu. Consulte a Guia do desenvolvedor da barra de ações.
  • Loader: um componente de framework que facilita o carregamento assíncrono de dados em combinação com componentes da interface para carregar dados dinamicamente sem bloquear a linha de execução principal. Consulte a Guia do desenvolvedor sobre Carregadores.
  • Área de transferência do sistema: os aplicativos podem copiar e colar dados (além de simples texto) de e para a área de transferência do sistema para a área de transferência do sistema. Os dados recortados podem ser texto simples, um URI ou uma intent. Consulte a Copiar e colar no guia para desenvolvedores.
  • Arrastar e soltar: um conjunto de APIs integradas ao framework de visualização que facilita o recurso de arrastar e soltar. as operações. Consulte a Arrastar e soltar guia para desenvolvedores.
  • Um novo framework de animação flexível permite animar propriedades arbitrárias de qualquer objeto (View, Drawable, Fragment, Object ou qualquer outra coisa) e definir aspectos de animação, como duração, interpolação, repetição e muito mais. O novo framework faz animações no Android mais simples do que nunca. Consulte a Desenvolvedor de animação de propriedades guia.
  • Gráficos do RenderScript e Compute Engine: o RenderScript oferece um 3D de alto desempenho renderização de gráficos e API de computação no nível nativo, que você programa em C (padrão C99), oferecendo o tipo de desempenho que você espera de um ambiente nativo e ainda portátil em várias CPUs e GPUs. Consulte a Desenvolvedor do RenderScript guia.
  • Gráficos 2D acelerados por hardware: agora você pode ativar o renderizador OpenGL para o seu definindo {android:hardwareAccelerated="true"} no elemento <application> do elemento do manifesto elemento ou para <activity> individuais os elementos. Isso resulta com animações mais suaves, rolagem mais suave e melhor desempenho geral e resposta ao usuário interação.

    Observação: se você definir minSdkVersion ou targetSdkVersion do 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 com Apps Android. As APIs são baseadas em uma pilha USB e serviços integrados à plataforma, incluindo suporte para interações com o host USB e o dispositivo. Consulte o guia para desenvolvedores Host e acessório USB.
  • APIs MTP/PTP: os aplicativos podem interagir diretamente com câmeras conectadas e outros dispositivos PTP para receber notificações quando os dispositivos são conectados e removidos, gerenciar arquivos e armazenamento nesses dispositivos e transferir arquivos e metadados para e a partir deles. A API MTP implementa o 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 RTP: o Android expõe uma API para a pilha RTP (protocolo de transporte em tempo real) integrada, que os aplicativos podem usar para gerenciar o streaming de dados sob demanda ou interativo. Em particular, apps que oferecem VOIP, push-to-talk, conferências e streaming de áudio podem usar a API para iniciar sessões e transmitir ou receber streams de dados em qualquer rede disponível. Consulte a documentação de android.net.rtp.
  • Suporte a joysticks e outras entradas de movimento genéricas.
  • Consulte as notas da Plataforma Android 3.1 para conferir mais APIs.
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 estende o modelo existente de suporte a telas com as 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), ao invés de seus tamanhos de tela (como grande ou extragrande). Por exemplo, isso é importante para ajudar você distinguir entre um dispositivo de 5" e um dispositivo de 7" que seriam tradicionalmente agrupados em classes "grande" telas. Consulte a postagem do blog, Novas ferramentas para gerenciar tamanhos de tela.
  • Novas constantes para <uses-feature> para declarar requisitos de orientação de tela em modo paisagem ou retrato.
  • O "tamanho da tela" do dispositivo a configuração muda durante uma orientação de tela mudar. Caso seu app seja direcionado ao nível 13 da API ou mais recente, processe o "screenSize" mudança de configuração 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 conferir outras APIs novas.

Nível da API

A API do Android 4.0 recebe um identificador inteiro, 14, que é armazenado no próprio sistema. Esse identificador, chamado de "nível da API", permite que o sistema determine corretamente se um aplicativo seja compatível com o sistema, antes de instalá-lo.

Para usar as APIs introduzidas no Android 4.0 no seu app, é necessário compilar o app em uma plataforma Android compatível com o nível 14 da API ou mais recente. Dependendo das suas necessidades, talvez seja necessário adicionar um atributo android:minSdkVersion="14" ao elemento <uses-sdk>.

Para mais informações, leia O que é o nível da API?