【问题标题】:Unique Android Device ID after MarshMallow warning "get device identifiers is not recommended"?MarshMallow 警告“不建议获取设备标识符”后的唯一 Android 设备 ID?
【发布时间】:2017-03-10 01:38:31
【问题描述】:

我看到了我最好的问题之一Is there a unique Android device ID?

编辑:

我也需要适用于 Android 10 的解决方案。

我使用以下代码来获取唯一 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.

有什么解决办法吗?它是有害的还是其他什么?

【问题讨论】:

  • 您可以使用 IMEI 号码作为唯一标识符。这只是警告,因为现在黑客根手机并更改设备ID。
  • 恢复出厂后会有变化。我不想要那个。
  • 不,IMEI无论如何都不会改变。
  • 根据我的经验...总是最好生成唯一的服务器密钥,而不是依赖于应用程序(如果您正在使用它)
  • 看这里,可能对你有帮助:developer.android.com/training/articles/…

标签: android telephonymanager android-settings android-identifiers


【解决方案1】:

非常简单的答案是,如果您需要唯一标识应用的每个用户,请在首次使用时创建一个随机 id。

    UUID.randomUUID().toString()

您可以将其保存在SharedPreferences 中,简单的工作就完成了。无需权限

问题是如果用户卸载并重新安装应用程序,它不会帮助你。

在 android 10 之前可以做到的一个简单技巧(根据 google,在 android 11 上不再可能)是将其保存在外部存储中的隐藏文件中......

然后在第一次使用应用程序时查找此类文件,如果存在读取 UUID,则不生成新文件并保存文件。

这个策略的问题是你需要WRITE_EXTERNAL_STORAGEPERMISSION

万一这不是问题,简单做...

new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + ".my_hidden_folder").mkdir();

保存在此文件夹中的任何文件都将对用户隐藏,在卸载您的应用时不会被删除

我个人使用

Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);

这无害,只是谷歌不喜欢你这样做

【讨论】:

    【解决方案2】:

    这是在 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();
    }
    

    【讨论】:

      【解决方案3】:

      很久以前,我需要为每台设备设置一个持久的唯一 ID,但我遇到了同样的问题。 以下是我找到的解决方案:

      1. IMEI : 最差的解决方案:不带 SIM 卡的 Android 设备(例如许多平板电脑)被排除在外,您需要请求“拨打电话”权限才能获得它,这是没人愿意授予的。

      2. 设备序列号:良好的解决方案,独特的价值;但在 API 级别 26 中已弃用 和新方法needs permission in Android 10.

      3. SSID(又名 Android_ID):我认为尽管有警告,但这是一个很好的解决方案。无重复记录。

      一些半独特的解决方案包括:

      Build.FINGERPRINT :构建的唯一记录。没有警告。它将设备限制在更小的范围内。

      Build.TIME : 自生成设备 ROM 以来的时间(以毫秒为单位)。

      提示:混合硬件属性是行不通的,因为它们可能相似(工厂生产大量模型),并且为了获得唯一 ID,您可能需要权限。 p>

      提示 2:在设备内存中保存记录是浪费时间,因为总是可以更改/删除它们。

      【讨论】:

        【解决方案4】:

        你无法真正“解决”这个警告。

        但是,如果您愿意,可以通过添加 @SuppressLint("HardwareIds") 来禁用警告,这会解决这个问题。

        请注意,通过此警告,Lint 让您有机会重新考虑是否需要发布。

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-19
        • 1970-01-01
        • 2013-09-19
        • 2015-08-31
        • 2014-08-07
        相关资源
        最近更新 更多