O Android 9 (API de nível 28) introduz diversas mudanças ao sistema Android. As mudanças de comportamento a seguir se aplicam a todos os aplicativos quando são executados na plataforma Android 9, independentemente do nível de API ao qual eles estejam direcionados. Todos os desenvolvedores devem analisar essas mudanças e adaptar seus aplicativos a elas sempre que aplicável.
Consulte as mudanças que afetam somente aplicativos direcionados ao nível de API 28 ou superior em Mudanças de comportamento: aplicativos direcionados a níveis de API acima do 28.
Gerenciamento de energia
O Android 9 introduz novos recursos para melhorar o gerenciamento de energia dos dispositivos. Essas mudanças, além dos recursos apresentados antes do Android 9, ajudam a garantir que os recursos do sistema estejam disponíveis aos aplicativos que mais precisam.
Para ver detalhes, leia Gerenciamento de energia.
Mudanças de privacidade
Para proteger ainda mais a privacidade do usuário, o Android 9 lança diversas mudanças de comportamento, como a limitação do acesso a sensores do dispositivo por parte dos aplicativos em segundo plano, a restrição de informações obtidas de verificações de Wi-Fi e novas regras e grupos de permissão relacionadas a chamadas telefônicas, ao estado do telefone e a verificações de Wi-Fi.
Essas mudanças afetam todos os aplicativos que operam no Android 9, independentemente da versão-alvo do SDK.
Acesso limitado a sensores quando em segundo plano
O Android 9 limita o acesso à interação do usuário e a dados dos sensores para aplicativos em segundo plano. Se seu aplicativo estiver sendo executado em segundo plano em um dispositivo com Android 9, o sistema aplicará as seguintes restrições a ele:
- O aplicativo não poderá acessar o microfone nem a câmera.
- Sensores que usam o modo de relatório continuous , como acelerômetros e giroscópios, não receberão eventos.
- Sensores que usam os modos de relatório on-change ou one-shot não receberão eventos.
Se seu aplicativo precisar detectar eventos de sensor em dispositivos com o Android 9, use um serviço de primeiro plano.
Acesso restrito a registros de chamada
O Android 9 apresenta o grupo
de permissões
CALL_LOG
e transfere as permissões
READ_CALL_LOG
,
WRITE_CALL_LOG
e
PROCESS_OUTGOING_CALLS
para esse grupo. Nas versões anteriores do Android, essas permissões
ficavam no grupo de permissões PHONE
.
O grupo de permissões CALL_LOG
dá aos usuários maior controle e visibilidade
dos aplicativos que precisam de acesso a informações confidenciais sobre chamadas telefônicas, como
a leitura do registro de chamadas e a identificação de números de telefone.
Se o aplicativo precisa acessar o registro de chamadas ou processar chamadas feitas, você
deve solicitar essas permissões explicitamente pelo grupo de permissões
CALL_LOG
.
Caso contrário, uma
SecurityException
vai ser gerada.
Observação: como essas permissões mudaram os grupos e são concedidas em tempo de execução, é possível que o usuário negue o acesso às informações do registro de chamadas telefônicas ao seu aplicativo. Nesse caso, o aplicativo deve ser capaz de lidar com a falta de acesso às informações sem problemas.
Se seu aplicativo já segue as práticas recomendadas para permissões em tempo de execução, ele consegue lidar com a mudança no grupo de permissões.
Acesso restrito a números de telefone
Os aplicativos que operam no Android 9 não podem ler números de telefone ou o estado do telefone sem
antes adquirir a permissão
READ_CALL_LOG
,
além de outras permissões que dependem do caso de uso
do aplicativo.
Números de telefone associados a chamadas feitas e recebidas são visíveis na
transmissão
do estado do telefone,
assim como para as chamadas feitas e recebidas, e podem ser acessados com a classe
PhoneStateListener
.
Porém, sem a permissão
READ_CALL_LOG
,
o campo do número de telefone fornecido nas transmissões
PHONE_STATE_CHANGED
e pelo PhoneStateListener
fica vazio.
Para ler números de telefone pelo estado do telefone, atualize seu aplicativo e faça-o solicitar as permissões necessárias de acordo com o caso de uso:
Para ler números pela ação da intent de
PHONE_STATE
, você precisa das permissõesREAD_CALL_LOG
eREAD_PHONE_STATE
.Para ler números com
onCallStateChanged()
, você precisa somente da permissãoREAD_CALL_LOG
. Você não precisa da permissãoREAD_PHONE_STATE
.
Acesso restrito às informações de localização e conexão do Wi-Fi
No Android 9, as necessidades de permissão que um aplicativo tem para realizar verificações de Wi-Fi são mais restritas do que nas versões anteriores. Para saber mais, acesse Restrições de verificação de Wi-Fi.
Restrições semelhantes também se aplicam ao método
getConnectionInfo()
,
que retorna um objeto WifiInfo
que descreve a conexão com Wi-Fi atual. Você só pode usar os métodos desse
objeto para obter os valores de SSID e BSSID se o aplicativo solicitante tiver as seguintes
permissões:
- ACCESS_FINE_LOCATION ou ACCESS_COARSE_LOCATION
- ACCESS_WIFI_STATE
Para obter o SSID ou o BSSID, os serviços de localização do dispositivo devem estar habilitados (em Configurar > Localização).
Informações removidas dos métodos de serviço Wi-Fi
No Android 9, os eventos e transmissões a seguir não recebem informações sobre a localização nem sobre dados pessoais do usuário:
- Os métodos
getScanResults()
egetConnectionInfo()
deWifiManager
. - Os métodos
discoverServices()
eaddServiceRequest()
deWifiP2pManager
. - A transmissão
NETWORK_STATE_CHANGED_ACTION
.
A transmissão NETWORK_STATE_CHANGED_ACTION
do sistema pelo Wi-Fi não contém mais o SSID (antes chamado de EXTRA_SSID),
o BSSID (antes chamado de EXTRA_BSSID) nem informações da conexão (antes chamadas de
EXTRA_NETWORK_INFO). Se o aplicativo precisar dessas informações, chame
getConnectionInfo()
.
Agora as informações de telefonia dependem da configuração de localização do dispositivo
Se o usuário desativou a localização do dispositivo em um dispositivo com Android 9, os métodos abaixo não produzem resultado:
Restrições para o uso de interfaces que não fazem parte do SDK
Para ajudar a garantir a estabilidade e a compatibilidade do aplicativo, a plataforma restringe o uso de de alguns métodos e campos não pertencentes ao SDK. Essas restrições se aplicam mesmo que você tente acessar os métodos e campos diretamente, via reflexão ou usando JNI. No Android 9, seu aplicativo pode continuar acessando essas interfaces restritas — a plataforma usa toasts e entradas de registro para chamar sua atenção. Se seu aplicativo mostrar esse toast, é importante adotar uma estratégia de implementação diferente da interface restrita. Se você acredita que estratégias alternativas não são viáveis, registre um bug para solicitar uma reavaliação da restrição.
O Restrições em interfaces externas ao SDK contém mais informações importantes. Você deve ler esse artigo para ter certeza de que o seu aplicativo continue funcionando corretamente.
Mudanças de comportamento de segurança
Mudanças na segurança do dispositivo
O Android 9 traz diversos recursos que aumentam a segurança do aplicativo, seja qual for a versão de plataforma dele.
Mudanças na implementação do TLS
A implementação do TLS do sistema sofreu diversas alterações no Android 9:
- Se uma instância de
SSLSocket
não se conectar enquanto estiver sendo criada, o sistema gerará umaIOException
, e não mais umaNullPointerException
. - A classe
SSLEngine
passa a gerenciar de forma simples todos os alertas declose_notify
que ocorrerem.
Para saber mais sobre como criar solicitações web seguras em um aplicativo Android, leia Um exemplo de HTTPS.
Filtro de SECCOMP mais rígido
O Android 9 restringe ainda mais as chamadas de sistema disponíveis aos aplicativos. Esse comportamento é uma extensão do filtro de SECCOMP incluso no Android 8.0 (API de nível 26).
Observação: essa mudança só afeta aplicativos que usam chamadas de sistema privilegiadas.
Mudanças na criptografia
O Android 9 introduz várias mudanças na implementação e no processamento de algoritmos criptográficos.
Implementações Conscrypt de parâmetros e algoritmos
O Android 9 oferece mais implementações de parâmetros de algoritmo no Conscrypt. Esses parâmetros incluem: AES, DESEDE, OAEP e EC. As versões do Bouncy Castle desses parâmetros e muitos algoritmos foram removidos a partir do Android 9.
Observação: A implementação do Conscrypt do parâmetro EC só oferece suporte a curvas nomeadas.
Se seu aplicativo for destinado ao Android 8.1 (nível de API 27) ou a uma versão anterior, você receberá um aviso
quando solicitar uma implementação Bouncy Castle de um desses algoritmos
obsoletos. Porém, se seu aplicativo é voltado ao Android 9, cada uma dessas solicitações gerará um
NoSuchAlgorithmException
.
Outras mudanças
O Android 9 apresenta diversas outras alterações relacionadas a criptografia:
- Ao usar chaves PBE, se o Bouncy Castle estiver esperando um vetor de inicialização (IV) e seu aplicativo não fornecer um, você receberá um aviso.
- A implementação Conscrypt da cifra ARC4 permite que você especifique ARC4/ECB/NoPadding ou ARC4/NONE/NoPadding.
- O provedor Crypto Java Cryptography Architecture (JCA) foi removido. Por esse
motivo, se seu aplicativo chamar
SecureRandom.getInstance("SHA1PRNG", "Crypto")
, umaNoSuchProviderException
ocorrerá. - Se seu aplicativo analisar chaves RSA em buffers maiores do que a estrutura da chave, não ocorrerá mais uma exceção.
Para saber mais sobre como usar os recursos criptográficos do Android, leia Criptografia.
Arquivos criptografados protegidos pelo Android não têm mais suporte
O Android 9 remove totalmente o suporte a arquivos criptografados protegidos Android (ASECs).
No Android 2.2 (API de nível 8), os ASECs foram lançados para que houvesse compatibilidade com o recurso "aplicativos em cartão SD". No Android 6.0 (API de nível 23), a plataforma lançou uma tecnologia de dispositivo de armazenamento adotável, que os desenvolvedores podem usar no lugar do ASECs.
Atualizações nas bibliotecas de ICU
O Android 9 usa a versão 60 da biblioteca ICU. O Android 8.0 (API de nível 26) e o Android 8.1 (API de nível 27) usam a ICU 58.
A ICU é usada para fornecer APIs públicas dentro de android.icu package
e é usada internamente na plataforma Android para suporte à internacionalização.
Por exemplo, ela é usada para implementar classes Android em java.util
, java.text
e android.text.format
.
A atualização para a ICU 60 contém muitas alterações pequenas, mas úteis, como o suporte a dados do Emoji 5.0 e melhorias nos formatos de data/hora, conforme documentado nas notas da versão 59 e 60 da ICU.
Estas são algumas mudanças de destaque dessa atualização:
- A forma como a plataforma lida com fusos horários mudou.
- A plataforma lida melhor com GMT e UTC (UTC não é mais sinônimo de
GMT).
A ICU agora fornece nomes de fusos traduzidos para GMT e UTC. Essa mudança afeta o comportamento de formatação e análise de
android.icu
para fusos como "GMT", "Etc/GMT", "UTC", "Etc/UTC” e "Zulu". java.text.SimpleDateFormat
agora usa a ICU para fornecer nomes de exibição para UTC/GMT, o que significa que:- A formatação
zzzz
gera uma string longa localizada para muitas localidades. Antes, ela produzia "UTC" para UTC e strings como "GMT+00H00" para GMT. - A análise de
zzzz
reconhece strings como "Universal Coordinated Time” e "Greenwich Mean Time". - Os aplicativos podem experimentar problemas de compatibilidade se presumirem
que "UTC" ou "GMT+00:00" são saídas de
zzzz
em todos os idiomas.
- A formatação
- O comportamento de
java.text.DateFormatSymbols.getZoneStrings()
mudou:- Assim como com
SimpleDateFormat
, UTC e GMT agora têm nomes longos. Variantes DST de nomes de fusos horários para UTC, como as "UTC", "Etc/UTC” e "Zulu", se tornaram GMT+00:00, que é a alternativa padrão quando não há nomes disponíveis, em vez da string codificadaUTC
. - Alguns IDs de fusos são corretamente reconhecidos como sinônimos de outros
fusos, portanto, o Android encontra strings para
IDs de fusos arcaicos, como
Eire
, que antes não podiam ser resolvidos.
- Assim como com
- Ásia/Hanoi não é mais um fuso reconhecido. Por esse motivo,
java.util.TimeZones.getAvailableIds()
não retorna esse valor ejava.util.TimeZone.getTimeZone()
não o reconhece. Esse comportamento é consistente com o comportamentoandroid.icu
existente.
- A plataforma lida melhor com GMT e UTC (UTC não é mais sinônimo de
GMT).
- O método
android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String)
pode gerar umaParseException
, mesmo ao analisar texto de moeda legítimo. Para evitar esse problema, useNumberFormat.parseCurrency
, disponível desde o Android 7.0 (API de nível 24), para texto de moeda com estiloPLURALCURRENCYSTYLE
.
Mudanças no Android Test
O Android 9 introduziu diversas mudanças à biblioteca e à estrutura de classes da estrutura do Android Test. Essas mudanças ajudam os desenvolvedores a usar APIs públicas compatíveis com a biblioteca, mas também dão maior flexibilidade de desenvolvimento e execução de testes usando bibliotecas de terceiros ou lógica personalizada.
Bibliotecas removidas da estrutura
O Android 9 reorganiza as classes baseadas em JUnit em três bibliotecas:
android.test.base, android.test.runner e android.test.mock.
Com essa mudança, você pode executar testes na versão do JUnit que funciona melhor
com as dependências do seu projeto. Essa versão do JUnit pode ser diferente
da que android.jar
oferece.
Se quiser saber mais sobre como as classes baseadas em JUnit são organizadas nessas três bibliotecas e aprender a preparar o projeto do seu aplicativo para o desenvolvimento e execução de testes, leia Configurar o projeto para o Android Test.
Mudanças na compilação do conjunto de teste
O método addRequirements()
na classe
TestSuiteBuilder
foi removido e a classe TestSuiteBuilder
em si ficou obsoleta.
O método addRequirements()
exigia que os desenvolvedores fornecessem argumentos cujos
tipos são APIs ocultas, o que tornava a API inválida.
Decodificador de UTF Java
UTF-8 é o conjunto de caracteres padrão no Android. Uma sequência de bytes UTF-8 pode ser decodificada
por um construtor String
, como String(byte[] bytes)
.
O decodificador de UTF-8 do Android 9 segue os padrões Unicode com mais firmeza do que as versões anteriores. As mudanças são:
- A forma não mais curta de UTF-8, como
<C0, AF>
, é tratada como se tivesse sido formada incorretamente. - A forma substituta de UTF-8, como
U+D800
..U+DFFF
, é tratada como se tivesse sido formada incorretamente. - A subparte máxima é substituída por um só
U+FFFD
. Por exemplo, na sequência de bytes "41 C0 AF 41 F4 80 80 41
," as subpartes máximas são "C0
," "AF
" e "F4 80 80
“. "F4 80 80
" pode ser a subsequência inicial de "F4 80 80 80
", mas "C0
" não pode ser a subsequência inicial de qualquer sequência de unidades de código formada corretamente. Portanto, a saída deve ser "A\ufffd\ufffdA\ufffdA
." - Para decodificar uma sequência UTF-8/CESU-8 modificada no Android 9, use o método
DataInputStream.readUTF()
ou o método JNINewStringUTF()
.
Verificação de nome do host usando um certificado
RFC 2818 descreve dois
métodos para fazer a correspondência de um nome de domínio com um certificado — usando os
nomes disponíveis na extensão subjectAltName
(SAN
) ou na falta de uma extensão
SAN
, executando fallback para commonName
(CN
).
No entanto, o fallback para o CN
foi tornado obsoleto na RFC 2818. Por esse motivo,
o Android deixou de fazer o fallback para o CN
. Para verificar um nome do host, o servidor
deve apresentar um certificado com um SAN
correspondente. Certificados que não
contêm um SAN
correspondente ao nome do host não são mais confiáveis.
Buscas de endereço de rede podem causar violações de rede
Buscas de endereços de rede que exigem resolução de nome podem envolver E/S de rede e, portanto, são consideradas operações de bloqueio. Operações de bloqueio no thread principal podem causar pausas ou travamentos.
A classe StrictMode
é uma ferramenta de desenvolvimento que ajuda
desenvolvedores a detectar problemas no código.
No Android 9 e em versões mais recentes, StrictMode
detecta violações
de rede causadas por buscas de endereço de rede que exigem resolução de nome.
Você não deve configurar seus aplicativos com StrictMode
ativado. Caso contrário,
os aplicativos podem apresentar novas exceções, como
NetworkOnMainThreadException
, ao usar os métodos
detectNetwork()
ou
detectAll()
, para ter uma
política que detecte violações de rede.
A resolução de um endereço IP numérico não é considerada uma operação de bloqueio. Esse tipo de resolução funciona melhor como nas versões anteriores ao Android 9.
Tagging de soquete
Nas versões da plataforma anteriores ao Android 9, se um soquete é
marcado usando o método
setThreadStatsTag()
,
é desmarcado ao ser enviado a outro processo usando o
associador IPC
com um contêiner ParcelFileDescriptor
.
A partir do Android 9, a tag do soquete é mantida quando ele é enviado a outro
processo usando um associador IPC. Essa mudança pode afetar as estatísticas de tráfego de rede, por
exemplo, quando se usa o método
queryDetailsForUidTag()
.
Se quiser manter o comportamento das versões anteriores, em que o soquete
é desmarcado quando é enviado a outro processo, chame
untagSocket()
antes de
enviá-lo.
Quantidade informada de bytes disponíveis no soquete
O método available()
retorna 0
quando é chamado
após invocar o método shutdownInput()
.
Relatórios de recursos de rede mais detalhados para VPNs
No Android 8.1 (API de nível 28) e em versões mais antigas, a classe
NetworkCapabilities
só comunicava um conjunto limitado de
informações de VPNs, como
TRANSPORT_VPN
, mas omitindo
NET_CAPABILITY_NOT_VPN
. Essa limitação
dificultava o processo de determinar se usar uma VPN geraria cobranças
ao usuário do aplicativo. Por exemplo, verificar
NET_CAPABILITY_NOT_METERED
não
determinaria se as redes envolvidas são tarifadas ou não.
A partir do Android 9, quando uma VPN chama o método
setUnderlyingNetworks()
,
o sistema Android mescla os transportes e os recursos de todas as
redes envolvidas e retorna os recursos de rede reais
da rede VPN como o resultado.
No Android 9 e em versões mais recentes, os aplicativos que já verificam
NET_CAPABILITY_NOT_METERED
recebem os recursos de rede da VPN e das
redes envolvidas.
Arquivos na pasta xt_qtaguid não estão mais disponíveis para aplicativos
Do Android 9 em diante, os aplicativos não poderão ter acesso
de leitura direto aos arquivos da pasta /proc/net/xt_qtaguid
. O motivo disso é
garantir a consistência com alguns dispositivos que não têm esses arquivos.
As APIs públicas que dependem desses arquivos, TrafficStats
e
NetworkStatsManager
, continuam funcionando da forma planejada.
Entretanto, as funções
cutils
que não contam com suporte, como a
qtaguid_tagSocket()
,
podem não funcionar da forma esperada— ou simplesmente não funcionar — em dispositivos diferentes.
O requisito FLAG_ACTIVITY_NEW_TASK agora é aplicado
Com o Android 9, não é possível iniciar uma atividade a partir de um
contexto de não atividade, a não ser que você passe o sinalizador de intent
FLAG_ACTIVITY_NEW_TASK
.
Se você tentar iniciar uma atividade sem passar esse sinalizador,
ela não será iniciada e o sistema adicionará uma mensagem no registro.
Observação: a exigência do sinalizador sempre foi o comportamento desejado e foi aplicada em versões anteriores ao Android 7.0 (API de nível 24). Um bug no Android 7.0 impedia a aplicação dessa exigência de sinalizador.
Mudanças na rotação da tela
Começando pelo Android 9, há mudanças importantes ao modo de rotação retrato. No Android 8.0 (API de nível 26), os usuários podiam alternar entre os modos de rotação rotação automática e retrato usando um bloco Quicksettings ou as configurações da tela. O modo retrato foi renomeado como rotação bloqueada e fica ativo quando a rotação automática está desativada. Não há mudanças no modo de rotação automática.
Quando o dispositivo estiver no modo de rotação bloqueada, os usuários poderão fixar a tela em qualquer
rotação permitida pela Activity principal visível. Uma Activity não deve presumir que sempre será
renderizada no modo retrato. Se a Activity principal puder ser renderizada em
várias rotações no modo de rotação automática, as mesmas opções deverão estar disponíveis no
modo de rotação bloqueada, com algumas exceções de acordo com a configuração
screenOrientation
da Activity (veja a tabela abaixo).
Atividades que solicitam uma orientação específica (por exemplo,
screenOrientation=landscape
) ignoram a preferência de bloqueio do usuário e comportam-se
da mesma forma que no Android 8.0.
A preferência de orientação da tela pode ser definida no nível da Activity no Manifesto do Android ou programaticamente com setRequestedOrientation().
O modo de bloqueio de rotação passa a funcionar ao se definir a preferência de rotação do usuário que o WindowManager usa para lidar com a rotação da Activity. A preferência de rotação do usuário pode ser alterada nos casos abaixo. Note que há uma tendência a retornar à rotação natural do dispositivo, que normalmente é no formato retrato para dispositivos com dimensões de um celular:
- Quando o usuário aceita uma sugestão de rotação, a preferência de rotação passa a ser essa sugestão.
- Quando o usuário troca para um aplicativo que força o modo retrato (incluindo a tela de bloqueio ou o inicializador), a preferência de rotação é alterada para retrato.
A tabela a seguir resume o comportamento de rotação das orientações de tela mais comuns:
Orientação da tela | Comportamento |
---|---|
unspecified, user | Na rotação automática e no bloqueio de rotação, a Activity pode ser renderizada no modo retrato ou paisagem (e o inverso). Espere oferecer suporte para layouts no modo retrato e no modo paisagem. |
userLandscape | Na rotação automática e no bloqueio de rotação, a Activity pode ser renderizada no modo paisagem ou paisagem inversa. Espere oferecer suporte apenas para layouts no modo paisagem. |
userPortrait | Na rotação automática e no bloqueio de rotação, a Activity pode ser renderizada no modo retrato ou retrato inverso. Espere oferecer suporte apenas para layouts no modo retrato. |
fullUser | Na rotação automática e no bloqueio de rotação, a Activity pode ser renderizada no modo retrato ou paisagem (e o inverso). Espere oferecer suporte para layouts no modo retrato e no modo paisagem. Os usuários do bloqueio de rotação terão a opção de bloquear no modo retrato inverso, frequentemente em 180º. |
sensor, fullSensor, sensorPortrait, sensorLandscape | A preferência do modo de bloqueio de rotação é ignorada e é tratada como se a rotação automática estivesse ativada. Use isso somente em circunstâncias excepcionais considerando a experiência do usuário com muito cuidado. |
A suspensão de uso do cliente Apache HTTP afeta aplicativos com ClassLoader não padrão
Com o Android 6.0,
removemos o suporte ao cliente Apache HTTP.
Essa mudança não tem efeito na grande maioria dos aplicativos que não são voltados ao
Android 9 ou a uma versão mais recente. No entanto, ela pode afetar determinados aplicativos que
usam uma estrutura ClassLoader
não padrão,
mesmo que os aplicativos não sejam voltados ao Android 9 ou a uma versão mais recente.
O aplicativo pode ser afetado se usar um ClassLoader
não padrão que delega
ao ClassLoader
do sistema explicitamente. Em vez disso, esses aplicativos devem delegar ao
ClassLoader
do aplicativo ao buscar classes em org.apache.http.*
. Se
delegarem ao ClassLoader
do sistema, os aplicativos apresentarão um erro
NoClassDefFoundError
no Android 9 ou em uma versão mais recente,
já que o ClassLoader
do sistema não reconhece mais essas classes. Para
evitar problemas semelhantes no futuro, em geral, os aplicativos devem carregar classes
por meio do ClassLoader
do aplicativo, e não acessar o ClassLoader
do sistema diretamente.
Enumerar câmeras
Os aplicativos que operam em dispositivos Android 9 podem descobrir todas as câmeras disponíveis chamando
getCameraIdList()
.
O aplicativo não deve presumir que o dispositivo só tenha uma câmera traseira ou uma
frontal.
Por exemplo, se o aplicativo tem um botão para alternar entre as câmeras frontal e traseira, pode haver mais de uma câmera frontal ou traseira para escolher. Você deve acessar a lista de câmeras, analisar as características de cada uma e decidir que câmeras vai apresentar ao usuário.