Android设备有唯一的ID吗?如果有,使用Java访问它的简单方法是什么?


当前回答

1.使用提供唯一id(即IMEI)的电话管理器。参见示例,

import android.telephony.TelephonyManager;
import android.content.Context;
// ...
TelephonyManager telephonyManager;
telephonyManager = (TelephonyManager) getSystemService(Context.
                TELEPHONY_SERVICE);
/*
* getDeviceId() returns the unique device ID.
* For example,the IMEI for GSM and the MEID or ESN for CDMA phones.
*/
String deviceId = telephonyManager.getDeviceId();
/*
* getSubscriberId() returns the unique subscriber ID,
*/
String subscriberId = telephonyManager.getSubscriberId();

这需要为您的用户提供android.permission.READ_PHONE_STATE,这很难证明遵循您所做的应用程序类型。

没有电话服务的设备(如平板电脑)必须报告一个唯一的设备ID,该ID可以通过android.os.Build.SERIAL从android 2.3 Gingerbread获得。一些具有电话服务的电话还可以定义序列号。就像不是所有的Android设备都有序列号一样,这种解决方案并不可靠。在设备首次启动时,会生成并存储一个随机值。此值可通过Settings.Secure.ANDROID_ID获得。它是一个64位数字,在设备的生命周期内应保持不变。ANDROID_ID似乎是唯一设备标识符的好选择,因为它适用于智能手机和平板电脑。要检索值,可以使用以下代码:,StringandroidId=Settings.Secure.getString(getContentResolver(),Settings.Secure.ANDROID_ID);

但是,如果在设备上执行出厂重置,则该值可能会更改。制造商的流行手机也存在一个已知的缺陷,每个实例都有相同的ANDROID_ID。显然,该解决方案并非100%可靠。

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

SharedPreferences sharedPrefs = context.getSharedPreferences(
         PREF_UNIQUE_ID, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);

更新:选项#1和#2在android 10之后不再可用,因为谷歌进行了隐私更新。因为选项2和3需要关键许可。

其他回答

Settings.Secure#ANDROID_ID返回每个用户64位十六进制字符串的唯一ANDROID ID。

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID);

另请阅读唯一标识符的最佳实践:https://developer.android.com/training/articles/user-data-ids

以下代码使用隐藏的Android API返回设备序列号。但是,这个代码在三星Galaxy Tab上不起作用,因为这个设备上没有设置“ro.seriano”。

String serial = null;

try {
    Class<?> c = Class.forName("android.os.SystemProperties");
    Method get = c.getMethod("get", String.class);
    serial = (String) get.invoke(c, "ro.serialno");
}
catch (Exception ignored) {

}

谷歌现在有一个广告ID。这也可以使用,但请注意:

广告ID是用户特定的、唯一的、可重置的ID

and

使用户可以在Google Play应用程序中重置其标识符或选择退出基于兴趣的广告。

因此,尽管这个id可能会改变,但似乎很快我们就没有选择了,这取决于这个id的用途。

更多信息@develper.android

在此处复制粘贴代码

HTH

当设备没有电话功能时,我使用以下代码获取IMEI或使用Secure.ANDROID_ID作为替代:

String identifier = null;
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE));
if (tm != null)
      identifier = tm.getDeviceId();
if (identifier == null || identifier .length() == 0)
      identifier = Secure.getString(activity.getContentResolver(),Secure.ANDROID_ID);

Google实例ID

2015年I/O发布;在Android上需要播放服务7.5。

https://developers.google.com/instance-id/https://developers.google.com/instance-id/guides/android-implementation

InstanceID iid = InstanceID.getInstance( context );   // Google docs are wrong - this requires context
String id = iid.getId();  // blocking call

谷歌似乎打算使用这个ID来识别Android、Chrome和iOS的安装。

它标识的是安装而不是设备,但同样,ANDROID_ID(这是公认的答案)现在也不再标识设备。使用ARC运行时,会为每个安装生成一个新的ANDROID_ID(此处详细信息),就像这个新的实例ID一样。此外,我认为识别安装(而不是设备)是我们大多数人真正需要的。

实例ID的优点

在我看来,谷歌打算将其用于此目的(识别您的安装),它是跨平台的,可以用于许多其他目的(请参阅上面的链接)。

如果您使用GCM,那么您最终将需要使用此实例ID,因为您需要它来获取GCM令牌(它取代了旧的GCM注册ID)。

缺点/问题

在当前的实现(GPS 7.5)中,当应用程序请求实例ID时,会从服务器检索实例ID。这意味着上面的调用是一个阻塞调用-在我的非科学测试中,如果设备处于联机状态,则需要1-3秒,如果设备离线,则需要0.5-1.0秒(大概这是在放弃并生成随机ID之前等待的时间)。这是在北美使用Android 5.1.1和GPS 7.5在Nexus 5上测试的。

如果您将ID用于他们想要的目的,例如应用程序认证、应用程序识别、GCM,我认为这1-3秒可能会令人讨厌(当然,这取决于您的应用程序)。