从Android6.0之后,google开始更多地关注用户隐私相关的数据,开始收紧应用请求用户隐私数据(包括设备标识符,短信,联系人,通话记录,帐号等等)的权限...
Android Q开始获取设备标识符的权限就更严格...
对于一个第三方应用,在Android Q上将无法获取到设备唯一标识符
MAC地址具有全局唯一性,无法被用户重置,恢复出厂设置后也不会变化
从Android6.0,本地设备的MAC地址(WLAN和蓝牙),无法通过提供的api WifiInfo.getMacAddress()
和BluetoothAdapter.getDefaultAdapter().getAddress()
获取到了,这两个方法现在会返回默认常量值02:00:00:00:00:00
Android官方不见用MAC标识符作为用户设备的标识符,但是有些应用可能还是需要采集更多的设备信息来判断用户行为,可通过下面方式来获取wifi mac地址和蓝牙的mac地址
private static String getWifiMacAddress() {
byte[] mac = null;
try {
Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces();
if (networkInterfaces == null){
return null;
}
while (networkInterfaces.hasMoreElements()){
NetworkInterface intf = networkInterfaces.nextElement();
if (intf.getName() != null && intf.getName().equalsIgnoreCase("wlan0")){
mac = intf.getHardwareAddress();
break;
}
}
} catch (SocketException ex) {
AccountLog.e(TAG, "failed to get wifi Mac Address", ex);
return null;
}
if (mac == null) {
return null;
}
StringBuilder buf = new StringBuilder();
for (byte aMac : mac) {
buf.append(String.format("%02X:", aMac));
}
if (buf.length()>0) {
buf.deleteCharAt(buf.length() - 1);
}
return buf.toString();
}
private static String getBluetoothMacAddress(Context context) {
return Settings.Secure.getString(context.getContentResolver(), "bluetooth_address");
}
Android Q版本上提供了可随机分配的MAC地址,提供的新的API如下:
/***
Returns MAC address set to be the local randomized MAC address. Depending on user preference, the device may or may not use the returned MAC address for connections to this network.
Information is restricted to Device Owner, Profile Owner, and Carrier apps (which will only obtain addresses for configurations which they create). Other callers will receive a default "02:00:00:00:00:00" MAC address.
*/
WifiConfiguration#getRandomizedMacAddress()
/***
Called by device owner to get the MAC address of the Wi-Fi device.
the MAC address of the Wi-Fi device, or null when the information is not available. (For example, Wi-Fi hasn't been enabled, or the device doesn't support Wi-Fi.)
The address will be in the XX:XX:XX:XX:XX:XX format.
Added in API level 24
*/
DevicePolicyManager#getWifiMacAddress(android.content.ComponentName)
Android 6.0开始引入了一种新的权限模式-运行时权限,用户可在运行时管理应用的权限,如此可以让用户更好地了解和控制权限,如果获取IMEI的 "android.permission.READ_PHONE_STATE"权限就变成dangerous的,需要运行时动态申请;
Android Q后,申请REA_PHONE_STATE权限已没有用了,应用必须拥有READ_PRIVILEGED_PHONE_STATE
权限才能获取IMEI和序列号....在搭载Android Q的设备上,如果你的应用没有该权限,将会发生下列情况:
- 以Android Q为目标平台,则会抛出SecurityException;
- 以Android 9(28)或更低版本为目标平台:
- 如果你的应用有READ_PHONE_STATE权限,TelephonyManager提供的API会直接返回null,Build#getSerial返回Build.UNKNOWN ;
- 否则(没有READ_PHONE_STATE权限),则会抛出SecurityExption
Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID)
On Android 8.0 (API level 26) and higher versions of the platform, a 64-bit number (expressed as a hexadecimal string), unique to each combination of app-signing key, user, and device. Values of ANDROID_ID are scoped by signing key and user. The value may change if a factory reset is performed on the device or if an APK signing key changes
NOTE:For apps that were installed prior to updating the device to a version of Android 8.0 (API level 26) or higher, the value of ANDROID_ID changes if the app is uninstalled and then reinstalled after the OTA. To preserve values across uninstalls after an OTA to Android 8.0 or higher, developers can use Key/Value Backup.
In versions of the platform lower than Android 8.0 (API level 26), a 64-bit number (expressed as a hexadecimal string) that is randomly generated when the user first sets up the device and should remain constant for the lifetime of the user's device. On devices that have multiple users, each user appears as a completely separate device, so the ANDROID_ID value is unique to each user.
NOTE: If the caller is an Instant App the ID is scoped to the Instant App, it is generated when the Instant App is first installed and reset if the user clears the Instant App.
来自https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID
Android 8.0开始对ANDROID_ID做了隐私性相关的变更:
对于应用在Android8.0+设备上的应用:
ANDROID_ID
值,在相同设备上运行但具有不同签署秘钥的应用获取到的ANDROID ID也不会相同;ANDROID_ID
的值都不会发生变化;ANDROID_ID
的值也不会变化。在Android 7及之前设备运行的应用:
ANDROID_ID会发生变化