Como nas versões anteriores, o Android 17 inclui mudanças de comportamento que podem afetar seu app. As mudanças de comportamento abaixo se aplicam exclusivamente a apps destinados ao Android 17 ou versões mais recentes. Caso seu app seja direcionado ao Android 17 ou a versões mais recentes, faça modificações para oferecer suporte a esses comportamentos, quando aplicável.
Consulte também a lista de mudanças de comportamento que afetam todos os apps
executados no Android 17, independente da targetSdkVersion do app.
Experiência do usuário e interface do sistema
O Android 17 inclui as mudanças a seguir, que têm como objetivo criar uma experiência do usuário mais consistente e intuitiva.
Widget de limite de memória
No Android 17 e versões mais recentes, o sistema aplica um limite de memória rigoroso às atualizações de
RemoteViews para apps destinados ao Android 17 (nível 37 da API) ou
mais recente. Quando um app transmite um objeto RemoteViews para
AppWidgetManager.updateAppWidget,
system_server calcula o consumo total de memória de todos os dados de imagem em
cada bucket de orientação e tamanho no payload. Se a memória total exceder
o limite do sistema (mMaxWidgetBitmapMemory), o sistema vai rejeitar a atualização e
gerar um IllegalArgumentException:
java.lang.IllegalArgumentException: RemoteViews for widget update exceeds maximum bitmap memory usage (used: XXXXX, max: YYYYY)
Para apps que usam o nível 36 da API ou anterior, o sistema registra essa violação de memória
como um aviso (Slog.w) sem gerar uma exceção.
Habilidades do Android
Ver no GitHubGerenciar atualizações do AppWidget e a memória de bitmap
android skills add glance-appwidget-updates-and-memoryComo o sistema calcula o limite de memória
O sistema define o orçamento de memória do bitmap do widget como 6 * width * height bytes
(1.5 * 4 * width * height, equivalente a 1,5 vez o tamanho de um buffer
ARGB_8888 em tela cheia) para a configuração de tela ativa. No nível 37 da API e
em versões mais recentes, esse cálculo inclui:
- Objetos
Bitmapna memória eIconcom suporte a bitmap (Icon.TYPE_BITMAPeIcon.TYPE_ADAPTIVE_BITMAP) armazenados emRemoteViews.mBitmapCache(como chamadas parasetImageViewBitmap,Icon.createWithBitmap,Icon.createWithAdaptiveBitmapou Jetpack GlanceImageProvider(bitmap)). Cada instância exclusiva deBitmapouIconcom suporte a bitmap emmBitmapCacheé contada uma vez por hierarquiaRemoteViews. - As imagens com suporte de URI (
Icon.createWithContentUri,setImageViewUriouImageProvider(uri)do Glance) não são contabilizadas no limite de bytes de IPCRemoteViewsemsystem_server, mas o processo do host do widget decodifica o arquivocontent://referenciado em resolução máxima no próprio heap. Sempre grave uma imagem reduzida emcontext.cacheDirantes de expô-la por um URIFileProvider.
Etapas de mitigação
Para manter as atualizações do widget dentro do limite de memória em smartphones, tablets e dobráveis, faça o seguinte:
Calcule o orçamento de memória de tempo de execução de
WindowMetrics:no nível da API 30 e em versões mais recentes, leia os limites da janela ativa deWindowManager.currentWindowMetrics.boundsem vez deresources.displayMetrics. Em dispositivos de várias resoluções e dobráveis,displayMetricspode informar dimensões de tela inativas. Estime o orçamento total de imagens do widget em6L * bounds.width() * bounds.height(), conforme mostrado no exemplo a seguir:private const val FALLBACK_MAX_BYTES = 15_000_000L fun calculateWidgetMemoryCapBytes(context: Context): Long { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { val wm = context.getSystemService(WindowManager::class.java) ?: return FALLBACK_MAX_BYTES val bounds = wm.currentWindowMetrics.bounds return 6L * bounds.width().toLong() * bounds.height().toLong() } val dm = context.resources.displayMetrics return 6L * dm.widthPixels.toLong() * dm.heightPixels.toLong() }Reduza a resolução das imagens para as dimensões visíveis do widget e use
RGB_565:decodifique bitmaps com valoresBitmapFactory.Options.inSampleSizede potência de dois dimensionados para as dimensões máximas de exibição do widget (maxWidthDppormaxHeightDp) e useBitmap.Config.RGB_565(2bytes por pixel) em vez deARGB_8888(4bytes por pixel) para fotografias e miniaturas opacas.Decodificação de bitmap de elevação fora de
provideContentno Jetpack Glance:ao usarSizeMode.ResponsiveouSizeMode.Exact, o Glance invoca o lambdaprovideContentuma vez por bucket de tamanho. Decodifique cadaBitmapcompartilhado uma vez dentro deprovideGlanceantes de chamarprovideContentpara que todos os buckets de tamanho façam referência à mesma instância deBitmapemRemoteViews.mBitmapCache.Use chamadas
updateAppWidgetcompletas ao substituir imagens:em implementações clássicas deAppWidgetProvider, evite chamarAppWidgetManager.partiallyUpdateAppWidgetpara trocar visualizações deBitmapouIcon. As atualizações parciais mesclam novas ações na árvoreRemoteViewsexistente emsystem_serversem remover as ações de imagem armazenadas em cache anteriormente. Crie um layoutRemoteViewscompleto e chameupdateAppWidget.Forneça um layout substituto de erro:no Jetpack Glance, substitua
onCompositionErrorpara renderizar um substituto deRemoteViewssem bitmap se uma atualização falhar.
Para inspecionar o uso da memória de bitmap serializada do widget em um dispositivo conectado, execute o seguinte:
adb shell dumpsys appwidget
Principal recurso
O Android 17 inclui as mudanças abaixo, que modificam ou ampliam vários recursos principais do sistema Android.
Nova implementação sem bloqueio de MessageQueue
A partir do Android 17, os apps destinados ao Android 17 (nível 37 da API)
ou mais recente recebem uma nova implementação sem bloqueio de
android.os.MessageQueue. A nova implementação melhora o desempenho e
reduz os frames perdidos, mas pode causar falhas em clientes que refletem em campos e métodos particulares
de MessageQueue.
Para mais informações, incluindo estratégias de mitigação, consulte as orientações sobre mudanças de comportamento da MessageQueue.
Os campos finais estáticos agora não podem ser modificados
Os apps executados no Android 17 ou versões mais recentes que segmentam
o Android 17 (nível 37 da API) ou versões mais recentes não podem mudar os campos static final. Se
um app tentar mudar um campo static final usando reflexão, isso vai
causar um IllegalAccessException. A tentativa de modificar um desses campos
com APIs JNI (como SetStaticLongField()) vai causar uma falha no app.
Acessibilidade
O Android 17 faz as mudanças abaixo para melhorar a acessibilidade.
Suporte de acessibilidade para digitação complexa em teclado físico com IME
This feature introduces new AccessibilityEvent and TextAttribute
APIs to enhance screen reader spoken feedback for CJKV language input. CJKV IME
apps can now signal whether a text conversion candidate has been selected during
text composition. Apps with edit fields can specify text change types when
sending text changed accessibility events.
For example, apps can specify that a text change occurred during text
composition, or that a text change resulted from a commit.
Doing this enables accessibility
services such as screen readers to deliver more precise feedback based on the
nature of the text modification.
App adoption
IME Apps: When setting composing text in edit fields, IMEs can use
TextAttribute.Builder.setTextSuggestionSelected()to indicate whether a specific conversion candidate was selected.Apps with Edit Fields: Apps that maintain a custom
InputConnectioncan retrieve candidate selection data by callingTextAttribute.isTextSuggestionSelected(). These apps should then callAccessibilityEvent.setTextChangeTypes()when dispatchingTYPE_VIEW_TEXT_CHANGEDevents. Apps targeting Android 17 (API level 37) that use the standardTextViewwill have this feature enabled by default. (That is,TextViewwill handle retrieving data from the IME and setting text change types when sending events to accessibility services).Accessibility Services: Accessibility services that process
TYPE_VIEW_TEXT_CHANGEDevents can callAccessibilityEvent.getTextChangeTypes()to identify the nature of the modification and adjust their feedback strategies accordingly.
Privacidade
O Android 17 inclui as mudanças abaixo para melhorar a privacidade do usuário.
ECH (Encrypted Client Hello) ativado
Android 17 introduces platform support for Encrypted Client Hello (ECH), a TLS extension that enhances user privacy by encrypting the Server Name Indication (SNI) in the TLS handshake. This encryption helps prevent network observers from easily identifying the specific domain your app is connecting to.
For apps targeting Android 17 (API level 37) or higher, ECH is used for TLS connections. ECH is active only if the networking library used by the app (for example, HttpEngine, WebView, or OkHttp) has integrated ECH support and the remote server also supports the ECH protocol. If ECH cannot be negotiated, the client sends an ECH extension with randomized contents (a mechanism called ECH GREASE). See RFC 9849 for more details on how ECH GREASE works.
To allow apps to customize this behavior, Android 17 adds a new
<domainEncryption> element to the Network Security Configuration file.
Developers can use <domainEncryption> within <base-config> or
<domain-config> tags to select an ECH mode (for example,
"enabled" or "disabled") on a global or per-domain basis.
For more information, see the Encrypted Client Hello documentation.
Permissão de rede local necessária para apps destinados ao Android 17
O Android 17 apresenta a permissão de execução ACCESS_LOCAL_NETWORK
para proteger os usuários contra o acesso não autorizado à rede local. Como isso se enquadra
no grupo de permissões NEARBY_DEVICES, os usuários que já
concederam outras permissões NEARBY_DEVICES não vão receber uma nova solicitação. Esse novo
requisito impede que apps mal-intencionados usem o acesso irrestrito à rede local
para rastreamento de usuários e técnicas de impressão digital. Ao declarar e solicitar
essa permissão, seu app pode descobrir e se conectar a dispositivos na rede de área
local (LAN), como dispositivos de casa inteligente ou receptores de transmissão.
Os apps destinados ao Android 17 (nível 37 da API) ou versões mais recentes agora têm duas maneiras de manter a comunicação com dispositivos LAN: adotar seletores de dispositivos mediados pelo sistema e que preservam a privacidade para pular a solicitação de permissão ou solicitar explicitamente essa nova permissão no momento da execução para manter a comunicação com a rede local.
Para mais informações, consulte a documentação sobre permissão de rede local.
Ocultar senhas de dispositivos físicos
Se um app for direcionado ao Android 17 (nível 37 da API) ou versões mais recentes e o usuário estiver usando
um dispositivo de entrada físico (por exemplo, um teclado externo), o sistema operacional
Android vai aplicar a nova configuração show_passwords_physical a todos
os caracteres no campo de senha. Por padrão, essa configuração oculta todos os caracteres
da senha.
O sistema Android mostra o último caractere digitado para ajudar o usuário a ver se ele digitou a senha incorretamente. No entanto, isso é muito menos necessário com teclados externos maiores. Além disso, os dispositivos com teclados externos geralmente têm telas maiores, o que aumenta o risco de alguém ver a senha digitada.
Se o usuário estiver usando a touch screen do dispositivo, o sistema vai aplicar a nova
configuração show_passwords_touch.
Proteção de OTP para mensagens SMS padrão
Beginning with Android 17, Android is extending its SMS OTP protection
to apply to standard SMS messages (SMS messages containing an OTP that do not
use the WebOTP or SMS Retriever formats). For most apps targeting
Android 17 (API level 37) or higher, these SMS messages do not become
available until three hours after receipt. This delay is intended to help
prevent OTP hijacking. During this three hour delay, the
SMS_RECEIVED_ACTION broadcast is withheld and
SMS provider database queries are filtered. The SMS message is
available to these apps after the delay.
Certain apps such as the default SMS assistant app, connected device companion apps, etc., are exempted from this delay. All apps that rely on reading SMS messages for OTP extraction should transition to using SMS Retriever or SMS User Consent APIs to ensure continued functionality.
Segurança
O Android 17 traz as seguintes melhorias para a segurança de dispositivos e apps.
Segurança de atividades
No Android 17, a plataforma continua a transição para uma arquitetura "segura por padrão", introduzindo um conjunto de melhorias projetadas para mitigar exploits de alta gravidade, como phishing, sequestro de interação e ataques de deputado confuso. Essa atualização exige que os desenvolvedores aceitem explicitamente os novos padrões de segurança para manter a compatibilidade do app e a proteção do usuário.
Os principais impactos para os desenvolvedores incluem:
- Reforço da BAL e melhoria da ativação:estamos refinando as restrições de inicialização de atividades em segundo plano (BAL, na sigla em inglês) ao estender as proteções para
IntentSender. Os desenvolvedores precisam migrar da constante legadaMODE_BACKGROUND_ACTIVITY_START_ALLOWED. Em vez disso, adote controles granulares, comoMODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE, que restringe as inicializações de atividades a cenários em que o app de ligação está visível, reduzindo significativamente a superfície de ataque. - Ferramentas de adoção:os desenvolvedores precisam usar o modo estrito e as verificações de lint atualizadas para identificar padrões legados e garantir a prontidão para os requisitos futuros do SDK de destino.
Ativar CT por padrão
Se um app for direcionado ao Android 17 (nível 37 da API) ou versões mais recentes, a transparência de certificados (CT, na sigla em inglês) será ativada por padrão. No Android 16, a CT está disponível, mas os apps precisavam ativar.
DCL nativa mais segura: C
Se o app for direcionado ao Android 17 (nível 37 da API) ou versões mais recentes, a proteção de carregamento dinâmico de código (DCL, na sigla em inglês) mais seguro, introduzida no Android 14 para arquivos DEX e JAR, agora se estende às bibliotecas nativas.
Todos os arquivos nativos carregados usando System.load() precisam ser marcados como somente leitura.
Caso contrário, o sistema vai gerar UnsatisfiedLinkError.
Recomendamos que os apps evitem carregar código dinamicamente sempre que possível, porque isso aumenta muito o risco de comprometimento do app por injeção ou adulteração de código.
Restringir campos de PII na visualização de dados do CP2
For apps targeting Android 17 (API level 37) and higher, Contacts Provider 2 (CP2) restricts certain columns containing Personally Identifiable Information (PII) from the data view. When this change is enabled, these columns are removed from the data view to enhance user privacy. The restricted columns include:
Apps that are using these columns from ContactsContract.Data
can extract them from ContactsContract.RawContacts
instead, by joining with RAW_CONTACT_ID.
Aplicar verificações rigorosas de SQL no CP2
Para apps destinados ao Android 17 (nível 37 da API) e
versões mais recentes, o Provedor de Contatos 2 (CP2) aplica uma validação rigorosa de consultas SQL quando
a tabela ContactsContract.Data é acessada sem
a permissão READ_CONTACTS.
Com essa mudança, se um app não tiver a permissão READ_CONTACTS, as opções StrictColumns e StrictGrammar serão definidas ao consultar a tabela ContactsContract.Data. Se uma consulta
usar um padrão incompatível com eles, ela será
rejeitada e causará uma exceção.
Inteligência
O Android 17 inclui as seguintes mudanças na inteligência do sistema.
Descontinuação de setContentCaptureEnabled
A Captura de Conteúdo é ativada por padrão em determinados dispositivos para permitir que os recursos de IA no dispositivo analisem o conteúdo da tela para experiências inteligentes.
A partir do Android 17, o método da API
ContentCaptureManager.setContentCaptureEnabled(boolean)
foi descontinuado. Para apps destinados ao Android 17 (nível 37 da API) ou
mais recente, chamar setContentCaptureEnabled(false) não desativa mais a captura de
conteúdo.
Se o app precisar continuar desativando a captura de conteúdo ou restringindo a captura
de conteúdo da tela pelo sistema, faça a transição para o
parâmetro de layout de janela FLAG_SECURE.
Para desativar a Captura de Conteúdo, defina a flag FLAG_SECURE na janela, conforme mostrado
no exemplo a seguir:
Kotlin
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
Java
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
);
Para mais detalhes, consulte a
documentação de referência do
WindowManager.LayoutParams.FLAG_SECURE.
Mídia
O Android 17 inclui as seguintes mudanças no comportamento de mídia.
Proteção de áudio em segundo plano
A partir do Android 17, o framework de áudio aplica restrições a interações de áudio em segundo plano, incluindo reprodução de áudio, solicitações de foco de áudio e APIs de mudança de volume para garantir que essas mudanças sejam iniciadas intencionalmente pelo usuário.
Algumas restrições de áudio se aplicam a todos os apps. No entanto, as restrições são mais rigorosas se um app for direcionado ao Android 17 (nível 37 da API). Se um desses apps interagir com áudio enquanto estiver em segundo plano, ele precisará ter um serviço em primeiro plano em execução. Além disso, o app precisa atender a um ou ambos os seguintes requisitos:
- O serviço em primeiro plano precisa ter recursos de uso (WIU, na sigla em inglês).
- O app precisa ter a permissão de alarme exato e interagir com
streams de áudio
USAGE_ALARM.
Para mais informações, incluindo estratégias de mitigação, consulte Proteção de áudio em segundo plano.
Formatos de dispositivo
O Android 17 inclui as mudanças a seguir para melhorar a experiência do usuário em vários tamanhos e formatos de dispositivos.
Mudanças na API Platform para ignorar restrições de orientação, redimensionamento e proporção em telas grandes (sw>=600 dp)
Introduzimos mudanças na API Platform no Android 16 para ignorar restrições de orientação, redimensionamento e proporção em telas grandes (sw >= 600 dp) para apps destinados ao nível 36 ou mais recente da API. Os desenvolvedores têm a opção de desativar essas mudanças com o SDK 36, mas essa desativação não vai estar mais disponível para apps destinados ao Android 17 (nível 37 da API) ou mais recente.
Para mais informações, consulte As restrições de orientação e redimensionamento são ignoradas.
Conectividade
O Android 17 apresenta a mudança abaixo para melhorar a consistência e
se alinhar ao comportamento padrão do Java InputStream para soquetes RFCOMM Bluetooth.
Comportamento consistente de read() do BluetoothSocket para RFCOMM
For apps targeting Android 17 (API level 37), the
read() method of the InputStream obtained from an
RFCOMM-based BluetoothSocket now returns -1 when the
socket is closed or the connection is dropped.
This change makes RFCOMM socket behavior consistent with LE CoC sockets and
aligns with the standard InputStream.read()
documentation, which states that -1 is returned when the end of the stream is
reached.
Apps that rely solely on catching an IOException to break out of a read loop may
be impacted by this change and should update the BluetoothSocket read loops to
explicitly check for a return value of -1. This ensures the loop terminates
correctly when the remote device disconnects or the socket is closed. For an
example of the recommended implementation, see the
code snippet in the Transfer Bluetooth data
guide.