Como nas versões anteriores, o Android 15 inclui mudanças de comportamento que podem afetar seu app. As mudanças de comportamento abaixo se aplicam exclusivamente a apps destinados ao Android 15 ou versões mais recentes. Caso seu app seja direcionado ao Android 15 ou a versões mais recentes, faça modificações para oferecer suporte a esses comportamentos de forma adequada, quando aplicável.
Consulte também a lista de mudanças de comportamento que afetam todos os apps
executados no Android 15, independente da targetSdkVersion do app.
Funcionalidade principal
O Android 15 modifica ou expande vários recursos principais do sistema Android.
Mudanças nos serviços em primeiro plano
We are making the following changes to foreground services with Android 15.
- Data sync foreground service timeout behavior
- New media processing foreground service type
- Restrictions on
BOOT_COMPLETEDbroadcast receivers launching foreground services - Restrictions on starting foreground services while an app holds the
SYSTEM_ALERT_WINDOWpermission
Data sync foreground service timeout behavior
Android 15 introduces a new timeout behavior to dataSync for apps targeting
Android 15 (API level 35) or higher. This behavior also applies to the new
mediaProcessing foreground service type.
The system permits an app's dataSync services to run for a total of 6 hours
in a 24-hour period, after which the system calls the running service's
Service.onTimeout(int, int) method (introduced in Android
15). At this time, the service has a few seconds to call
Service.stopSelf(). When Service.onTimeout() is called, the
service is no longer considered a foreground service. If the service does not
call Service.stopSelf(), the system throws an internal exception. The
exception is logged in Logcat with the following message:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type dataSync did not stop within its timeout: [component name]"
To avoid problems with this behavior change, you can do one or more of the following:
- Have your service implement the new
Service.onTimeout(int, int)method. When your app receives the callback, make sure to callstopSelf()within a few seconds. (If you don't stop the app right away, the system generates a failure.) - Make sure your app's
dataSyncservices don't run for more than a total of 6 hours in any 24-hour period (unless the user interacts with the app, resetting the timer). - Only start
dataSyncforeground services as a result of direct user interaction; since your app is in the foreground when the service starts, your service has the full six hours after the app goes to the background. - Instead of using a
dataSyncforeground service, use an alternative API.
If your app's dataSync foreground services have run for 6 hours in the last
24, you cannot start another dataSync foreground service unless the user
has brought your app to the foreground (which resets the timer). If you try to
start another dataSync foreground service, the system throws
ForegroundServiceStartNotAllowedException
with an error message like "Time limit already exhausted for foreground service
type dataSync".
Testing
To test your app's behavior, you can enable data sync timeouts even if your app
is not targeting Android 15 (as long as the app is running on an Android 15
device). To enable timeouts, run the following adb command:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
You can also adjust the timeout period, to make it easier to test how your
app behaves when the limit is reached. To set a new timeout period, run the
following adb command:
adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds
New media processing foreground service type
O Android 15 apresenta um novo tipo de serviço em primeiro plano, mediaProcessing. Esse
tipo de serviço é adequado para operações como transcodificação de arquivos de mídia. Por
exemplo, um app de mídia pode fazer o download de um arquivo de áudio e precisar convertê-lo para um
formato diferente antes de reproduzi-lo. Você pode usar um serviço em primeiro plano
mediaProcessing para garantir que a conversão continue mesmo quando o app estiver em
segundo plano.
O sistema permite que os serviços mediaProcessing de um app sejam executados por um total de 6
horas em um período de 24 horas. Depois disso, o sistema chama o método
Service.onTimeout(int, int) do serviço em execução (introduzido no Android
15). Nesse momento, o serviço tem alguns segundos para chamar
Service.stopSelf(). Se o serviço não
chamar Service.stopSelf(), o sistema vai gerar uma exceção interna. A
exceção é registrada no Logcat com a seguinte mensagem:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type mediaProcessing did not stop within its timeout: [component name]"
Para evitar a exceção, siga um destes procedimentos:
- Faça com que o serviço implemente o novo método
Service.onTimeout(int, int). Quando o app receber o callback, chamestopSelf()dentro de alguns segundos. Se você não interromper o app imediatamente, o sistema vai gerar uma falha. - Verifique se os serviços
mediaProcessingdo app não são executados por mais de um total de seis horas em qualquer período de 24 horas, a menos que o usuário interaja com o app, redefinindo o timer. - Só inicie serviços em primeiro plano
mediaProcessingcomo resultado da interação direta do usuário. Como o app está em primeiro plano quando o serviço é iniciado, ele tem seis horas completas após o app ir para o segundo plano. - Em vez de usar um serviço em primeiro plano
mediaProcessing, use uma API alternativa, como o WorkManager.
Se os serviços em primeiro plano mediaProcessing do app tiverem sido executados por 6 horas nas
últimas 24 horas, não será possível iniciar outro serviço em primeiro plano mediaProcessing a menos que
o usuário tenha trazido o app para o primeiro plano (o que redefine o timer). Se você
tentar iniciar outro serviço mediaProcessing em primeiro plano, o sistema vai gerar
ForegroundServiceStartNotAllowedException
com uma mensagem de erro como "O limite de tempo já se esgotou para o tipo de serviço em primeiro plano
mediaProcessing".
Para mais informações sobre o tipo de serviço mediaProcessing, consulte Mudanças nos
tipos de serviço em primeiro plano do Android 15: processamento de mídia.
Teste
Para testar o comportamento do app, ative os timeouts de processamento de mídia, mesmo que
o app não seja direcionado ao Android 15 (desde que esteja sendo executado em um
dispositivo Android 15). Para ativar os tempos limite, execute o seguinte comando adb:
adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name
Você também pode ajustar o período de tempo limite para facilitar o teste do comportamento
do app quando o limite for atingido. Para definir um novo período de tempo limite, execute o
seguinte comando adb:
adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds
Restrictions on BOOT_COMPLETED broadcast receivers launching foreground services
Há novas restrições para inicialização de broadcast receivers BOOT_COMPLETED
serviços em primeiro plano. Receptores BOOT_COMPLETED não têm permissão para iniciar o
seguintes tipos de serviços em primeiro plano:
dataSynccameramediaPlaybackphoneCallmediaProjectionmicrophone(esta restrição está em vigor paramicrophonedesde o Android 14)
Se um receptor BOOT_COMPLETED tentar iniciar qualquer um desses tipos de primeiro plano
serviços, o sistema gera ForegroundServiceStartNotAllowedException.
Teste
Para testar o comportamento do app, ative essas novas restrições mesmo que seu
O app não é destinado ao Android 15, desde que seja executado em um Android 15
dispositivo). Execute o seguinte comando adb:
adb shell am compat enable FGS_BOOT_COMPLETED_RESTRICTIONS your-package-name
Para enviar uma transmissão BOOT_COMPLETED sem reiniciar o dispositivo:
Execute o seguinte comando adb:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED your-package-name
Restrictions on starting foreground services while an app holds the SYSTEM_ALERT_WINDOW permission
Previously, if an app held the SYSTEM_ALERT_WINDOW permission, it could launch
a foreground service even if the app was currently in the background (as
discussed in exemptions from background start restrictions).
If an app targets Android 15, this exemption is now narrower. The app now needs
to have the SYSTEM_ALERT_WINDOW permission and also have a visible overlay
window. That is, the app needs to first launch a
TYPE_APPLICATION_OVERLAY window and the window
needs to be visible before you start a foreground service.
If your app attempts to start a foreground service from the background without
meeting these new requirements (and it does not have some other exemption), the
system throws ForegroundServiceStartNotAllowedException.
If your app declares the SYSTEM_ALERT_WINDOW permission
and launches foreground services from the background, it may be affected by this
change. If your app gets a ForegroundServiceStartNotAllowedException, check
your app's order of operations and make sure your app already has an active
overlay window before it attempts to start a foreground service from the
background. You can check if your overlay window is currently visible
by calling View.getWindowVisibility(), or you
can override View.onWindowVisibilityChanged()
to get notified whenever the visibility changes.
Testing
To test your app's behavior, you can enable these new restrictions even if your
app is not targeting Android 15 (as long as the app is running on an Android 15
device). To enable these new restrictions on starting foreground services
from the background, run the following adb command:
adb shell am compat enable FGS_SAW_RESTRICTIONS your-package-name
Mudanças em quando os apps podem modificar o estado global do modo Não perturbe
Apps that target Android 15 (API level 35) and higher can no longer change the
global state or policy of Do Not Disturb (DND) on a device (either by modifying
user settings, or turning off DND mode). Instead, apps must contribute an
AutomaticZenRule, which the system combines into a global policy with the
existing most-restrictive-policy-wins scheme. Calls to existing APIs that
previously affected global state (setInterruptionFilter,
setNotificationPolicy) result in the creation or update of an implicit
AutomaticZenRule, which is toggled on and off depending on the call-cycle of
those API calls.
Note that this change only affects observable behavior if the app is calling
setInterruptionFilter(INTERRUPTION_FILTER_ALL) and expects that call to
deactivate an AutomaticZenRule that was previously activated by their owners.
Mudanças na API OpenJDK
O Android 15 continua o trabalho de atualizar as principais bibliotecas do Android para se alinhar aos recursos das versões mais recentes do LTS do OpenJDK.
Algumas dessas mudanças podem afetar a compatibilidade de apps destinados ao Android 15 (nível 35 da API):
Mudanças nas APIs de formatação de strings: a validação de índice de argumento, flags, largura e precisão agora é mais rigorosa ao usar as seguintes APIs
String.format()eFormatter.format():String.format(String, Object[])String.format(Locale, String, Object[])Formatter.format(String, Object[])Formatter.format(Locale, String, Object[])
Por exemplo, a exceção a seguir é gerada quando um índice de argumento 0 é usado (
%0na string de formato):IllegalFormatArgumentIndexException: Illegal format argument index = 0Nesse caso, o problema pode ser corrigido usando um índice de argumento 1 (
%1na string de formato).Mudanças no tipo de componente de
Arrays.asList(...).toArray(): ao usarArrays.asList(...).toArray(), o tipo de componente da matriz resultante agora é umObject, não o tipo dos elementos da matriz subjacente. Portanto, o código a seguir gera umClassCastException:String[] elements = (String[]) Arrays.asList("one", "two").toArray();Nesse caso, para preservar
Stringcomo o tipo de componente na matriz resultante, useCollection.toArray(Object[]):String[] elements = Arrays.asList("two", "one").toArray(new String[0]);Mudanças no processamento de códigos de idioma: ao usar a API
Locale, os códigos de idioma para hebraico, iídiche e indonésio não são mais convertidos para as formas obsoletas (hebraico:iw, iídiche:jie indonésio:in). Ao especificar o código de idioma para uma dessas localidades, use os códigos do ISO 639-1 (hebraico:he, iídiche:yie indonésio:id).Mudanças nas sequências de números inteiros aleatórios: seguindo as mudanças feitas em https://bugs.openjdk.org/browse/JDK-8301574, os seguintes métodos
Random.ints()agora retornam uma sequência de números diferente dos métodosRandom.nextInt():Em geral, essa mudança não deve resultar em um comportamento que prejudique o app, mas seu código não deve esperar que a sequência gerada pelos métodos
Random.ints()corresponda aRandom.nextInt().
A nova API SequencedCollection pode afetar a compatibilidade do app
depois que você atualizar compileSdk na configuração do build do app para usar
o Android 15 (nível da API 35):
Conflito com as funções de extensão
MutableList.removeFirst()eMutableList.removeLast()emkotlin-stdlibO tipo
Listem Java é mapeado para o tipoMutableListem Kotlin. Como as APIsList.removeFirst()eList.removeLast()foram introduzidas no Android 15 (nível 35 da API), o compilador Kotlin resolve chamadas de função, por exemplo,list.removeFirst(), estaticamente para as novas APIsListem vez das funções de extensão emkotlin-stdlib.Se um app for recompilado com
compileSdkdefinido como35eminSdkdefinido como34ou inferior, e depois o app for executado no Android 14 e versões anteriores, um erro de tempo de execução será gerado:java.lang.NoSuchMethodError: No virtual method removeFirst()Ljava/lang/Object; in class Ljava/util/ArrayList;A opção
NewApido lint no Plug-in do Android para Gradle pode detectar esses novos usos da API../gradlew lintMainActivity.kt:41: Error: Call requires API level 35 (current min is 34): java.util.List#removeFirst [NewApi] list.removeFirst()Para corrigir a exceção de tempo de execução e os erros de lint, as chamadas de função
removeFirst()eremoveLast()podem ser substituídas porremoveAt(0)eremoveAt(list.lastIndex), respectivamente, em Kotlin. Se você estiver usando o Android Studio Ladybug | 2024.1.3 ou mais recente, ele também vai oferecer uma opção de correção rápida para esses erros.Considere remover
@SuppressLint("NewApi")elintOptions { disable 'NewApi' }se a opção de lint tiver sido desativada.Colisão com outros métodos em Java
Novos métodos foram adicionados aos tipos atuais, por exemplo,
ListeDeque. Esses novos métodos podem não ser compatíveis com os métodos de mesmo nome e tipos de argumentos em outras interfaces e classes. No caso de uma colisão de assinatura de método com incompatibilidade, o compiladorjavacgera um erro de tempo de build. Exemplo:Exemplo de erro 1:
javac MyList.javaMyList.java:135: error: removeLast() in MyList cannot implement removeLast() in List public void removeLast() { ^ return type void is not compatible with Object where E is a type-variable: E extends Object declared in interface ListExemplo de erro 2:
javac MyList.javaMyList.java:7: error: types Deque<Object> and List<Object> are incompatible; public class MyList implements List<Object>, Deque<Object> { both define reversed(), but with unrelated return types 1 errorExemplo de erro 3:
javac MyList.javaMyList.java:43: error: types List<E#1> and MyInterface<E#2> are incompatible; public static class MyList implements List<Object>, MyInterface<Object> { class MyList inherits unrelated defaults for getFirst() from types List and MyInterface where E#1,E#2 are type-variables: E#1 extends Object declared in interface List E#2 extends Object declared in interface MyInterface 1 errorPara corrigir esses erros de build, a classe que implementa essas interfaces precisa substituir o método com um tipo de retorno compatível. Exemplo:
@Override public Object getFirst() { return List.super.getFirst(); }
Segurança
O Android 15 inclui mudanças que promovem a segurança do sistema para ajudar a proteger apps e usuários contra apps maliciosos.
Versões TLS restritas
Android 15 restricts the usage of TLS versions 1.0 and 1.1. These versions had previously been deprecated in Android, but are now disallowed for apps targeting Android 15.
Inícios de atividades em segundo plano protegidos
Android 15 protects users from malicious apps and gives them more control over their devices by adding changes that prevent malicious background apps from bringing other apps to the foreground, elevating their privileges, and abusing user interaction. Background activity launches have been restricted since Android 10 (API level 29).
Other changes
- Change
PendingIntentcreators to block background activity launches by default. This helps prevent apps from accidentally creating aPendingIntentthat could be abused by malicious actors. - Don't bring an app to the foreground unless the
PendingIntentsender allows it. This change aims to prevent malicious apps from abusing the ability to start activities in the background. By default, apps are not allowed to bring the task stack to the foreground unless the creator allows background activity launch privileges or the sender has background activity launch privileges. - Control how the top activity of a task stack can finish its task. If the top activity finishes a task, Android will go back to whichever task was last active. Moreover, if a non-top activity finishes its task, Android will go back to the home screen; it won't block the finish of this non-top activity.
- Prevent launching arbitrary activities from other apps into your own task. This change prevents malicious apps from phishing users by creating activities that appear to be from other apps.
- Block non-visible windows from being considered for background activity launches. This helps prevent malicious apps from abusing background activity launches to display unwanted or malicious content to users.
Intents mais seguros
Android 15 introduces StrictMode for
intents.
In order to see detailed logs about Intent usage violations, use following
method:
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() .detectUnsafeIntentLaunch() .build() ) }
Java
public void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() .detectUnsafeIntentLaunch() .build()); }
Experiência do usuário e interface do sistema
O Android 15 inclui algumas mudanças que visam criar uma experiência do usuário mais consistente e intuitiva.
Mudanças no encarte da janela
There are two changes related to window insets in Android 15: edge-to-edge is enforced by default, and there are also configuration changes, such as the default configuration of system bars.
Aplicação de ponta a ponta
Os apps são de ponta a ponta por padrão em dispositivos com Android 15 se o app for destinado ao Android 15 (nível 35 da API).
Essa é uma mudança incompatível que pode afetar negativamente a interface do seu app. As mudanças afetam as seguintes áreas da interface:
- Barra de navegação com alça de gesto
- Transparente por padrão.
- O deslocamento inferior está desativado, então o conteúdo é desenhado por trás da barra de navegação do sistema, a menos que insets sejam aplicados.
setNavigationBarColoreR.attr#navigationBarColorestão descontinuados e não afetam a navegação por gestos.setNavigationBarContrastEnforcedeR.attr#navigationBarContrastEnforcedcontinuam sem efeito na navegação por gestos.
- Navegação com três botões
- Opacidade definida como 80% por padrão, com a cor possivelmente correspondendo ao plano de fundo da janela.
- Deslocamento inferior desativado para que o conteúdo seja mostrado por trás da barra de navegação do sistema, a menos que margens das janelas sejam aplicadas.
setNavigationBarColoreR.attr#navigationBarColorsão definidos para corresponder ao plano de fundo da janela por padrão. O plano de fundo da janela precisa ser um drawable de cor para que esse padrão seja aplicado. Essa API está descontinuada, mas continua afetando a navegação com três botões.setNavigationBarContrastEnforcedeR.attr#navigationBarContrastEnforcedsão verdadeiros por padrão, o que adiciona um plano de fundo 80% opaco na navegação com três botões.
- Barra de status
- Transparente por padrão.
- O deslocamento superior é desativado, então o conteúdo é mostrado por trás da barra de status, a menos que margens das janelas sejam aplicadas.
setStatusBarColoreR.attr#statusBarColorforam descontinuados e não têm efeito no Android 15.setStatusBarContrastEnforcedeR.attr#statusBarContrastEnforcedforam descontinuados, mas ainda têm um efeito no Android 15.
- Corte da tela
- O
layoutInDisplayCutoutModede janelas não flutuantes precisa serLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS.SHORT_EDGES,NEVEReDEFAULTsão interpretados comoALWAYSpara que os usuários não vejam uma barra preta causada pelo corte da tela e apareçam de ponta a ponta.
- O
O exemplo a seguir mostra um app antes e depois de ser direcionado ao Android 15 (nível 35 da API) e antes e depois de aplicar encartes. Este exemplo não é abrangente e pode aparecer de maneira diferente no Android Auto.
O que verificar se o app já é de ponta a ponta
Se o app já for de ponta a ponta e aplicar encartes, você não será muito afetado, exceto nos seguintes cenários. No entanto, mesmo que você não acredite que seu app foi afetado, recomendamos que você o teste.
- Você tem uma janela não flutuante, como um
Activityque usaSHORT_EDGES,NEVERouDEFAULTem vez deLAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS. Se o app falhar na inicialização, isso pode ser devido à tela de apresentação. Você pode fazer upgrade da dependência core splashscreen para 1.2.0-alpha01 ou uma versão mais recente ou definirwindow.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always. - Pode haver telas com menos tráfego e interface obstruída. Verifique se essas telas menos visitadas não têm uma interface obstruída. As telas com menos tráfego incluem:
- Telas de onboarding ou login
- Páginas de configurações
O que verificar se o app ainda não é de ponta a ponta
Se o app ainda não estiver de ponta a ponta, é provável que você seja afetado. Além dos cenários para apps que já são de ponta a ponta, considere o seguinte:
- Se o app usar componentes do Material 3 (
androidx.compose.material3) no Compose, comoTopAppBar,BottomAppBareNavigationBar, é provável que esses componentes não sejam afetados porque processam encartes automaticamente. - Se o app estiver usando componentes do Material 2 (
androidx.compose.material) no Compose, eles não vão processar encartes automaticamente. No entanto, você pode acessar os encartes e aplicá-los manualmente. No androidx.compose.material 1.6.0 e versões mais recentes, use o parâmetrowindowInsetspara aplicar os encartes manualmente emBottomAppBar,TopAppBar,BottomNavigationeNavigationRail. Da mesma forma, use o parâmetrocontentWindowInsetsparaScaffold. - Se o app usa views e componentes do Material Design
(
com.google.android.material), a maioria dos componentes do Material baseados em views, comoBottomNavigationView,BottomAppBar,NavigationRailViewouNavigationView, processa encartes e não exige mais trabalho. No entanto, você precisará adicionarandroid:fitsSystemWindows="true"se estiver usandoAppBarLayout. - Para elementos combináveis personalizados, aplique os encartes manualmente como padding. Se o conteúdo estiver em um
Scaffold, use os valores de padding Scaffoldpara consumir encartes. Caso contrário, aplique o padding usando um dosWindowInsets. - Se o app estiver usando visualizações e
BottomSheet,SideSheetou contêineres personalizados, aplique padding usandoViewCompat.setOnApplyWindowInsetsListener. ParaRecyclerView, aplique padding usando esse listener e também adicioneclipToPadding="false".
O que verificar se o app precisa oferecer proteção de segundo plano personalizada
Se o app precisar oferecer proteção de plano de fundo personalizada para a navegação com três botões ou
a barra de status, ele deverá colocar um elemento combinável ou uma visualização atrás da barra de sistema
usando WindowInsets.Type#tappableElement() para receber a altura da barra de navegação
com três botões ou WindowInsets.Type#statusBars.
Outros recursos de ponta a ponta
Consulte os guias Visualizações de ponta a ponta e Compose de ponta a ponta para mais considerações sobre a aplicação de encartes.
APIs obsoletas
As APIs a seguir estão descontinuadas, mas não desativadas:
R.attr#enforceStatusBarContrastR.attr#navigationBarColor(para navegação com três botões, com alfa de 80%)Window#isStatusBarContrastEnforcedWindow#setNavigationBarColor(para navegação com três botões, com alfa de 80%)Window#setStatusBarContrastEnforced
As APIs a seguir estão desativadas:
R.attr#navigationBarColor(para navegação por gestos)R.attr#navigationBarDividerColorR.attr#statusBarColorWindow#setDecorFitsSystemWindowsWindow#getNavigationBarColorWindow#getNavigationBarDividerColorWindow#getStatusBarColorWindow#setNavigationBarColor(para navegação por gestos)Window#setNavigationBarDividerColorWindow#setStatusBarColor
Configuração estável
If your app targets Android 15 (API level 35) or higher, Configuration no
longer excludes the system bars. If you use the screen size in the
Configuration class for layout calculation, you should replace it with better
alternatives like an appropriate ViewGroup, WindowInsets, or
WindowMetricsCalculator depending on your need.
Configuration has been available since API 1. It is typically obtained from
Activity.onConfigurationChanged. It provides information like window density,
orientation, and sizes. One important characteristic about the window sizes
returned from Configuration is that it previously excluded the system bars.
The configuration size is typically used for resource selection, such as
/res/layout-h500dp, and this is still a valid use case. However, using it for
layout calculation has always been discouraged. If you do so, you should move
away from it now. You should replace the use of Configuration with something
more suitable depending on your use case.
If you use it to calculate the layout, use an appropriate ViewGroup, such as
CoordinatorLayout or ConstraintLayout. If you use it to determine the height
of the system navbar, use WindowInsets. If you want to know the current size
of your app window, use computeCurrentWindowMetrics.
The following list describes the fields affected by this change:
Configuration.screenWidthDpandscreenHeightDpsizes no longer exclude the system bars.Configuration.smallestScreenWidthDpis indirectly affected by changes toscreenWidthDpandscreenHeightDp.Configuration.orientationis indirectly affected by changes toscreenWidthDpandscreenHeightDpon close-to-square devices.Display.getSize(Point)is indirectly affected by the changes inConfiguration. This was deprecated beginning in API level 30.Display.getMetrics()has already worked like this since API level 33.
O atributo elegantTextHeight é definido como "true" por padrão
Em apps destinados ao Android 15 (nível 35 da API), o atributo
elegantTextHeight TextView
passa a ser true por padrão, substituindo a fonte compacta usada por padrão por alguns
scripts com métricas verticais grandes por uma que é muito mais legível.
A fonte compacta foi introduzida para evitar a quebra de layouts. O Android 13 (nível
33 da API) evita muitas dessas quebras, permitindo que o layout de texto
estique a altura vertical usando o atributo
fallbackLineSpacing.
No Android 15, a fonte compacta ainda permanece no sistema. Assim, o app pode definir
elegantTextHeight como false para ter o mesmo comportamento de antes, mas é
improvável que haja suporte a ele nas próximas versões. Portanto, se o app oferecer suporte aos
seguintes scripts: árabe, lao, birmanês, tâmil, gujarati, canarês, malaiala,
odia, télugo ou tailandês, teste o app definindo elegantTextHeight como true.
elegantTextHeight comportamento para apps destinados ao Android 14 (nível 34 da API) e versões anteriores.
elegantTextHeight para apps destinados ao Android 15.Mudanças na largura da TextView para formas de letras complexas
Nas versões anteriores do Android, algumas fontes cursivas ou linguagens que têm
modelagem complexa podiam desenhar as letras na área do caractere anterior ou seguinte.
Em alguns casos, essas letras eram cortadas na posição inicial ou final.
No Android 15 e versões mais recentes, uma TextView aloca largura para desenhar espaço suficiente
para essas letras e permite que os apps solicitem mais paddings à esquerda para
evitar recortes.
Como essa mudança afeta a forma como um TextView decide a largura, o TextView
aloca mais largura por padrão se o app for destinado ao Android 15 (nível 35 da API) ou
mais recente. Para ativar ou desativar esse comportamento, chame a
API setUseBoundsForWidth em TextView.
Como adicionar o padding à esquerda pode causar um desalinhamento nos layouts atuais, ele
não é adicionado por padrão nem mesmo para apps direcionados ao Android 15 ou mais recente.
No entanto, é possível adicionar um padding extra para evitar o corte chamando
setShiftDrawingOffsetForStartOverhang.
Os exemplos a seguir mostram como essas mudanças podem melhorar o layout de texto para algumas fontes e idiomas.
<TextView android:fontFamily="cursive" android:text="java" />
<TextView android:fontFamily="cursive" android:text="java" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
<TextView android:text="คอมพิวเตอร์" />
<TextView android:text="คอมพิวเตอร์" android:useBoundsForWidth="true" android:shiftDrawingOffsetForStartOverhang="true" />
Altura de linha padrão com reconhecimento de localidade para EditText
In previous versions of Android, the text layout stretched the height of the
text to meet the line height of the font that matched the current locale. For
example, if the content was in Japanese, because the line height of the Japanese
font is slightly larger than the one of a Latin font, the height of the text
became slightly larger. However, despite these differences in line heights, the
EditText element was sized uniformly, regardless
of the locale being used, as illustrated in the following image:
EditText elements that
can contain text from English (en), Japanese (ja), and Burmese (my). The
height of the EditText is the same, even though these languages
have different line heights from each other.For apps targeting Android 15 (API level 35), a minimum line height is now
reserved for EditText to match the reference font for the specified Locale, as
shown in the following image:
EditText elements that
can contain text from English (en), Japanese (ja), and Burmese (my). The
height of the EditText now includes space to accommodate the
default line height for these languages' fonts.If needed, your app can restore the previous behavior by specifying the
useLocalePreferredLineHeightForMinimum attribute
to false, and your app can set custom minimum vertical metrics using the
setMinimumFontMetrics API in Kotlin and Java.
Câmera e mídia
O Android 15 faz as seguintes mudanças no comportamento da câmera e da mídia para apps destinados ao Android 15 ou versões mais recentes.
Restrições para solicitar a seleção de áudio
Apps that target Android 15 (API level 35) must be the top app or running a
foreground service in order to request audio focus. If an app
attempts to request focus when it does not meet one of these requirements, the
call returns AUDIOFOCUS_REQUEST_FAILED.
You can learn more about audio focus at Manage audio focus.
Atualização das restrições não SDK
O Android 15 inclui listas atualizadas de interfaces não SDK restritas com base na colaboração com desenvolvedores Android e nos testes internos mais recentes. Antes de restringirmos interfaces não SDK, sempre que possível, garantimos que haja alternativas públicas disponíveis.
Caso seu app não seja destinado ao Android 15, é possível que algumas dessas mudanças não afetem você imediatamente. No entanto, embora seja possível que seu app acesse algumas interfaces não SDK dependendo do nível desejado da API do app, o uso de qualquer método ou campo não SDK sempre apresenta um alto risco de corromper o app.
Se você não souber se seu app usa interfaces não SDK, poderá testá-lo para descobrir. Se ele depende de interfaces não SDK, comece a planejar uma migração para alternativas SDK. No entanto, entendemos que alguns apps têm casos de uso válidos para interfaces não SDK. Se você não encontrar uma alternativa para deixar de usar uma interface não SDK em um recurso no seu app, solicite uma nova API pública.
To learn more about the changes in this release of Android, see Updates to non-SDK interface restrictions in Android 15. To learn more about non-SDK interfaces generally, see Restrictions on non-SDK interfaces.