Android 标识符(MAC,IMEI,ANDROID ID)

从Android6.0之后,google开始更多地关注用户隐私相关的数据,开始收紧应用请求用户隐私数据(包括设备标识符,短信,联系人,通话记录,帐号等等)的权限...

Android Q开始获取设备标识符的权限就更严格...

对于一个第三方应用,在Android Q上将无法获取到设备唯一标识符

硬件标识符访问权(MAC)

MAC地址具有全局唯一性,无法被用户重置,恢复出厂设置后也不会变化

Android 6.0 的变更

从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 的变更

Android Q版本上提供了可随机分配的MAC地址,提供的新的API如下:

  • 获取随机分配的MAC地址
/***
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()
  • 获取实际的出厂硬件MAC地址:此方法对于跟踪设备队列非常有用
/***
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)

不可重置的设备标识符(IMEI和序列号 serialNumber)

Android 6.0 的变更

Android 6.0开始引入了一种新的权限模式-运行时权限,用户可在运行时管理应用的权限,如此可以让用户更好地了解和控制权限,如果获取IMEI的 "android.permission.READ_PHONE_STATE"权限就变成dangerous的,需要运行时动态申请;

Android Q 的变更

Android Q后,申请REA_PHONE_STATE权限已没有用了,应用必须拥有READ_PRIVILEGED_PHONE_STATE 权限才能获取IMEI和序列号....在搭载Android Q的设备上,如果你的应用没有该权限,将会发生下列情况:

  1. 以Android Q为目标平台,则会抛出SecurityException;
  2. 以Android 9(28)或更低版本为目标平台:
  •     如果你的应用有READ_PHONE_STATE权限,TelephonyManager提供的API会直接返回null,Build#getSerial返回Build.UNKNOWN ;
  •     否则(没有READ_PHONE_STATE权限),则会抛出SecurityExption

Settings.Secure.ANDROID_ID

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+设备上的应用:

  • 应用的apk秘钥,用户和设备具有唯一的ANDROID_ID值,在相同设备上运行但具有不同签署秘钥的应用获取到的ANDROID ID也不会相同;
  • 只要签署秘钥相同, apk卸载或重新安装,ANDROID_ID的值都不会发生变化;
  • 即使系统更新导致软件包签署密钥发生变化,ANDROID_ID 的值也不会变化。

在Android 7及之前设备运行的应用:

  • 全局唯一,恢复出厂设置ANDROID_ID会发生变化

你可能感兴趣的:(android)