我看到了一个我最好的问题Is there a unique Android device ID?
我使用了以下代码来获取唯一ID。
public static String getDeviceId(Activity context) {
PermissionsChecker checker = new PermissionsChecker(context);
if (checker.lacksPermissions(Manifest.permission.READ_PHONE_STATE))
PermissionsActivity.startActivityForResult(context, 0, REQUIRED_PERMISSION);
else {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice = tm.getDeviceId();
final String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32));
return deviceUuid.toString();
}
return null;
}
但是我在悬停时会收到一些警告
tm.getDeviceId();
和
Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
如下:
建议不要使用getString来获取设备标识符。
除高值外,建议不要使用设备标识符 防欺诈和高级电话用例。用于广告 用例,使用AdvertisingIdClient $ Info#getId并进行分析,使用 INSTANCEID#的getId。
有什么解决方案吗?它有害还是其他什么?
答案 0 :(得分:1)
Andorid Q中添加的限制是getDeviceId
仅适用于系统应用程序。如果尝试使用它,则会抛出异常
SecurityException: getDeviceId: The user 10196 does not meet the requirements to access device identifiers.
您可以从此link
阅读更多的Andorid Q更改无论如何,在搜索并看到许多解决方案后,我发现此解决方案适用于每个Android平台,都能很好地获得UUID。
//This method is fully compatible with Android 1 to Android 10
public static String getDeviceUUID(Context context) {
String serial = null;
String m_szDevIDShort = "35" +
Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +
Build.CPU_ABI.length() % 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 Bit
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
serial = android.os.Build.getSerial();
} else {
serial = Build.SERIAL;
}
//API>=9 Use serial number
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
} catch (Exception exception) {
//serial Need an initialization
serial = "serial"; // Random initialization
}
// 15-digit number cobbled together using hardware information
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
答案 1 :(得分:0)
你无法真正“解决”这个警告。
但是如果你想要,你可以通过添加@SuppressLint(“HardwareIds”)来禁用警告,这将解决这个问题。
请注意,通过此警告,Lint有机会重新考虑您是否需要发布。
答案 2 :(得分:0)
一个非常简单的答案是,如果您需要唯一标识应用程序的每个用户,请在首次使用时为其创建一个随机ID。
UUID.randomUUID().toString()
您可以将其保存在SharedPreferences
中,轻松完成工作。不需要权限
问题在于,如果用户卸载并重新安装该应用程序,它将无法为您提供帮助。
一个可能要到android 10才做的简单技巧(根据google在android 11上将不再可能)将它保存在外部存储中的隐藏文件中...
然后,在首次使用应用程序时,您会寻找此类文件,如果存在,请读取UUID,在不生成新文件的情况下保存文件。
此策略的问题是您需要WRITE_EXTERNAL_STORAGE
权限
万一这不是一个简单的问题...
new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + ".my_hidden_folder").mkdir();
此文件夹中保存的所有文件都将对用户隐藏,在卸载应用程序时不会删除
我个人使用
Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
这不是有害的,只是Google不喜欢您这么做
答案 3 :(得分:0)
我正在使用设备Build.SERIAL
来获取设备的唯一ID
String serial ="";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ActivityCompat.requestPermissions(MainActivity.mainContext, new String[]{Manifest.permission.READ_PHONE_STATE}, RequestCode);
if (ActivityCompat.checkSelfPermission(MainActivity.mainContext, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
// Application Needs permission.READ_PHONE_STATE permission
} else {
serial = Build.getSerial();
}
} else {
serial = Build.SERIAL;
}
我已将此解决方案用于已发布的应用,并且Android 10
或旧版Android都能完美运行。
答案 4 :(得分:0)
很早以前,我需要为每个设备拥有一个永久的唯一ID,并且遇到了相同的问题。 这是我找到的解决方案:
IMEI:最糟糕的解决方案:没有SIM卡的Android设备(例如大量平板电脑)将被排除在外,您需要获得“拨打电话”权限才能获得,这是没人愿意授予的。
设备序列号:好的解决方案,唯一的价值;但在API级别26中已弃用 和新方法needs permission in Android 10.
SSID(又名Android_ID):尽管有警告,我认为这是一个不错的解决方案。没有重复的记录。
一些半唯一的解决方案包括:
Build.FINGERPRINT:构建的唯一记录。没有警告。它将设备限制在较小的范围内。
Build.TIME:自产生设备ROM以来的时间(以毫秒为单位)。
提示::混合硬件属性可能不起作用,因为它们可能很相似(一家工厂生产大量模型),并且为了获得唯一的ID,您可能需要权限。
>提示2:将记录保存在设备内存中是浪费时间,因为始终可以更改/删除它们。