Android 11 introduces tools for testing and debugging your app against the behavior changes in the latest version of the platform. These tools are part of a new compatibility framework that lets app developers turn changes on and off individually. Use this flexibility to toggle a single change off and continue testing your app against other changes in the platform, or to isolate and test against only one behavior change at a time.
Both types of behavior changes can be toggled, including changes that affect all apps and changes that only affect apps targeting Android 11.
How to identify which changes are enabled
You can check which behavior changes are currently enabled using the developer options, logcat, or an ADB command.
Identify enabled changes using developer options

Figure 1. App Compatibility Changes screen in developer options.
You can see which changes are currently enabled and toggle those changes on or off in a device's developer options. To access these options, follow these steps:
- If developer options are not already enabled, enable them.
- Open your device's Settings app and navigate to System > Advanced > Developer options > App Compatibility Changes.
- Select your app from the list.
Each behavior change usually belongs to one of the following two categories:
Changes that affect all apps when they are run on Android 11, regardless of the app's
targetSdkVersion
.These changes are enabled by default in the compatibility framework, and are listed in the UI in the Default Enabled Changes section.
Changes that only affect apps that are targeting Android 11.
These changes are enabled by default in the compatibility framework if your app is targeting Android 11, and are listed in the UI in the Enabled After SDK 29 section.
You'll also notice a section in figure 1 called Default Disabled Changes. Changes that fall into this section are usually experimental changes.
Identify enabled changes using logcat
For each behavior change, the first time during your app's process when your app calls the affected API, the system outputs a logcat message like this one:
D CompatibilityChangeReporter: Compat change id reported: 141455849; UID 10265; state: ENABLED
Each logcat message includes the following information:
- Change ID
- Indicates which change is affecting the app. This value maps to one of the
behavior changes that are listed on the App Compatibility Changes screen
(see figure 1). In this example,
141455849
maps toANONYMIZED_DEVICE_ADDRESS_CHANGE_ID
. - UID
- Indicates which app is affected by the change.
- State
Indicates whether the change is currently affecting the app.
The state can be one of these values:
State Meaning ENABLED
The change is currently enabled and will affect the app's behavior if the app uses the APIs that were changed. DISABLED
The change is currently disabled and will not affect the app.
Note: If this change is disabled because the app's
targetSDKVersion
is below the required threshold (the app is not targeting Android 11), the change will be enabled by default when the app increases itstargetSDKVersion
to target Android 11.LOGGED
The change is being logged through the compatibility framework but can't be toggled on or off. Although this change can't be toggled, it might still affect your app's behavior. See the description of the change in the list of behavior changes for more information. In many cases, these types of changes are experimental and can be ignored.
Identify enabled changes using ADB
Run the following ADB command to see the complete set of changes (both enabled and disabled) on the entire device:
adb shell dumpsys platform_compat
The output lists the following information for each change:
- Change ID
- A unique identifier for this behavior change. For example,
141455849
. - Name
- The name of this behavior change. For example,
ANONYMIZED_DEVICE_ADDRESS_CHANGE_ID
. - targetSDKVersion criteria
Which
targetSDKVersion
the change is gated by (if any).For example, if this change is only enabled for apps targeting SDK version 30 or higher,
enableAfterTargetSdk=29
is output. If the change is not gated bytargetSDKVersion
,enableAfterTargetSdk=0
is output.- Package overrides
The name of each package where the change's default state (either enabled or disabled) has been overridden.
For example, if this is a change that is enabled by default, your app's package name would be listed if you toggled the change off using either the developer options or ADB. In this case, the output would be:
packageOverrides={com.my.package=false}
Changes that are gated by
targetSDKVersion
can be either enabled or disabled by default, so the list of packages can include instances of both true or false, depending on each of those app'stargetSDKVersion
. For example:packageOverrides={com.my.package=true, com.another.package=false}
When to toggle changes
The main purpose of the compatibility framework is to provide you with control and flexibility as you test your app with a new version of Android.
When to toggle changes off
Changes that affect all apps are enabled by default for a specific platform
version, regardless of your app's targetSDKVersion
. Usually, you'll want to test
and update your app for these changes first to ensure that your users on that
version of the platform don't have a degraded app experience. You should also
prioritize testing these changes because you can't toggle these changes off
when using a public release build of Android (to protect the
security of end users).
If your app is targeting a specific targetSDKVersion
, any changes that are
gated by that version will also be enabled by default.
Because your app might be affected by more than one of these changes, you can toggle these changes off one by one. If your app is crashing, use this approach to help you determine which platform change has broken your app.
When to toggle changes on
Changes that are gated by a specific targetSDKVersion
are disabled by default
whenever an app is targeting a lower SDK version than the gated version. In some
cases, you might want to enable these changes.
For example, you might be testing your app against a series of platform changes
in the next targetSdkVersion
. Using developer options or ADB commands, you could
enable and test each gated change one by one, rather than changing your app
manifest and opting in to every change at once. This extra control can help you
test changes in isolation and avoid debugging and updating multiple parts of
your app at once.
Toggle changes on or off
The compatibility framework lets you toggle each change on or off using the developer options or ADB commands. Because toggling changes on or off can cause your app to crash or disable important security changes, there are some restrictions on when you can toggle changes.
Toggle changes using the developer options
Use the developer options to toggle changes on or off. To find the developer options, follow these steps:
- If developer options are not already enabled, enable them.
- Open your device's Settings app and navigate to System > Advanced > Developer options > App Compatibility Changes.
- Select your app from the list.
From the list of changes, find the change that you want to toggle on or off and tap the switch.
Toggle changes using ADB
To toggle a change on or off using ADB, run one of the following commands:
adb shell am compat enable (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME
adb shell am compat disable (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME
Pass either the CHANGE_ID
(for example, 141455849
) or
the CHANGE_NAME
(for example,
ANONYMIZED_DEVICE_ADDRESS_CHANGE_ID
) and your app's
PACKAGE_NAME
.
You can also use the following command to reset a change back to its default state, removing any override that you've set using ADB or the developer options:
adb shell am compat reset (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME
Restrictions on toggling changes
By default, each behavior change is either enabled or disabled. Changes that
affect all apps are enabled by default. Other changes are gated by a
targetSdkVersion
. These changes are enabled by default when an app targets the
corresponding SDK version or higher and disabled by default when an app is
targeting an SDK version lower than the gated version. When you toggle a change
on or off, you override its default state.
To prevent the compatibility framework from being used maliciously, there are some restrictions on when you can toggle changes. Whether or not you can toggle a change depends on the type of change, whether your app is debuggable, and the type of build running on your device. The following table describes when you are allowed to toggle different types of changes:
Build type | Non-debuggable app | Debuggable app | |
---|---|---|---|
All changes | Changes gated by targetSDKVersion | All other changes | |
Developer Preview or Beta build | Can't toggle | Can toggle | Can toggle |
Public user build | Can't toggle | Can toggle | Can't toggle |
Behavior changes included in the compatibility framework
The list in this section describes each behavior change that is included in the compatibility framework in Android 11. Use this list in conjunction with the developer options and ADB commands to test and debug your app.
ADD_CONTENT_OBSERVER_FLAGS
Change ID: 150939131
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For apps targeting Android 11, there is a new public API overload
onChange(boolean, Uri, int)
that includes an integer flags
argument.
This new method is a public SDK alternative for apps that use the non-SDK
onChange()
overloaded method that includes an integer userId
argument.
ADMIN_APP_PASSWORD_COMPLEXITY
Change ID: 123562444
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For admin apps targeting Android 11, throw an error whenever an
app sets a password requirement that is not relevant to the currently assigned
password quality. For example, when the password quality is set to
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
,
an app would not be able to set a minimum password length. In this case, before
trying to set the minimum password length, the app should first call the
setPasswordQuality()
method and only then call the
setPasswordMinimumLength()
method.
In addition, when an admin app targeting Android 11 lowers the password quality, any existing password requirements that no longer apply are reset to their default values.
APP_DATA_DIRECTORY_ISOLATION
Change ID: 143937733
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
Apps that target Android 11 can no longer access files in private data directories of any app, regardless of the other app's target SDK version.
To learn more, see Access to private directories.
APN_READING_PERMISSION_CHANGE_ID
Change ID: 124107808
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For apps targeting Android 11, accessing the APN database now
requires the Manifest.permission.WRITE_APN_SETTINGS
permission.
To learn more about this change, see Restricted read access to APN database.
BACKGROUND_RATIONALE_CHANGE_ID
Change ID: 147316723
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
Apps must now provide a valid rationale every time they request to access the device's location in the background.
To learn more about this change, see the guide on how to Access background location in Android 11 that discusses privacy changes related to location in Android 11.
CALLBACK_ON_CLEAR_CHANGE
Change ID: 119147584
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
Whenever
Editor.clear
is called, a callback is now made to
OnSharedPreferenceChangeListener.onSharedPreferenceChanged
with a null
key.
To learn more about this change, see Callback changes for OnSharedPreferenceChangeListener.
CALLBACK_ON_MORE_ERROR_CODE_CHANGE
Change ID: 130595455
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
The error codes are now expanded for updateAvailableNetworks(List,
Executor,
Consumer)
and setPreferredOpportunisticDataSubscription(int, boolean, Executor,
Consumer)
.
CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE
Change ID: 148180766
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
This is a subtle behavior change to startWatchingMode(String, String,
AppOpsManager.OnOpChangedListener)
.
Before this change the system called back for the switched op. After the change
the system will call back for the actually requested op or all switched ops if
no op is specified.
CAMERA_MICROPHONE_CAPABILITY_CHANGE_ID
Change ID: 136219221
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For apps targeting Android 11, foreground services only receive
camera and microphone while-in-use capabilities when the
R.attr.foregroundServiceType
is configured as
ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
and
ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
respectively in the manifest file. On earlier versions of Android, foreground
services automatically received camera and microphone capabilities.
To learn more about this change, see Foreground service types in Android 11.
CHANGE_BACKGROUND_CUSTOM_TOAST_BLOCK
Change ID: 128611929
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
Apps can no longer post custom toasts in the background. However, apps can still
post toasts using the Toast.makeText(Context, CharSequence,
int)
method and its variants while in the background.
To learn more about this change, see Custom toast views are blocked.
CHANGE_RESTRICT_SAW_INTENT
Change ID: 135920175
Default state: This change can't be toggled. It is only logged by the compatibility framework.
Intents using the android.settings.MANAGE_APP_OVERLAY_PERMISSION
action and
the package
data URI scheme no longer direct the user to an app-specific
screen for managing the associated permission. Instead, the user is directed to
a screen where they can manage all the apps that have requested the permission.
CHANGE_TEXT_TOASTS_IN_THE_SYSTEM
Change ID: 147798919
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
Text toasts are now rendered by the SystemUI instead of in-app. This prevents apps from circumventing restrictions on posting custom toasts in the background.
DEFAULT_SCOPED_STORAGE
Change ID: 149924527
Default state: Enabled for all apps.
All apps targeting Android 11 now use scoped storage by default and can no longer opt out of scoped storage.
However, you can test your app without scoped storage, regardless of your app's target SDK version and manifest flag values, by toggling this change off.
To learn more about the changes to scoped storage in Android 11, see the Scoped storage section on the page about changes to Android storage in Android 11.
EMPTY_INTENT_ACTION_CATEGORY
Change ID: 151163173
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For apps targeting Android 11, the system now throws an error if
an intent filter's action
or
category
is an empty string. A bug
in the platform before Android 11 allowed this case to pass
through without throwing an error. Note that this does not include cases when
the attribute is null or missing, as that has always thrown an error.
FILTER_APPLICATION_QUERY
Change ID: 135549675
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
Apps now need to declare the packages and intents they intend to use before they
can get details about other apps on a device. Such declarations must be made
using the <queries>
tag in the app's manifest.
To learn more about how to query and interact with other installed apps in Android 11, see the package visibility privacy page.
FORCE_ENABLE_SCOPED_STORAGE
Change ID: Value: 132649864
Default state: Disabled for all apps.
All apps targeting Android 11 now use scoped storage by default and can no longer opt out of scoped storage.
However, if your app still targets Android 10 (API level 29) or lower, you can test your app with scoped storage, regardless of your app's target SDK version and manifest flag values, by toggling this change on.
To learn more about the changes to scoped storage in Android 11, see the Scoped storage section on the page about changes to Android storage in Android 11.
GET_DATA_CONNECTION_STATE_R_VERSION
Change ID: 148535736
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
To check the SDK version for
PreciseDataConnectionState#getDataConnectionState
.
GET_DATA_STATE_R_VERSION
Change ID: 148534348
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
To check the SDK version for
getDataState()
.
GET_PROVIDER_SECURITY_EXCEPTIONS
Change ID: 150935354
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For apps targeting Android 11 (API level 30) or higher,
getProvider(String)
no longer throws any security exceptions.
GET_TARGET_SDK_VERSION_CODE_CHANGE
Change ID: 145147528
Default state: Enabled for apps that target Android 10 (API level 29) or higher.
To check the SDK version for the SmsManager.sendResolverResult()
method.
GWP_ASAN
Change ID: 135634846
Default state: Disabled for all apps.
Enables sampled native memory bug detection in apps.
To learn more about this change, see the GWP-ASan guide.
HIDE_MAXTARGETSDK_P_HIDDEN_APIS
Change ID: 149997251
Default state: Enabled for apps that target Android 10 (API level 29) or higher.
For apps targeting Android 10 (API level 29) or higher, removes access to all
non-SDK interfaces that are part of the max-target-p
(greylist-max-p
)
list
for Android 10 (API level 29).
HIDE_MAXTARGETSDK_Q_HIDDEN_APIS
Change ID: 149994052
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For apps targeting Android 11 (API level 30) or higher, removes access to all
non-SDK interfaces that are part of the max-target-q
(greylist-max-q
)
list
for Android 11 (API level 30).
To learn more about this change, see non-SDK interfaces that are now blocked in Android 11.
LISTEN_CODE_CHANGE
Change ID: 147600208
Default state: Enabled for apps that target Android 10 (API level 29) or higher.
To check the SDK version for TelephonyManager.listen(PhoneStateListener,
int)
.
MISSING_APP_TAG
Change ID: 150776642
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For apps targeting Android 11, an error is now thrown when an
app's manifest file is missing an application
or instrumentation
tag.
NATIVE_HEAP_POINTER_TAGGING
Change ID: 135754954
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For apps targeting Android 11, native heap allocations now have a non-zero tag in the most significant byte.
To learn more, see Heap pointer tagging.
PHONE_STATE_LISTENER_LIMIT_CHANGE_ID
Change ID: 150880553
Default state: Enabled for all apps.
For apps targeting Android 11, there is now a limit on the number
of PhoneStateListener
objects any process may register via TelephonyManager.listen(PhoneStateListener, int)
.
The default limit is 50, which may change via remote device config updates. This
limit is enforced via an IllegalStateException
thrown from TelephonyManager.listen(PhoneStateListener, int)
when the
offending process attempts to register one too many listeners.
PREVENT_META_REFLECTION_BLACKLIST_ACCESS
Change ID: 142365358
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
Apps targeting Android 11 can no longer use an extra layer of reflection to access non-SDK interfaces that are restricted.
PROCESS_CAPABILITY_CHANGE_ID
Change ID: 136274596
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For apps targeting Android 11, the flag
Context.BIND_INCLUDE_CAPABILITIES
can now be used to pass while-in-use capabilities from the client process to a
bound service.
REMOVE_ANDROID_TEST_BASE
Change ID: 133396946
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For apps targeting Android 11, the android.test.base
library
has been removed if the app does not depend on android.test.runner
(as it
depends on classes from the android.test.base
library).
REQUEST_ACCESSIBILITY_BUTTON_CHANGE
Change ID: 136293963
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
For accessibility services targeting Android 11, the
FLAG_REQUEST_ACCESSIBILITY_BUTTON
flag must now be specified in the accessibility service metadata file.
Otherwise, the flag is ignored.
To learn more about this change, see Declare accessibility button usage in metadata file.
RESOURCES_ARSC_COMPRESSED
Change ID: 132742131
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
Apps targeting Android 11 (API level 30) can't be installed if they
contain a compressed resources.arsc
file or if this file is not aligned on
a 4-byte boundary.
To learn more about this change, see Compressed resource files.
RESTRICT_STORAGE_ACCESS_FRAMEWORK
Change ID: 141600225
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
If your app targets Android 11 and uses the Storage Access
Framework (SAF), you can no longer
access certain directories using the
ACTION_OPEN_DOCUMENT
and
ACTION_OPEN_DOCUMENT_TREE
intent actions. To learn more about these changes, see the Document access
restrictions section
on the page that discusses privacy updates related to storage in
Android 11.
SELINUX_LATEST_CHANGES
Change ID: 143539591
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
This change gates apps access to the untrusted_app_R-targetSDk SELinux domain.
This is one of the foundational changes in the compatibility framework that
allow apps to toggle other changes that are gated by targetSdkVersion
without
changing their app's targetSDKVersion
. For this reason, you should not disable
this change for an app that targets Android 11, or the app will
not function.
This change has no effect for apps that use a shared user ID.
THROW_SECURITY_EXCEPTIONS
Change ID: 147340954
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
Prior to Android 11, a SecurityException
would only be thrown by setEnabled
APIs for a permission error. In
Android 11 this no longer holds true, and a SecurityException
can be thrown for any number of reasons, none of which are exposed to the
caller.
To maintain existing API behavior, if a legacy permission failure or actor
enforcement failure occurs for an app that does not target
Android 11, the exception is coerced into an
IllegalStateException
that
existed in the source prior to Android 11.
USE_SET_LOCATION_ENABLED
Change ID: 117835097
Default state: Enabled for apps that target Android 11 (API level 30) or higher.
Admin apps targeting Android 11 can no longer use
DevicePolicyManager.setSecureSetting(ComponentName, String, String)
to change the deprecated Settings.Secure.LOCATION_MODE
setting. Instead they should use DevicePolicyManager.setLocationEnabled(ComponentName, boolean)
.