Settings.Secure#ANDROID_ID
返回 Android ID 作为每个用户 64 位十六进制字符串的唯一 ID。
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
更新 :截至 Android 的最新版本, ANDROID_ID
许多问题已得到解决,我相信不再需要这种方法。请看看安东尼的回答 。
完全披露:我的应用程序最初使用了以下方法但不再使用此方法,我们现在使用Android 开发人员博客条目中概述的方法,即emmby 的答案链接(即生成并保存UUID#randomUUID()
)。
这个问题有很多答案,其中大部分只会在某些时候起作用,不幸的是,这还不够好。
基于我对设备的测试(所有电话,其中至少有一部分未激活):
TelephonyManager.getDeviceId()
的值TelephonyManager.getSimSerialNumber()
的值getSimSerialNumber()
返回 null(如预期的那样) ANDROID_ID
的值ANDROID_ID
和TelephonyManager.getDeviceId()
返回相同的值(或相同值的推导)。 所以,如果你想要独一无二的设备本身,一些TM.getDeviceId()
应该足够了。显然有些用户比其他用户更偏执,因此对这些标识符中的一个或多个进行散列可能很有用,这样该字符串对于设备来说实际上仍然是唯一的,但是没有明确标识用户的实际设备。例如,使用String.hashCode()
,结合 UUID:
final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();
可能会导致类似于: 00000000-54b3-e7c7-0000-000046bffd97
它对我来说效果很好。
正如 Richard 在下面提到的那样,不要忘记您需要获得读取TelephonyManager
属性的权限,因此请将其添加到清单中:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
导入库
import android.content.Context;
import android.telephony.TelephonyManager;
import android.view.View;
在阅读关于创建唯一 ID,Google 开发人员博客和 Android 文档的每篇 Stack Overflow 帖子后,我觉得好像'Pseudo ID' 是最好的选择。
Psuedo 代码:
if API >= 9/10: (99.5% of devices)
return unique ID containing serial id (rooted devices may be different)
else
return unique ID of build information (may overlap data - API < 9)
感谢 @stansult 发布我们的所有选项 (在此 Stack Overflow 问题中)。
用户电子邮件 - 软件
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
或<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
( 如何获取 Android 设备的主要电子邮件地址 ) 用户电话号码 - 软件
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
IMEI - 硬件 (只有手机,需要android.permission.READ_PHONE_STATE
)
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Android ID - 硬件 (可以为 null,可以在出厂重置时更改,可以在有根设备上更改)
WLAN MAC 地址 - 硬件 (需要android.permission.ACCESS_WIFI_STATE
)
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE "/>
蓝牙 MAC 地址 - 硬件 (带蓝牙的设备,需要android.permission.BLUETOOTH
)
<uses-permission android:name="android.permission.BLUETOOTH "/>
伪唯一 ID - 软件 (适用于所有 Android 设备)
我知道没有任何 “完美” 的方法可以在不使用权限的情况下获取唯一 ID; 但是,有时我们只需要跟踪设备安装。在创建唯一 ID 时,我们可以根据 Android API 提供的信息创建 “伪唯一 ID”,而无需使用额外的权限。通过这种方式,我们可以向用户展示尊重并尝试提供良好的用户体验。
使用伪唯一 ID,您实际上只会遇到基于类似设备这一事实可能存在重复的事实。您可以调整组合方法,使其更加独特; 但是,一些开发人员需要跟踪设备安装,这将基于类似设备执行技巧或性能。
如果他们的 Android 设备是 API 9 或更高版本,由于 “Build.SERIAL” 字段,这保证是唯一的。
请记住 ,从技术上讲,只有 0.5%的API <9的用户错过了。所以你可以专注于其余的:这是 99.5%的用户!
如果用户的 Android 设备低于 API 9; 希望他们没有完成工厂重置,他们的'Secure.ANDROID_ID' 将被保留或不是'null'。 (见http://developer.android.com/about/dashboards/index.html )
如果所有其他方法都失败了,如果用户确实低于 API 9(低于 Gingerbread),重置了他们的设备或'Secure.ANDROID_ID' 返回'null',那么返回的 ID 将完全基于他们的 Android 设备信息。这是碰撞可能发生的地方。
变化:
请看下面的方法:
/**
* Return pseudo unique ID
* @return ID
*/
public static String getUniquePsuedoID() {
// If all else fails, if the user does have lower than API 9 (lower
// than Gingerbread), has reset their device or 'Secure.ANDROID_ID'
// returns 'null', then simply the ID returned will be solely based
// off their Android device information. This is where the collisions
// can happen.
// Thanks http://www.pocketmagic.net/?p=1662!
// Try not to use DISPLAY, HOST or ID - these items could change.
// If there are collisions, there will be overlapping data
String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);
// Thanks to @Roman SL!
// https://stackoverflow.com/a/4789483/950427
// Only devices with API >= 9 have android.os.Build.SERIAL
// http://developer.android.com/reference/android/os/Build.html#SERIAL
// If a user upgrades software or roots their device, there will be a duplicate entry
String serial = null;
try {
serial = android.os.Build.class.getField("SERIAL").get(null).toString();
// Go ahead and return the serial for api => 9
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
} catch (Exception exception) {
// String needs to be initialized
serial = "serial"; // some value
}
// Thanks @Joe!
// https://stackoverflow.com/a/2853253/950427
// Finally, combine the values we have found by using the UUID class to create a unique identifier
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
来自 Google Play Developer 的控制台:
从 2014 年 8 月 1 日开始,Google Play 开发者计划政策要求所有新的应用上传和更新都使用广告 ID 代替任何其他持久性标识符,以用于任何广告目的。学到更多
实施 :
允许:
<uses-permission android:name="android.permission.INTERNET" />
码:
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
import com.google.android.gms.common.GooglePlayServicesAvailabilityException;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import java.io.IOException;
...
// Do not call this function from the main thread. Otherwise,
// an IllegalStateException will be thrown.
public void getIdThread() {
Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
} catch (IOException exception) {
// Unrecoverable error connecting to Google Play services (e.g.,
// the old version of the service doesn't support getting AdvertisingId).
} catch (GooglePlayServicesAvailabilityException exception) {
// Encountered a recoverable error connecting to Google Play services.
} catch (GooglePlayServicesNotAvailableException exception) {
// Google Play services is not available entirely.
}
final String id = adInfo.getId();
final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
}
来源 / 文档:
http://developer.android.com/google/play-services/id.html http://developer.android.com/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html
当 Google Play 服务可用时,广告 ID 旨在完全取代其他标识符的现有使用,以用于广告目的(例如在 Settings.Secure 中使用 ANDROID_ID)。 Google Play 服务不可用的情况由 getAdvertisingIdInfo()引发的 GooglePlayServicesNotAvailableException 指示。
http://en.kioskea.net/faq/34732-android-reset-your-advertising-id
我试图引用我从中获取信息的每个链接。如果您遗失并需要加入,请发表评论!