Behavior changes: Apps targeting Android 15 or higher

Like previous releases, Android 15 includes behavior changes that might affect your app. The following behavior changes apply exclusively to apps that are targeting Android 15 or higher. If your app is targeting Android 15 or higher, you should modify your app to support these behaviors properly, where applicable.

Be sure to also review the list of behavior changes that affect all apps running on Android 15 regardless of your app's targetSdkVersion.

Core functionality

Android 15 modifies or expands various core capabilities of the Android system.

Changes to foreground services

We are making the following changes to foreground services with Android 15.

New media processing foreground service type

Android 15 introduces a new foreground service type, mediaProcessing. This service type is appropriate for operations like transcoding media files. For example, a media app might download an audio file and need to convert it to a different format before playing it. You can use a mediaProcessing foreground service to make sure the conversion continues even while the app is in the background.

For more information about the mediaProcessing service type, see Changes to foreground service types for Android 15.

Restrictions on BOOT_COMPLETED broadcast receivers launching foreground services

There are new restrictions on BOOT_COMPLETED broadcast receivers launching foreground services. BOOT_COMPLETED receivers are not allowed to launch the following types of foreground services:

If a BOOT_COMPLETED receiver tries to launch any of those types of foreground services, the system throws ForegroundServiceStartNotAllowedException.

Key management for end-to-end encryption

We are introducing the E2eeContactKeysManager in Android 15, which facilitates end-to-end encryption (E2EE) in your Android apps by providing an OS-level API for the storage of cryptographic public keys.

The E2eeContactKeysManager is designed to integrate with the platform contacts app to give users a centralized way to manage and verify their contacts' public keys.

User experience

Android 15 includes some changes that are intended to create a more consistent, intuitive user experience.

Window inset changes

There are two related window inset related changes coming in Android 15. In Beta 1, edge-to-edge will be enforced. There are also upcoming configuration changes, including the default configuration of system bars.

Edge-to-edge enforcement

Apps will be edge-to-edge by default on Android 15+ devices after they target SDK 35.

An app that targets Android 14 and is not edge-to-edge on an Android 15 device.
An app that targets Android 15 and is edge-to-edge on an Android 15 device. This app mostly uses Material 3 Compose Components that automatically apply insets. This screen is not negatively impacted by the Android 15 edge-to-edge enforcement.

This is a breaking change that might negatively impact your app's UI. The changes are as follows:

  • Gesture handle navigation bar
    • Transparent by default.
    • Bottom offset is disabled so content draws behind the system navigation bar unless insets are applied.
    • setNavigationBarColor and and R.attr#navigationBarColor is deprecated and does not affect gesture navigation.
    • setNavigationBarContrastEnforced and R.attr#navigationBarContrastEnforced continues to have no effect on gesture navigation.
  • 3 button navigation
    • Opacity set to 80% by default, with color possibly matching the window background.
    • Bottom offset disabled so content draws behind the system navigation bar unless insets are applied.
    • setNavigationBarColor and R.attr#navigationBarColor is set to match the window background by default. The window background must be a color drawable for this default to apply. This API is deprecated but continues to affect three button navigation.
    • setNavigationBarContrastEnforced and R.attr#navigationBarContrastEnforced is true by default, which adds an 80% opaque background across three button navigation.
  • Status bar
    • Transparent by default.
    • The top offset is disabled so content will draw behind the status bar unless insets are applied.
    • setStatusBarColor and R.attr#statusBarColor are deprecated and have no effect on Android 15.
    • setStatusBarContrastEnforced and R.attr#statusBarContrastEnforced are deprecated but still have an effect on Android 15.
  • Display cutout
    • layoutInDisplayCutoutMode of non-floating windows must be LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS. Otherwise apps will crash with an IllegalArgumentException. ALWAYS is the only allowed option so that users don't see a Black bar caused by the display cutout in landscape mode and therefore appear edge-to-edge.

The following example shows an app before and after targeting SDK 35, and before and after applying insets.

An app that targets Android 14 and is not edge-to-edge on an Android 15 device.
An app that targets Android 15 and is edge-to-edge on an Android 15 device. However, many elements are now occluded by the status bar, 3-button navigation bar, or display cutout due to the Android 15 edge-to-edge enforcements. Occluded UI includes the Material 2 TopAppBar, FAB, and list items.
An app that targets Android 15, is edge to edge on an Android 15 device and applies insets so that UI is not occluded.

