每个设备的Secure.ANDROID_ID是否唯一?


80

我正在使用此电话:

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

获取设备的UID。我想我从多个设备上获得了相同的ID。应该可以吗?

有问题的ID为:9774d56d682e549c,显然有多个设备返回此ID http://code.google.com/p/android/issues/list?cursor=10603&updated=10603&ts=1295993403


查找有问题的ID并看到有关它的线程后,我确定。起初,我认为设备可能返回null,并将其作为默认值放置在某处。但这种情况并非如此。我肯定可以在多个设备上获得相同的价值。
FoamyGuy 2011年


对于不唯一的情况,请使用随附的此库Identity.getDeviceId(context)
caw

Answers:


47

签入此线程,。但是,您应小心,因为它记录为“可以在恢复出厂设置时更改”。使用时需要您自担风险,并且可以轻松地在有根电话上对其进行更改。同样,似乎有些制造商的手机有重复编号的线出现问题。根据您的尝试,我可能不会将其用作UID。


19
真可惜,ANDROID_ID的实现是如此... me脚!从Google的文档来看,其意图是使用更长的ID: A 64-bit number (as a hex string) that is randomly generated on the device's first boot and should remain constant for the lifetime of the device
某处某人

3
根据该线程 链接, “而且,在一家主要制造商的流行手机中,至少有一个被广泛观察到的错误,其中每个实例都具有相同的ANDROID_ID。” 最好不要使用它
穆罕默德Riyaz

2
那是从2011年Froyo比赛开始的。现在无关紧要了。
奥巴汀萨迈

设备备份/还原或设备克隆怎么办?对拥有相同ANDROID_ID的机会有任何想法吗?假设设备没有植根。
FunkSoulBrother

37

使用Android O时,ANDROID_ID的行为将发生变化。手机上每个用户的每个应用的ANDROID_ID都不同。

摘自:https : //android-developers.googleblog.com/2017/04/changes-to-device-identifiers-in.html

Android ID

在O中,对于每个应用和设备上的每个用户,Android ID(Settings.Secure.ANDROID_ID或SSAID)具有不同的值。需要设备范围标识符的开发人员应改用可重置的标识符,例如广告ID,以使用户拥有更多控制权。广告ID还提供了面向用户的设置,以限制广告跟踪。

此外,在Android O中:

  • 只要软件包名称和签名密钥相同,ANDROID_ID值在软件包卸载/重新安装时不会更改。应用程序可以依靠此值来维护重新安装的状态。
  • 如果将应用程序安装在运行早期版本Android的设备上,则将设备更新到Android O时,Android ID保持不变,除非已卸载并重新安装了该应用程序。
  • 仅当设备恢复出厂设置或签名密钥在卸载和
    重新安装事件之间旋转时,Android ID值才会更改。
  • 只有使用Google Play服务和广告ID发货的设备制造商才需要进行此更改。其他设备制造商可能会提供替代的可重置ID或继续提供ANDROID ID。

