应用读取 Device_ID
Android Q 之前有如下代码,获取设备Id,IMEI等
1 2 3 |
TelephonyManager telManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); telManager.getDeviceId(); telManager.getImei(); |
添加下面权限,并且需要动态申请权限
1 |
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> |
在 Android Q 上调用上面方法会报错
1 |
java.lang.SecurityException: getDeviceId: The user xxxx does not meet the requirements to access device identifiers. |
或者
1 2 |
E/Exception: getSubscriberId: The user xxxx does not meet the requirements to access device identifiers. java.lang.SecurityException: getSubscriberId: The user xxxx does not meet the requirements to access device identifiers. |
在 Android Q 上上面方法已经不能使用了,如果获取设备唯一Id,需要使用其他方式了,谷歌提供的获取唯一标识符做法见 文档,也可以用Android_ID,上面这些也不是绝对能得到一个永远不变的Id,可能需要多种方案获取其他Id,比如有谷歌商店的手机可以使用谷歌提供的广告Id,还有其他厂商一般都会提供手机的一个唯一Id。
我们项目现在使用下面这种方式 参考链接。要求生成之后,存储在应用的本地数据库中,读取的时候,优先从本地数据库读取上次存储的设备ID,不要每次都调用下面的接口获取,下面的接口不能保证每次都返回相同结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
public static String getDeviceId(Context context) { final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion; if (targetSdkVersion > Build.VERSION_CODES.P && Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { return getUniqueID(context); } else { return getTelId(context); } } private static String getTelId(Context context) { final TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); return manager.getDeviceId(); } private static String getUniqueID(Context context) { String id = null; final String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); if (!TextUtils.isEmpty(androidId) && !"9774d56d682e549c".equals(androidId)) { try { UUID uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8")); id = uuid.toString(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } if (TextUtils.isEmpty(id)) { id = getUUID(); } return TextUtils.isEmpty(id) ? UUID.randomUUID().toString() : id; } private static String getUUID() { String serial = null; String m_szDevIDShort = "35" + Build.BOARD.length() % 10 + Build.BRAND.length() % 10 + ((null != Build.CPU_ABI) ? Build.CPU_ABI.length() : 0) % 10 + Build.DEVICE.length() % 10 + Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 + Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 + Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 + Build.TAGS.length() % 10 + Build.TYPE.length() % 10 + Build.USER.length() % 10; //13 位 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { serial = android.os.Build.getSerial(); } else { serial = Build.SERIAL; } //API>=9 使用serial号 return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString(); } catch (Exception exception) { serial = "serial" + UUID.randomUUID().toString(); // 随便一个初始化 } } else { serial = android.os.Build.UNKNOWN + UUID.randomUUID().toString(); // 随便一个初始化 } //使用硬件信息拼凑出来的15位号码 return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString(); } |
参考链接