The Android 12 platform includes behavior changes that may
affect your app. The following behavior changes apply to all apps when they
run on Android 12, regardless of targetSdkVersion
. You should
test your app and then modify it as needed to support these properly, where
applicable.
Make sure to also review the list of behavior changes that only affect apps targeting Android 12.
User experience
Immersive mode improvements for gesture navigation
Android 12 simplifies immersive mode to make gesture navigation easier and more consistent with the rest of the experience of activities such as watching a video and reading a book. Apps can still protect from accidental gestures in full-screen gaming experiences so users don't accidentally quit out of their games while playing; all other full-screen or immersive experiences now allow users to navigate their phone with one swipe.
To make this possible, the existing behaviors for non-sticky immersive
experiences (BEHAVIOR_SHOW_BARS_BY_TOUCH
,
BEHAVIOR_SHOW_BARS_BY_SWIPE
)
are deprecated starting in Android 12. They have been replaced with default
behavior (BEHAVIOR_DEFAULT
)
that allows gestures with one swipe when hiding system bars. This flag exhibits
different visual and functional behavior depending on the mode:
- In three-button mode, visual and functional behavior is the same as immersive mode in versions of Android prior to 12.
- In gestural navigation mode, the behavior is as follows:
- Visually, it’s the same as immersive mode in Android 11 and lower.
- Functionally, gestures are allowed even when the bar is hidden; system back requires only one swipe to invoke instead of the two swipes required for Android 11. No additional swipes are needed to pull down the notification bar or start going Home.
Sticky immersive mode (BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
)
has not changed for Android 12. Note the following backward-compatibility for
this feature:
- For apps running on Android 12 that target Android 11 and lower:
BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
behaves the same functionally and visually.- The default is mapped to
BEHAVIOR_SHOW_BARS_BY_SWIPE
.
- For apps running on Android 11 (API level 30) and lower that target Android
12:
- The same behavior is expected, except
BEHAVIOR_SHOW_BARS_BY_TOUCH
is mapped toBEHAVIOR_SHOW_BARS_BY_SWIPE
. - Make sure to update your SDK level to have the new default (
BEHAVIOR_SHOW_BARS_BY_SWIPE
). Otherwise,BEHAVIOR_SHOW_BARS_BY_TOUCH
remains the default.
- The same behavior is expected, except
Foreground service notification delay
To provide a streamlined experience for short-running foreground services on Android 12, the system can delay the display of foreground service notifications by 10 seconds for certain foreground services. This change gives short-lived tasks a chance to complete before their notifications appear.
If a foreground service has at least one of the following characteristics, the system shows the associated notification immediately after the service starts:
- The service is associated with a notification that includes action buttons.
- The service has a
foregroundServiceType
ofconnectedDevice
,mediaPlayback
,mediaProjection
, orphoneCall
. The service provides a use case related to phone calls, navigation, or media playback, as defined in the notification's category attribute.
The service has opted out of the behavior change by calling
setShowForegroundImmediately()
when setting up the notification.
Privacy
Restrictions on Netlink MAC Address
Android 12 further restricts access to a device's MAC address, a non-resettable identifier, for all non-system apps regardless of target API level.
Related APIs return empty or placeholder values, depending on the app’s target SDK version:
- If your app targets Android 12 the API returns null.
- If your app targets Android 11 or lower the API returns a hard-coded placeholder value:
02:00:00:00:00:00
Developers should use ConnectivityManager
rather than lower-level APIs like NetworkInterface
,
getifaddrs()
, or Netlink sockets. When a developer calls NetworkInterface.getHardwareAddress()
in their code, the logcat output shows:
CompatibilityChangeReporter: Compat change id reported: 170188668;
Developers can use the compatibility flag called
RETURN_NULL_HARDWARE_ADDRESS
to toggle the behavior of NetworkInterface.getHardwareAddress()
between returning null when enabled or 02:00:00:00:00:00
when disabled.
Security
Untrusted touch events are blocked
To preserve system security and a good user experience, Android 12 prevents apps from consuming touch events where an overlay obscures the app in an unsafe way. In other words, the system blocks touches that pass through certain windows, with a few exceptions.
Affected apps
This change affects apps that choose to let touches pass through their windows,
for example by using the
FLAG_NOT_TOUCHABLE
flag. Several examples include, but aren't limited to, the following:
- Overlays that require the
SYSTEM_ALERT_WINDOW
permission, such as windows that useTYPE_APPLICATION_OVERLAY
, and use theFLAG_NOT_TOUCHABLE
flag. - Activity windows that use the
FLAG_NOT_TOUCHABLE
flag. - Toast messages.
Exceptions
In the following cases, "pass-through" touches are allowed:
- Interactions within your app. Your app shows the overlay, and the overlay appears only when the user is interacting with your app.
Trusted windows. These windows include (but aren't limited to) the following:
Invisible windows. The window's root view is
GONE
orINVISIBLE
.Completely transparent windows. The
alpha
property is 0.0 for the window.Sufficiently translucent system alert windows. The system considers a set of system alert windows to be sufficiently translucent when the combined opacity is less than or equal to the system's maximum obscuring opacity for touches. In Developer Preview 1, this maximum opacity is 0.8, but this value might change later in the Developer Preview.
Detect when an untrusted touch is blocked
If a touch action is blocked by the system, Logcat logs the following message:
Untrusted touch due to occlusion by PACKAGE_NAME
Test the change
Untrusted touches are blocked by default on devices that run Android 12 Developer Preview 1. To allow untrusted touches, run the following ADB command in a terminal window:
# A specific app adb shell am compat disable BLOCK_UNTRUSTED_TOUCHES com.example.app # All apps # If you'd still like to see a Logcat message warning when a touch would be # blocked, use 1 instead of 0. adb shell settings put global block_untrusted_touches 0
To revert the behavior to the default (untrusted touches are blocked), run the following command:
# A specific app adb shell am compat reset BLOCK_UNTRUSTED_TOUCHES com.example.app # All apps adb shell settings put global block_untrusted_touches 2
Apps can't close system dialogs
To improve user control when interacting with apps and the system, the
ACTION_CLOSE_SYSTEM_DIALOGS
intent action is deprecated as of Android 12. Except for a few
special cases, when your app tries to invoke
an intent that contains this action, the
system does one of the following based on your app's target SDK version:
- If your app targets Android 12, a
SecurityException
occurs. If your app targets Android 11 (API level 30) or lower, the intent doesn't execute, and the following message appears in Logcat:
E ActivityTaskManager Permission Denial: \ android.intent.action.CLOSE_SYSTEM_DIALOGS broadcast from \ com.package.name requires android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS, \ dropping broadcast.
Exceptions
In the following cases, an app can still close system dialogs on Android 12:
- Your app is running an instrumentation test.
Your app targets Android 11 or lower and is showing a window that is on top of the notification drawer.
Your app targets Android 11 or lower. In addition, the user has interacted with a notification, possibly using the notification's action buttons, and your app is processing a service or broadcast receiver in response to that user action.
Non-SDK interface restrictions
Android 12 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 12, some of these changes might not immediately affect you. However, while you can currently use 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 cannot 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 12. To learn more about non-SDK interfaces generally, see Restrictions on non-SDK interfaces.