【问题标题】:Android Unique Serial NumberAndroid 唯一序列号
【发布时间】:2013-04-11 06:59:40
【问题描述】:

我正在开发一个面向 Android 4.0 (API 14) 及更高版本的 Android 应用程序。

我正在寻找每个设备唯一且永久存在的序列号(随设备一起死掉,恢复出厂设置后不会更改)。

我在网上找到了很多关于 android 设备唯一标识符的结果,但关于 android.os.Build.SERIAL 编号的结果却很少。

到目前为止,我不再使用 ANDROID_ID,因为它可能会在恢复出厂设置后发生变化。我还取消了 IMEI 的使用,因为安卓设备可能不是手机。我无法使用 wifi 或蓝牙 MAC 地址,因为设备可能没有此类硬件和/或如果未启用硬件,则此类 MAC 地址可能无法读取(基于我在网上找到的内容) .

我相信我可能会去获取 android 设备序列号。

使用 android.os.Build.SERIAL 可以轻松访问(因为它是在 API 级别 9 中添加的,不需要任何额外的权限)。

我的问题是:

  • 考虑到我的应用程序面向 Android 4.0 (API 14) 及更高版本,Android 设备的 android.os.Build.SERIAL 编号是否对每个设备都是唯一的? p>

  • 目前,android.os.Build.SERIAL 的文档表明:硬件序列号(如果有)。仅限字母数字,不区分大小写。 这是否意味着序列号可能不可用?

  • 满足上述条件的另一种选择是什么?

【问题讨论】:

标签: android uniqueidentifier serial-number


【解决方案1】:

考虑到我的应用程序面向 Android 4.0 (API 14) 及更高版本,Android 设备的 android.os.Build.SERIAL 编号是否对每个设备都是唯一的?

根据 Android 开发者博客中这个有用的articleandroid.os.Build.SERIAL应该是唯一的(如果它可用)。 来自文章:

没有电话的设备需要在此处报告唯一的设备 ID;有些手机也可能这样做。

这是否意味着序列号可能不可用?

正确,它可能不可用。请注意,他们说“需要没有电话的设备...”,因此只有没有“电话”的设备(例如只有 wifi 的平板电脑)才需要提供SERIAL 号码,尽管有些手机仍然这样做(如 Nexus 4)。

关于这个主题肯定缺乏文档,但从措辞来看,可能只有“没有电话的设备”需要提交唯一 ID,而提交 ID 的手机可能不是唯一的。

满足上述条件的另一种选择是什么?

对于您的情况,我认为您最好的选择是首先检查deviceId(IMEI,或者不存在),如果deviceId 不存在,那么您回退到使用android.os.Build.SERIAL(因为这可能是平板电脑)像这样:

public static String getDeviceId(Context context) {
    final String deviceId = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
    if (deviceId != null) {
        return deviceId;
    } else {
        return android.os.Build.SERIAL;
    }
}

记住使用deviceId你需要android.permission.READ_PHONE_STATE的权限。

所以由于您的应用的 minSDK 是 14,您可以安全地使用字段android.os.Build.SERIAL。如果我们假设没有电话的设备确实总是在SERIAL 中提供唯一的 ID,那么我认为这将是一个安全的赌注,始终获得唯一的设备 ID(当然排除任何错误)。

【讨论】:

  • 那么,如果我将Build.SERIAL 用于非手机设备,将getDeviceId() 用于手机设备,您认为这将始终有效并始终提供唯一性吗?提前致谢。
  • @LuckyMe 如果一切正常,我认为这将是安全的。但当然也有错误,例如,getDeviceId() 的文章指出 错误:我们已经看到一些生产手机实例,其实现存在错误并返回垃圾,例如零或星号。 这还取决于您的最小 API,因为 Build.SERIAL 仅适用于 API 9 及更高版本。但是,如果您的情况与 OP 的情况相似,那么我认为您是安全的。但是你还是应该检查你的数据库,看看你是否收到了奇怪的设备标识符。
  • 我一直在使用 Build.SERIAL,认为它是独一无二的,但我们刚刚从中国的一家制造商那里收到了一批平板电脑/平板电脑 (API 15),并且在多台设备上的序列号相同(但不是全部)。这可能只是一个流氓制造商,但我建议你不要依赖这个系列是独一无二的!
  • ~"虽然有些手机仍然可以"。实际上,大多数手机都提供序列号。即使是低端的预付费电话也可以。可以通过android.os.Build.SERIAL查询序列号。
【解决方案2】:

我个人使用Secure.ANDROID_ID & Build.SERIAL 来识别手机:

androidId = Settings.Secure.getString(this.getContentResolver(), 
                Settings.Secure.ANDROID_ID) + Build.SERIAL;

他们可能有相同的ANDROID_ID,他们可能没有SERIAL。但两者的机会都很低。

【讨论】:

  • 似乎这是一个解决方案。我需要每个设备的一些静态唯一字符串发送到我的服务器 api 来注册用户。它的解决方案不需要任何插件权限。喜欢!
  • 问题是,如果用户恢复出厂设置,您使用Secure.ANDROID_ID 获得的值可能会发生变化,这意味着您的连接 ID 也会发生变化,即使它仍然是同一设备。
【解决方案3】:

你似乎已经很好地总结了情况。

序列号对于每台设备都是唯一的,但是(这是 Android)当然存在导致异常的错误,例如 https://code.google.com/p/android/issues/detail?id=35193

正如您所指出的,文档表明这是一个硬件序列号,但它的措辞表明您不应该指望它。并且不要将其误认为是设备的实际序列号,即印在背面或包装盒上的序列号。同样,我认为它的使用远没有 android_id 广泛使用,因此很可能存在未报告的问题。

我已经看到广泛报道 android_id 是基于序列号的,但我认为这不是真的 - 我最近观察到,在具有新的多用户功能的平板电脑上,每个用户帐户都有自己的android_id 但两者的序列号相同。

AFAIK“另一种选择”不存在:您的列表已完成。除非您准备依赖 wifi 或蓝牙权限,否则序列号是最接近您所追求的。

【讨论】:

  • 你说得对,android_id 不是基于序列号的。显然它只是基于随机数生成器。当他们最终修复许多设备具有相同 android_id 的错误时,请查看他们对代码所做的更改 here
  • 使用Settings.Secure.ANDROID_ID怎么样?那不是比序列号更可靠吗?
【解决方案4】:

我通常通过对一些唯一字符串(通常是公司名称)+ imei(如果没有 imei,mac 地址 [wifi、蓝牙等])进行 SHA1 哈希来获得唯一 ID。这给了我看起来相同的唯一 ID,每个设备往往是唯一的(如果 MAC 被更改/伪造,则不完美)。

【讨论】:

  • 小心点。据我所知,如果 wifi 关闭,某些设备似乎会为 MAC 返回 null,从而导致同一设备有两个 ID。
  • 自 Marshmallow 起不再报告 MAC 地址。你不应该使用那个值。
猜你喜欢
  • 1970-01-01
  • 2016-04-07
  • 1970-01-01
  • 1970-01-01
  • 2018-06-23
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多