Keywords: Android Q | IMEI Access Restrictions | Device Identifiers | Privacy Protection | ANDROID_ID Alternative
Abstract: This article provides an in-depth examination of the significant privacy policy changes regarding device identifier access in Android Q (API level 29). It systematically analyzes the access restriction mechanisms for non-resettable identifiers such as IMEI and serial numbers, based on official documentation and developer feedback. The article explains the causes of SecurityException, the scope of READ_PRIVILEGED_PHONE_STATE permission, and offers complete code implementations using ANDROID_ID as an alternative. By comparing device identifier acquisition strategies across different Android versions, it provides developers with privacy-compliant device identification solutions.
Background of Privacy Policy Changes in Android Q
With the release of Android Q (API level 29), Google introduced stricter privacy protection measures, particularly implementing significant adjustments in device identifier access. This change directly affects traditional methods of obtaining persistent device identifiers such as IMEI (International Mobile Equipment Identity) and serial numbers.
Technical Details of IMEI Access Restrictions
In Android Q and later versions, non-platform applications (i.e., third-party apps) cannot directly obtain IMEI or device serial numbers through TelephonyManager. When attempting to call methods like TelephonyManager.getImei(), the system throws a specific security exception:
java.lang.SecurityException: getImeiForSlot: The user {user_id} does not meet the requirements to access device identifiers.
This restriction stems from a new permission model design. Only applications with the READ_PRIVILEGED_PHONE_STATE permission can access these sensitive identifiers, and this permission is granted exclusively to platform applications and apps with special carrier privileges. Ordinary third-party applications cannot declare or obtain this permission.
Official Documentation and Developer Resources
Android developer documentation clearly states that the intent behind this change is to protect user privacy by preventing cross-app tracking through non-resettable device identifiers. Key reference resources include:
- The device identifiers section in Android privacy guidelines, detailing the types of accessible identifiers and restriction conditions
- Relevant developer feedback and official responses in Google Issue Tracker, documenting practical issues and solutions encountered during development
These resources emphasize that starting from Android Q, developers need to reevaluate device identification strategies and shift toward using resettable or permission-based identifiers.
Alternative Solution: Using ANDROID_ID
To address IMEI access restrictions, the most practical alternative is using Settings.Secure.ANDROID_ID. This 64-bit number is generated when the device is first booted and resets when the device undergoes a factory reset, providing a relatively stable identifier for each app-user combination.
Below is an implementation for obtaining device identifiers compatible with different Android versions:
public static String getDeviceId(Context context) {
String deviceId;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
} else {
final TelephonyManager mTelephony = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
deviceId = mTelephony.getDeviceId();
} else {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
}
}
return deviceId;
}
This implementation follows version compatibility principles: using ANDROID_ID for Android Q and above, while attempting to obtain IMEI first in older versions, falling back to ANDROID_ID if unsuccessful. It's important to note that ANDROID_ID may have different values across different applications and may return fixed values or null in certain custom ROMs.
Consideration of Other Identifiers
Besides ANDROID_ID, developers may consider the following identifiers, each with its own limitations:
- Advertising ID: Obtainable through advertising services, user-resettable, suitable for advertising-related scenarios
- Instance ID: Provided by Firebase, suitable for Google service integration
- Custom UUID: Application-generated identifiers stored in app-private directories
When selecting identifiers, consider specific use cases, privacy compliance requirements, and user control capabilities.
Best Practice Recommendations
Based on Android Q's privacy changes, developers are advised to:
- Comprehensively assess the actual need for device identifiers in applications, avoiding unnecessary collection
- Implement version-aware identifier acquisition logic to ensure backward compatibility
- Clearly inform users about the purpose of identifier collection and usage, following transparency principles
- Prepare fallback solutions for cases where ANDROID_ID may be null or duplicated
- Regularly check Android privacy policy updates and adjust implementation strategies accordingly
By adopting these practices, developers can achieve reasonable device identification functionality while protecting user privacy.