Android Q 彻底禁止了第三方应用获取设备的 IMEI 序列号, 无论target编译版本是多少,都不能在 Android Q 设备上获得设备标识符。
官方替换为AndoridID
手机恢复出厂设置,Android ID会重置
如果用户拒绝权限,也还是会获取不到设备标识。
获取AndoridID
public static String getIMEI(Context context) {
String deviceId = null;
try {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
deviceId = Settings.System.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
} else {
// request old storage permission
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return null;
}
deviceId = tm.getDeviceId();
}
if (deviceId == null || "".equals(deviceId)) {
return getLocalMacAddress(context);
}
} catch (Exception e) {
e.printStackTrace();
if (deviceId == null || "".equals(deviceId)) {
return getLocalMacAddress(context);
}
}
return deviceId;
}
public static String getLocalMacAddress(Context context) {
String strMac = null;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.e("=====", "6.0以下");
strMac = getLocalMacAddressFromWifiInfo(context);
return strMac;
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Log.e("=====", "6.0以上7.0以下");
strMac = getMacAddress(context);
return strMac;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Log.e("=====", "7.0以上");
if (!TextUtils.isEmpty(getMacAddress())) {
Log.e("=====", "7.0以上1");
strMac = getMacAddress();
return strMac;
} else if (!TextUtils.isEmpty(getMachineHardwareAddress())) {
Log.e("=====", "7.0以上2");
strMac = getMachineHardwareAddress();
return strMac;
} else {
Log.e("=====", "7.0以上3");
strMac = getLocalMacAddressFromBusybox();
return strMac;
}
}
return "02:00:00:00:00:00";
}
而国内大厂联盟给广告商留了一个后门, OAID (匿名设备标识符, Open Anonymous Device Identifier, 最长64位)
获取 OAID
需要集成某联盟的SDK, 且定制系统的版本也有要求, 具体在以下文档里有说明