API de nível: 17
Android 4.2 (JELLY_BEAN_MR1
)
é uma atualização da versão Jelly Bean que oferece novos recursos para usuários e apps
desenvolvedores de aplicativos. Este documento fornece uma introdução aos conceitos mais importantes
novas APIs úteis para desenvolvedores.
Como desenvolvedor de aplicativos, você deve baixar a imagem do sistema do Android 4.2 e a plataforma do SDK em o SDK Manager assim que possível. Se você não tiver um dispositivo com Android 4.2 no qual testar o aplicativo, use o sistema Android 4.2 para testar seu app no Android Emulator. Em seguida, crie seus aplicativos na plataforma Android 4.2 para começar a usar as APIs mais recentes.
Para otimizar seu aplicativo para dispositivos com o Android 4.2,
defina o targetSdkVersion
como
"17"
, instale em uma imagem do sistema Android 4.2,
testá-lo e publicar uma atualização com essa alteração.
Você
podem usar APIs no Android 4.2 e, ao mesmo tempo, oferecer suporte a versões mais antigas, adicionando
ao código que verificam o nível da API do sistema antes da execução
APIs não compatíveis com seu minSdkVersion
.
Para saber mais sobre
manter a compatibilidade com versões anteriores, leia Criação de compatibilidade com versões anteriores
IUs.
Para mais informações sobre como os níveis de API funcionam, consulte O que é uma API Nível?
Mudanças de comportamento importantes
Se você já tiver publicado um app para Android, saiba que: mudanças que podem afetar o comportamento do app:
- Provedores de conteúdo não são mais exportados por padrão. Ou seja, o valor padrão
para o atributo
android:exported
agora é“false"
. Se é importante que outros apps sejam conseguir acessar seu provedor de conteúdo, defina explicitamenteandroid:exported="true"
.Essa mudança só vai entrar em vigor se você definir
android:targetSdkVersion
ouandroid:minSdkVersion
como 17 ou mais. Caso contrário, o valor padrão ainda será“true"
. mesmo com o Android 4.2 ou superior. - Em comparação com versões anteriores do Android, os resultados da localização do usuário podem ser menos precisos
se o app solicitar a permissão
ACCESS_COARSE_LOCATION
, mas não solicita a permissãoACCESS_FINE_LOCATION
.Para atender às expectativas de privacidade dos usuários quando o app solicita permissão para localização aproximada (e não precisa), o sistema não vai fornecer uma estimativa de local do usuário um resultado mais preciso do que um quarteirão.
- Algumas configurações do dispositivo definidas por
Settings.System
agora estão somente leitura. Se o app tentar gravar mudanças nas configurações definidas noSettings.System
que foram movidas paraSettings.Global
, faça o seguinte: a operação de gravação falhará silenciosamente ao ser executada no Android 4.2 e versões posteriores.Mesmo que o valor de
android:targetSdkVersion
eandroid:minSdkVersion
seja menor que 17, o app não poderá modificar as configurações que tenham movida paraSettings.Global
ao executar no Android 4.2 e versões mais recentes. - Caso seu aplicativo use
WebView
, o Android 4.2 adicionará uma camada adicional de segurança para que você possa vincular o JavaScript ao seu Código do Android. Se você definir seutargetSdkVersion
para 17 ou maior, agora é preciso adicionar a anotação@JavascriptInterface
a qualquer método que você que devem estar disponíveis para seu JavaScript (o método também precisa ser público). Se você não fornecer o anotação, o método não pode ser acessado por uma página da Web naWebView
ao executar no Android 4.2 ou superior. Se você definirtargetSdkVersion
para 16 ou menos, a anotação não é necessária, mas recomendamos que você atualize sua versão de destino e adicione a anotação para aumentar a segurança.Leia mais sobre vinculação do código JavaScript para o código do Android.
Daydream
O Daydream é um novo modo interativo de protetor de tela para dispositivos Android. Ele é ativado automaticamente quando o dispositivo está inserido em uma base ou quando o dispositivo fica inativo enquanto conectado a uma carregador (em vez de desligar a tela). O Daydream exibe um sonho por vez, que pode ser uma tela puramente visual e passiva dispensada pelo toque ou que pode ser interativa e responsiva para o pacote completo de eventos de entrada. Seus sonhos são realizados no processo do app e têm acesso total a kit de ferramentas de interface do Android, incluindo visualizações, layouts e animações, para que sejam mais flexíveis e poderosos do que os planos de fundo interativos ou widgets de apps.
Você pode criar um sonho para o Daydream implementando uma subclasse de DreamService
. As APIs DreamService
são
projetada para ser semelhante aos de Activity
. Para especificar a interface do usuário
sonhar, transmita um ID de recurso de layout ou View
para setContentView()
a qualquer momento depois de
em uma janela, como do onAttachedToWindow()
o retorno de chamada.
A classe DreamService
fornece outro callback importante do ciclo de vida
métodos com base nas APIs Service
básicas, como onDreamingStarted()
, onDreamingStopped()
e onDetachedFromWindow()
.
Não é possível iniciar uma DreamService
no
app. Ele é iniciado automaticamente pelo sistema.
Se seu sonho for interativo, você pode iniciar uma atividade dele para direcionar o usuário
a interface completa do seu app para ter mais detalhes ou controle. Você pode usar finish()
para encerrar o sonho para que o usuário possa ver o
uma nova atividade.
Para disponibilizar seu Daydream para o sistema, declare seu DreamService
com um elemento <service>
no arquivo de manifesto. Em seguida, inclua um filtro de intent com a ação "android.service.dreams.DreamService"
. Exemplo:
<service android:name=".MyDream" android:exported="true" android:icon="@drawable/dream_icon" android:label="@string/dream_label" > <intent-filter> <action android:name="android.service.dreams.DreamService" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service>
Há outros métodos úteis em DreamService
que você deve conhecer:
setInteractive(boolean)
controla se o sonho recebe eventos de entrada ou saídas imediatamente após a entrada do usuário. Se o sonho é interativo, o usuário pode usar os botões Voltar ou Início para sair do sonho, ou você pode chamarfinish()
para impedi-lo.- Se você quiser uma tela totalmente imersiva, chame
setFullscreen()
para ocultar a barra de status. - Antes do início do Daydream, a tela escurece para sinalizar ao usuário que o tempo limite de inatividade
está se aproximando. Chamar
setScreenBright(true)
permite que você configure a tela com o brilho normal.
Para mais informações, consulte a documentação DreamService
.
Telas secundárias
O Android agora permite que seu app mostre conteúdo exclusivo em outras telas conectadas
ao dispositivo do usuário por uma conexão com fio ou Wi-Fi.
Para criar conteúdo exclusivo para uma tela secundária, estenda o Presentation
e implemente o callback onCreate()
. Dentro de
onCreate()
, especifique a interface para a tela secundária
chame setContentView()
.
Como uma extensão da classe Dialog
, a classe Presentation
fornece a região em que o app pode mostrar uma interface exclusiva no
tela secundária.
Para detectar telas secundárias em que você pode exibir seu Presentation
, faça o seguinte:
use o DisplayManager
ou o MediaRouter
APIs de terceiros. As APIs DisplayManager
permitem enumerar
várias telas que podem ser conectadas ao mesmo tempo, use MediaRouter
para acessar rapidamente a tela padrão do sistema
apresentações.
Para definir a tela padrão da sua apresentação, chame MediaRouter.getSelectedRoute()
e transmita-a
ROUTE_TYPE_LIVE_VIDEO
. Isso retorna um objeto MediaRouter.RouteInfo
que descreve a rota selecionada no sistema no momento.
para apresentações de vídeo. Se o MediaRouter.RouteInfo
não for nulo, chame
getPresentationDisplay()
para receber o Display
que representa a tela conectada.
Você pode mostrar sua apresentação transmitindo o objeto Display
como um construtor para a classe Presentation
. Sua apresentação agora será
na tela secundária.
Para detectar durante a execução quando uma nova tela foi conectada, crie uma instância do MediaRouter.SimpleCallback
em que você implementa o método de callback onRoutePresentationDisplayChanged()
, que o sistema chamará quando uma nova
tela da apresentação conectada. Em seguida, registre o MediaRouter.SimpleCallback
transmitindo-o para MediaRouter.addCallback()
com o tipo de rota ROUTE_TYPE_LIVE_VIDEO
. Quando você receber uma chamada para
onRoutePresentationDisplayChanged()
, basta chamar MediaRouter.getSelectedRoute()
, conforme mencionado acima.
Para otimizar ainda mais a interface na Presentation
para
telas secundárias, é possível aplicar
um tema diferente especificando o atributo android:presentationTheme
no <style>
que você
aplicadas ao seu aplicativo ou atividade.
Lembre-se de que as telas conectadas ao dispositivo do usuário geralmente têm um tamanho de tela maior e
provavelmente uma densidade de tela diferente. Como as características da tela podem ser diferentes, você deve
fornecem recursos otimizados especificamente para essas telas maiores. Se você precisar
para solicitar outros recursos da Presentation
, chame getContext()
.getResources()
para receber o objeto Resources
correspondente à exibição. Isso fornece
os recursos apropriados do app mais adequados para
o tamanho e a densidade da tela da tela secundária.
Para mais informações e alguns exemplos de código, consulte a Presentation
documentação da classe.
Widgets da tela de bloqueio
O Android agora permite que os usuários adicionem widgets de apps à tela de bloqueio. Para disponibilizar seu widget de app para uso no
tela de bloqueio, adicione o atributo android:widgetCategory
ao seu arquivo XML que especifica o AppWidgetProviderInfo
. Esse atributo é compatível com dois valores: home_screen
e keyguard
. Por padrão, o atributo é definido como home_screen
para que os usuários possam adicionar seus
widget do app à tela inicial. Se você quiser que seu widget de app também esteja disponível na fechadura
adicione o valor keyguard
:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" ... android:widgetCategory="keyguard|home_screen"> </appwidget-provider>
Também é necessário especificar um layout inicial para o widget de app na tela de bloqueio com
o atributo android:initialKeyguardLayout
. Ele funciona da mesma forma que android:initialLayout
, porque fornece
um layout que pode aparecer imediatamente até que o widget do app seja inicializado e possa atualizar o
o mesmo layout organizacional.
Para mais informações sobre como criar widgets de apps para a tela de bloqueio, incluindo para verificar para dimensionar o widget do app na tela de bloqueio, consulte o guia Widgets de apps.
Vários usuários
O Android agora permite vários espaços de usuário em dispositivos compartilháveis, como tablets. Cada usuário de uma dispositivo com o próprio conjunto de contas, apps, configurações do sistema, arquivos e qualquer outro dados associados ao usuário.
Como desenvolvedor de apps, você não precisa fazer nada diferente para que seu app funcione com vários usuários em um único dispositivo. Independentemente de quantos usuários dispositivo, os dados que o app salva para um determinado usuário são mantidos separados dos dados que o app salva para outros usuários. O sistema acompanha quais dados do usuário pertencem ao processo do usuário em que seu app está em execução e fornece acesso somente aos dados desse usuário, sem permitir acesso aos dados de outros usuários.
Como salvar dados em um ambiente multiusuário
Sempre que o app salva as preferências do usuário, cria um banco de dados ou grava um arquivo no interno ou externo, esses dados só podem ser acessados enquanto estiverem sendo executados como esse usuário.
Para ter certeza de que seu app se comporta corretamente em um ambiente multiusuário, não consulte o diretório interno do app ou local de armazenamento externo usando caminhos codificados e sempre as APIs apropriadas:
- Para acessar o armazenamento interno, use
getFilesDir()
,getCacheDir()
ouopenFileOutput()
. - Para acessar o armazenamento externo, use
getExternalFilesDir()
ougetExternalStoragePublicDirectory()
.
Independentemente das APIs usadas para salvar os dados de um determinado usuário, os dados não serão acessíveis enquanto são executados como um usuário diferente. Do ponto de vista do seu app, cada usuário está executando em um dispositivo completamente separado.
Como identificar usuários em um ambiente multiusuário
Caso seu app queira identificar usuários únicos, por exemplo, para coletar análises ou criar outra conta
associações, você deve seguir as práticas recomendadas para identificar
e instalações exclusivas. Crie uma nova UUID
quando o app for iniciado para o
pela primeira vez, você certamente obterá um ID exclusivo para rastrear cada usuário, independentemente de quantos
que os usuários instalem
seu app em um único dispositivo. Como alternativa, você pode salvar um token local buscado em
seu servidor ou use o ID de registro fornecido pelo Google Cloud Messaging.
Esteja ciente de que, se o aplicativo solicitar um dos identificadores de dispositivo de hardware (como o MAC Wi-Fi
endereço ou o número da SERIAL
), elas fornecerão o mesmo valor para cada
usuário, porque esses identificadores estão vinculados ao hardware e não ao usuário. Sem mencionar o outro
problemas que esses identificadores apresentam, conforme discutido no tópico Como
Postagem do blog sobre instalações de apps (em inglês).
Novas configurações globais
Com a adição do Settings.Global
, as configurações do sistema foram atualizadas para oferecer suporte a vários usuários. Este conjunto de configurações é semelhante às configurações do Settings.Secure
, porque são somente leitura, mas são aplicáveis globalmente
todos os espaços do usuário no dispositivo.
Várias configurações atuais foram realocadas aqui de Settings.System
ou Settings.Secure
. Se o app for
fazendo mudanças nas configurações definidas anteriormente em Settings.System
(como AIRPLANE_MODE_ON
), espere que
isso não funcionará mais em um dispositivo com Android 4.2 ou superior se essas configurações forem
movidos para Settings.Global
. Você pode continuar a ler as configurações que estão em
Settings.Global
, mas como as configurações não são mais consideradas seguras
caso os apps mudem, essa ação vai falhar silenciosamente, e o sistema vai escrever um aviso para
o registro do sistema ao executar o aplicativo no Android 4.2 ou superior.
Suporte a layout RTL
O Android agora oferece diversas APIs que permitem criar interfaces do usuário que funcionam Transforme a orientação do layout para oferecer suporte a idiomas que usam interfaces e leitura da direita para a esquerda (RTL, na sigla em inglês) direção, como árabe e hebraico.
Para começar a oferecer suporte a layouts RTL no seu app, defina o atributo android:supportsRtl
como o elemento <application>
no arquivo de manifesto.
e defini-lo como “true"
. Depois de ativar isso, o sistema vai ativar várias APIs RTL para
exibir seu aplicativo com layouts RTL. Por exemplo, a barra de ações vai mostrar o ícone e o título
no lado direito e nos botões de ação à esquerda, e todos os layouts que você criou com o
As classes View
fornecidas pelo framework também serão revertidas.
Se você precisar otimizar ainda mais a aparência do aplicativo quando exibido com um layout RTL, há dois níveis básicos de otimização:
- Converter propriedades de layout orientadas à esquerda e à direita em um layout orientado ao início e ao final
propriedades.
Por exemplo, use
android:layout_marginStart
. no lugar deandroid:layout_marginLeft
eandroid:layout_marginEnd
no lugar deandroid:layout_marginRight
.A classe
RelativeLayout
também fornece o layout correspondente para substituir as posições esquerda/direita, comoandroid:layout_alignParentStart
para substituirandroid:layout_alignParentLeft
eandroid:layout_toStartOf
em vez deandroid:layout_toLeftOf
. - Ou, para fornecer otimização completa para layouts RTL, você pode fornecer arquivos totalmente
arquivos de layout usando o qualificador de recurso
ldrtl
(ldrtl
significa layout-direção-da direita para a esquerda}). Por exemplo, você pode salvar seus arquivos de layout padrão emres/layout/
e seus layouts otimizados para RTL emres/layout-ldrtl/
.O qualificador
ldrtl
é ótimo para recursos drawable, que permite fornecer gráficos que são orientados na direção correspondente à direção de leitura.
Várias outras APIs estão disponíveis no framework para dar suporte a layouts RTL, como em
a classe View
para que você possa implementar os comportamentos adequados para
visualizações e em Configuration
para consultar a direção atual do layout.
Observação: se você estiver usando o SQLite e tiver tabelas ou nomes de colunas
"somente número" ser
cuidado: o uso de String.format(String, Object...)
pode causar erros em que os números
foram convertidos para os equivalentes em árabe caso seu dispositivo tenha sido configurado para a localidade árabe.
Use String.format(Locale,String,Object...)
para garantir que os números sejam
preservados como ASCII. Use também String.format("%d", int)
em vez de
String.valueOf(int)
para
e formatação de números.
Fragments aninhados
Agora é possível incorporar fragmentos dentro de fragmentos. Isso é útil para diversas situações em
que você quer colocar componentes de IU dinâmicos e reutilizáveis em um componente de IU que seja próprio
dinâmico e reutilizável. Por exemplo, se você usar ViewPager
para
criar fragmentos que deslizam para a esquerda e para a direita e consomem a maior parte do espaço da tela,
Agora é possível inserir fragmentos em cada página de fragmentos.
Para aninhar um fragmento, basta chamar getChildFragmentManager()
no
o Fragment
em que você quer adicionar um fragmento. Isso retorna um FragmentManager
que pode ser usado normalmente na atividade de nível superior.
para criar transações de fragmentos. Por exemplo, aqui está um código que adiciona um fragmento de dentro
uma classe Fragment
já existente:
Kotlin
val videoFragment = VideoPlayerFragment() childFragmentManager.beginTransaction().apply { add(R.id.video_fragment, videoFragment) commit() }
Java
Fragment videoFragment = new VideoPlayerFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.video_fragment, videoFragment).commit();
A partir de um fragmento aninhado, você pode obter uma referência ao fragmento pai chamando
getParentFragment()
:
A Biblioteca de Suporte do Android agora também oferece suporte a fragmentos aninhados, para que você possa implementar designs de fragmentos no Android 1.6 e mais recentes.
Observação:não é possível inflar um layout em um fragmento quando ele
inclui um <fragment>
. Fragmentos aninhados são aceitos apenas quando adicionados a um
fragmentar dinamicamente.
RenderScript
A funcionalidade de computação do Renderscript foi aprimorada com os seguintes recursos:
- Intrínsecos do script
É possível usar os intrínsecos de script integrados do Renderscript que implementam operações comuns, como:
Blends
Blur
Color matrix
3x3 convolve
5x5 convolve
Per-channel lookup table
Converting an Android YUV buffer to RGB
Para usar um script intrínseco, chame o método estático
create()
de cada para criar uma instância do script. Em seguida, você chama a funçãoset()
disponível métodos intrínsecos de cada script para definir as entradas e opções necessárias. Por fim, chame o métodoforEach()
para executar o script.- Grupos de script
-
ScriptGroup
s permitem encadear o Renderscript relacionado. scripts e executá-los com uma chamada.Usar um
ScriptGroup.Builder
para adicionar todos os scripts ao grupo chameaddKernel()
. Quando você adicionar todos os scripts, criar as conexões entre os scripts chamandoaddConnection()
. Quando terminar de adicionar as conexões, chamecreate()
. para criar o grupo de scripts. Antes de executar o grupo de scripts, especifique a entradaAllocation
e o script inicial a ser executado com a métodosetInput(Script.KernelID, Allocation)
e fornecer a saídaAllocation
em que o resultado será gravado e o script final executar comsetOutput()
. Por fim, chameexecute()
para executar o grupo de scripts. - Filterscript (em inglês)
-
O Filterscript define restrições nas APIs Renderscript existentes que permitem que o código resultante seja executado em uma variedade maior de processadores (CPUs, GPUs e DSPs). Para criar arquivos Filterscript, crie
.fs
. em vez de.rs
e especificar#pragma rs_fp_relaxed
para informar ao tempo de execução do Renderscript que os scripts não exigem precisão de ponto flutuante IEEE 754-2008 rigorosa. Essa precisão permite a liberação de zero para desnormalização e arredondamento em direção a zero. Além disso, o Filterscript os scripts não devem usar tipos integrados de 32 bits e devem especificar uma função raiz personalizada usando o__attribute__((kernel))
porque o Filterscript não é compatível com ponteiros, que define a assinatura padrão da funçãoroot()
.
Observação:embora o Filterscript seja compatível com a plataforma, o desenvolvedor O suporte será disponibilizado na versão 21.0.1 das Ferramentas do SDK.
Para obter uma visão detalhada de todas as mudanças de API no Android 4.2, consulte a Relatório de diferenças da API.