谢谢。我正在竭尽全力试图弄清楚为什么我没有使用Device ID报告的(md5'ed)ID在妻子的电话中获得测试广告,然后为什么这与通过adb shell settings命令报告的值不匹配。 ..我以为我快疯了。
ecv

15

所以,如果你想要独一无二的设备本身的东西,TM.getDeviceId() 应该是足够的。

这是显示如何获取电话管理器ID的代码。您正在使用的android设备ID可以在出厂设置上更改,而且某些制造商在提供唯一ID时也存在问题。

TelephonyManager tm = 
        (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
String androidId = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID);
Log.d("ID", "Android ID: " + androidId);
Log.d("ID", "Device ID : " + tm.getDeviceId());

确保TelephonyManager通过使用获得许可

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

3
是的,使用getDeviceId()也可以。但是您应该非常小心,因为它可能会返回null。(在没有3g /电话调制解调器的设备上)我使用的解决方案是使用Wifi的mac地址(当然也可能会丢失,但通常不在同一设备上)
vdstw 2012年

19
要求READ_PHONE_STATE许可是可怕的。使用ANDROID_ID代替。
2012年

是的,在没有3g设备(市场上有很多)上,它可能会返回null,那么您应该使用WiFi-它的guid也可能为null,直到在设备重启后至少打开/关闭它一次为止。而且,如果没有wifi ...真正的噩梦,则在Windows CE上,每个设备都有GUID,生活是美好的。
marcinj 2012年

事实证明,在成千上万次请求之后,可以在假设备上复制Device ID(即IMEI),因此不是一个完整的解决方案。我将恢复使用getSimSerialNumber和ANDROID_ID作为后备。
Ajibola

6

我已经阅读了一些有关此内容的信息,不幸的是,不应依赖ANDROID_ID来唯一标识单个设备。

它似乎并没有在Android合规性要求中得到强制执行,因此制造商似乎以他们选择的方式来实现它,包括一些人更多地将其用作“模型” ID等。

另外,请注意,即使制造商编写了生成器以使其成为UUID(例如),也不能保证它会恢复出厂设置。


6
我认为这将保证不会因设计而恢复出厂设置,这在文档中已提到。这是实现它的正确方法。
紫罗兰色长颈鹿

那么我们如何生成GUID?
IgorGanapolsky

6

存在多种解决方案,但都不完美。我们一个接一个地走。

1. Unique Telephony Number (IMEI, MEID, ESN, IMSI)

  • 此解决方案需要向您的用户请求 android.permission.READ_PHONE_STATE,这可能很难根据您所创建的应用程序的类型来证明。

  • 此外,此解决方案仅限于智能手机,因为平板电脑没有电话服务。优点之一是该值可以保留到设备上的出厂重置状态。

2. MAC Address

  • 您也可以尝试从具有Wi-Fi或蓝牙硬件的设备上获取MAC地址。但是,不建议使用此解决方案,因为并非所有设备都具有Wi-Fi连接。即使用户具有Wi-Fi连接,也必须将其打开才能检索数据。否则,该呼叫不会报告MAC地址。

3. Serial Number

  • 自Android 2.3 Gingerbread以来,没有电话服务的设备(例如平板电脑)必须报告一个唯一的设备ID,该ID可通过android.os.Build.SERIAL获得。某些具有电话服务的电话也可以定义序列号。就像并非所有的Android设备都有序列号一样,此解决方案也不可靠。

4. Secure Android ID

  • 在设备首次启动时,将生成并存储一个随机值。可通过Settings.Secure.ANDROID_ID使用此值。这是一个64位数字,应在设备的整个使用寿命内保持不变。对于唯一的设备标识符,ANDROID_ID似乎是一个不错的选择,因为它可用于智能手机和平板电脑。

    String androidId = Settings.Secure.getString(getContentResolver(),Settings.Secure.ANDROID_ID);
    
  • 但是,如果在设备上执行了出厂重置,则该值可能会更改。制造商的流行手机也存在一个已知错误,其中每个实例都具有相同的ANDROID_ID。显然,该解决方案不是100%可靠的。

5. Use UUID

  • 由于大多数应用程序的需求是标识特定的安装而不是物理设备,因此,如果使用UUID类,则为用户获取唯一ID的一个很好的解决方案。Google的Reto Meier在Google I / O演示中提出了以下解决方案:

    private static String uniqueID = null;
    private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";
    public synchronized static String id(Context context) {
       if (uniqueID == null) {
           SharedPreferences sharedPrefs = context.getSharedPreferences(
                   PREF_UNIQUE_ID, Context.MODE_PRIVATE);
           uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
           if (uniqueID == null) {
               uniqueID = UUID.randomUUID().toString();
               Editor editor = sharedPrefs.edit();
               editor.putString(PREF_UNIQUE_ID, uniqueID);
               editor.commit();
           }
       }    return uniqueID;
    }
    

识别Android上的特定设备并非易事。有很多很好的理由可以避免这种情况。最佳解决方案可能是使用UUID解决方案来识别特定的安装。信用:博客


1

只需在此处列出替代解决方案,即广告ID:

https://support.google.com/googleplay/android-developer/answer/6048248?hl=en

从上面的链接复制:

广告ID是由Google Play服务提供的用户可重置的唯一ID。它为用户提供了更好的控件,并为开发人员提供了一个简单的标准系统,以继续通过其应用获利。它使用户可以重置其标识符或选择退出Google Play应用中的个性化广告(以前称为基于兴趣的广告)。

限制是:

  1. 仅支持Google Play的设备。
  2. 隐私政策: https://support.google.com/googleplay/android-developer/answer/113469?hl=en&rd=1#privacy

这对没有Google Play(服务)的手机有效吗?
马克斯·沃特曼

这不是GUID
IgorGanapolsky

0
//Fields
String myID;
int myversion = 0;


myversion = Integer.valueOf(android.os.Build.VERSION.SDK);
if (myversion < 23) {
        TelephonyManager mngr = (TelephonyManager) 
getSystemService(Context.TELEPHONY_SERVICE);
        myID= mngr.getDeviceId();
    }
    else
    {
        myID = 
Settings.Secure.getString(getApplicationContext().getContentResolver(), 
Settings.Secure.ANDROID_ID);
    }

是的,Secure.ANDROID_ID对于每个设备都是唯一的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.