如何解析设备所有应用ActivityInfo中android:configChanges的多配置值?
Great question! The configChanges integer you're seeing is actually a bitmask—each configuration change corresponds to a single bit in that integer, and multiple changes are combined by setting multiple bits. Here's how you can decode it into the actual config names you recognize from AndroidManifest.xml:
Core Concept: Bitwise Operations
Each configuration type (like orientation or uiMode) is assigned a unique power-of-2 constant in ActivityInfo (e.g., CONFIG_ORIENTATION = 1, CONFIG_SCREEN_SIZE = 16). When multiple configs are set, their values are added together. To check if a specific config is included, use the bitwise AND (&) operation: if the result is non-zero, that config is part of the set.
Example Implementation (Java)
Create a utility function to map the integer mask to a list of human-readable config names:
import android.content.pm.ActivityInfo; import java.util.ArrayList; import java.util.List; public class ConfigChangesParser { public static List<String> parseConfigChanges(int configChanges) { List<String> configList = new ArrayList<>(); // Check each config type using bitwise AND if ((configChanges & ActivityInfo.CONFIG_ORIENTATION) != 0) { configList.add("orientation"); } if ((configChanges & ActivityInfo.CONFIG_SCREEN_SIZE) != 0) { configList.add("screenSize"); } if ((configChanges & ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE) != 0) { configList.add("smallestScreenSize"); } if ((configChanges & ActivityInfo.CONFIG_UI_MODE) != 0) { configList.add("uiMode"); } if ((configChanges & ActivityInfo.CONFIG_SCREEN_LAYOUT) != 0) { configList.add("screenLayout"); } if ((configChanges & ActivityInfo.CONFIG_LOCALE) != 0) { configList.add("locale"); } if ((configChanges & ActivityInfo.CONFIG_MCC) != 0) { configList.add("mcc"); } if ((configChanges & ActivityInfo.CONFIG_MNC) != 0) { configList.add("mnc"); } if ((configChanges & ActivityInfo.CONFIG_KEYBOARD) != 0) { configList.add("keyboard"); } if ((configChanges & ActivityInfo.CONFIG_KEYBOARD_HIDDEN) != 0) { configList.add("keyboardHidden"); } if ((configChanges & ActivityInfo.CONFIG_TOUCHSCREEN) != 0) { configList.add("touchscreen"); } if ((configChanges & ActivityInfo.CONFIG_DENSITY) != 0) { configList.add("density"); } if ((configChanges & ActivityInfo.CONFIG_FONT_SCALE) != 0) { configList.add("fontScale"); } if ((configChanges & ActivityInfo.CONFIG_LAYOUT_DIRECTION) != 0) { configList.add("layoutDirection"); } if ((configChanges & ActivityInfo.CONFIG_NIGHT_MODE) != 0) { configList.add("nightMode"); } return configList; } }
Example Implementation (Kotlin)
For a more concise Kotlin version:
import android.content.pm.ActivityInfo fun parseConfigChanges(configChanges: Int): List<String> { val configs = mutableListOf<String>() with(ActivityInfo) { if (configChanges and CONFIG_ORIENTATION != 0) configs.add("orientation") if (configChanges and CONFIG_SCREEN_SIZE != 0) configs.add("screenSize") if (configChanges and CONFIG_SMALLEST_SCREEN_SIZE != 0) configs.add("smallestScreenSize") if (configChanges and CONFIG_UI_MODE != 0) configs.add("uiMode") // Add remaining checks as in the Java example } return configs }
Key Notes
- API Version Compatibility: Some constants (like
CONFIG_NIGHT_MODEadded in API 23,CONFIG_LAYOUT_DIRECTIONin API 17) are only available in newer Android versions. However, since you're retrievingActivityInfofrom the system, the mask will only include bits relevant to the device's API level—so checking these constants safely won't cause errors (the bit will just be 0 on older devices). - Matching Manifest Values: The strings returned (like "orientation") exactly match the values you'd set in
android:configChangesin your manifest, making it easy to map back to the original configuration. - Custom Descriptions: If you need user-friendly labels (e.g., "Screen Orientation" instead of "orientation"), just replace the string values in the function with your preferred descriptions.
Usage Example
Once you have your ActivityInfo instance, call the function like this:
ActivityInfo activityInfo = ...; // Your retrieved ActivityInfo List<String> configs = ConfigChangesParser.parseConfigChanges(activityInfo.configChanges); // Now configs contains all the config change items set for the activity
内容的提问来源于stack exchange,提问作者Dhinakaran Thennarasu