If your app:

  • is already edge-to-edge and applies insets, you are mostly unimpacted, except in the following scenarios. However, even if you feel you aren't impacted, we recommend you test your app.
    • Your app crashes because you have a non-floating window, such as an Activity that uses SHORT_EDGES, NEVER or DEFAULT instead of LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS. If your app crashes on launch, this may be due to your splashscreen. Until a fix is available, set window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutInDisplayCutoutMode.always.
    • There may be lower traffic screens with occluded UI. Verify these less visited screens don't have occluded UI. Lower traffic screens include:
      • Onboarding or sign-in screens
      • Settings pages
  • is not edge-to-edge, you are most likely impacted. In addition to the scenarios for apps that are already edge-to-edge, you will need to consider the following:
    • If your app uses Material 3 Components (androidx.compose.material3) in compose, such as TopAppBar, BottomAppBar, and NavigationBar, these components are likely not impacted because they automatically handle insets.
    • If your app is using Material 2 Components (androidx.compose.material) in Compose, these components don't automatically handle insets. However, you can get access to the insets and apply them manually. In androidx.compose.material 1.6.0 and later use the windowInsets parameter to apply the insets manually for BottomAppBar, TopAppBar, BottomNavigation, and NavigationRail. Likewise, use the contentWindowInsets parameter for Scaffold.
    • If your app uses Views and Material Components (com.google.android.material), most Views based Material Components such as BottomNavigationView, BottomAppBar, NavigationRailView, or NavigationView, handle insets and require no additional work. However, you will need to add android:fitsSystemWindows="true" if using AppBarLayout.
    • For custom Composables, apply the insets manually as padding. If your content is within a Scaffold, you may consume insets using Scaffold's padding values. Otherwise, apply padding using one of the WindowInsets.
    • If your app is using Views and BottomSheet, SideSheet or custom containers, apply padding using ViewCompat.setOnApplyWindowInsetsListener. For RecyclerView, apply padding using this listener and also add clipToPadding="false".
  • must offer custom background protection to three button navigation or the status bar, you app should place a composable or view behind the system bar using WindowInsets.Type#tappableElement() to get the three button navigation bar height or WindowInsets.Type#statusBars.

See the Edge to Edge Views and Edge to Edge Compose guides for additional considerations on applying insets.

The list of deprecated and disabled APIs are:

  • R.attr#statusBarColor
  • R.attr#navigationBarColor
  • R.attr#navigationBarDividerColor
  • Window#setDecorFitsSystemWindows
  • Window#setStatusBarColor
  • Window#setStatusBarContrastEnforced
  • Window#setNavigationBarColor
  • Window#setNavigationBarDividerColor
  • Window#getStatusBarColor
  • Window#getStatusBarContrastEnforced
  • Window#getNavigationBarColor
  • Window#getNavigationBarDividerColor

Stable configuration

This change is not available to test in Beta 1, but is coming soon.

If your app targets Android 15 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:

elegantTextHeight attribute defaults to true

For apps targeting Android 15, the elegantTextHeight TextView attribute becomes true by default, replacing the compact font used by default with some scripts that have large vertical metrics with one that is much more readable. The compact font was introduced to prevent breaking layouts; Android 13 (API level 33) prevents many of these breakages by allowing the text layout to stretch the vertical height utilizing the fallbackLineSpacing attribute.

In Android 15, the compact font still remains in the system, so your app can set elegantTextHeight to false to get the same behavior as before, but it is unlikely to be supported in upcoming releases. So, if your app supports the following scripts: Arabic, Lao, Myanmar, Tamil, Gujarati, Kannada, Malayalam, Odia, Telugu or Thai, test your app by setting elegantTextHeight to true.

elegantTextHeight behavior for apps targeting Android 14 (API level 34) and lower.
elegantTextHeight behavior for apps targeting Android 15.

Updated non-SDK restrictions

Android 15 includes updated lists of restricted non-SDK interfaces based on collaboration with Android developers and the latest internal testing. Whenever possible, we make sure that public alternatives are available before we restrict non-SDK interfaces.

If your app does not target Android 15, some of these changes might not immediately affect you. However, while it's possible for your app to access some non-SDK interfaces depending on your app's target API level, using any non-SDK method or field always carries a high risk of breaking your app.

If you are unsure if your app uses non-SDK interfaces, you can test your app to find out. If your app relies on non-SDK interfaces, you should begin planning a migration to SDK alternatives. Nevertheless, we understand that some apps have valid use cases for using non-SDK interfaces. If you can't find an alternative to using a non-SDK interface for a feature in your app, you should request a new public API.

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.