在我们的 App 开发中, 通常需要获取到设备的唯一标识. 在 Android6.0 之前, 有很多方法我们可以方便获取到硬件的唯一标识, 但是在 Android6.0 之后, Android 系统大幅限制了我们获取设备的硬件信息.
DEVICE_ID
通 getSystemService(Context.TELEPHONY_SERVICE).getDeviceId()获取, 但是 6.0 之后必须申请 READ_PHONE_STATE, 并且获取到的这个值在不同的厂商和设备中并不可靠.
Mac 地址
这个是无线网卡的 Mac 地址, 这个需要 ACCESS_WIFI_STATE 权限, 并且很多情况下并获取不到这个值, 也并不是十分可靠.
ANDROID_ID
这个值是当一个新的设备第一次启动时, 或者恢复出厂设置时, 系统会生成一个 64 位的数字, 这个值目前 (Android4.0 之后) 已经非常可靠, 但是仍有个别厂商的定制系统的 BUG, 导致这个值返回 null.
获取设备唯一标识的正确姿势
由于 ANDROID_ID 的值相对稳定和可靠, 并且不需要申请权限, 所以我们获取设备的唯一标识应该使用这个值, 同时我们应该考虑到一些极端情况和安全问题.
获取 ANDROID_ID
- public static String getAndroidID() {
- String id = Settings.Secure.getString(
- Utils.getApp().getContentResolver(),
- Settings.Secure.ANDROID_ID
- );
- return id == null ? "" : id;
- }
构造 UUID, 防止直接暴露 ANDROID_ID
- private static String getDeviceUUid()
- {
- String androidId = DeviceUtils.getAndroidID();
- UUID deviceUuid = new UUID(androidId.hashCode(), ((long)androidId.hashCode() << 32));
- return deviceUuid.toString();
- }
考虑极端情况, 我们自己生成一个应用级别的 UUID
这种情况我们需要将生成的 UUID 保存到 SharedPreference 中, 只要应用不被卸载或者清除数据, 这个值就不会变.
- private static String getAppUUid() {
- String uuid = SPUtils.getInstance().getString(PREF_KEY_UUID);
- if (TextUtils.isEmpty(uuid)) {
- uuid = UUID.randomUUID().toString();
- // 这里需要保存到 SharedPreference 中
- ...
- }
- return uuid;
- }
将上面的获取方法封装到一个方法中
- public static String getUUID() {
- String uuid = getDeviceUUid();
- if (TextUtils.isEmpty(uuid)) {
- uuid = getAppUUid();
- }
- return uuid;
- }
总结
这些获取 UUID 方法非常简单, 并且在应用的开发中可以满足 99% 的需求, 不需要动态申请权限, 也非常可靠, 但是在使用时需要清楚其生成过程, 以便应用到安全性要求非常高的场景中.
如有更多疑问, 请参考我的其它 Android 相关博客: 我的博客地址
Android 开发 - 获取 Android 设备的唯一标识码(Android 6.0 或更高)
来源: http://www.bubuko.com/infodetail-2811470.html