是否有唯一的Android设备ID?
Android设备是否有唯一的ID,如果有,使用Java访问它的简单方法是什么?
Settings.Secure#ANDROID_ID
将Android ID作为每个用户的64位十六进制字符串的唯一返回值。
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
更新 :至于最近的Android版本, ANDROID_ID
许多问题已经解决,我相信这种方法不再必要。 请看看安东尼的回答。
完全公开:我的应用程序最初使用了下面的方法,但不再使用这种方法,现在我们使用Emmby的答案链接(即生成并保存UUID#randomUUID()
)的Android开发人员博客条目中概述的方法。
这个问题有很多答案,其中大部分只会在某些时候起作用,不幸的是这还不够好。
根据我对设备的测试(所有手机,至少其中一个未启动):
TelephonyManager.getDeviceId()
的值 TelephonyManager.getSimSerialNumber()
返回一个值 getSimSerialNumber()
返回null(如预期的那样) ANDROID_ID
的值 ANDROID_ID
和TelephonyManager.getDeviceId()
都返回相同的值(或派生相同的值TelephonyManager.getDeviceId()
- 只要在安装期间添加了Google帐户。 所以,如果你想要设备本身独有的东西, TM.getDeviceId()
应该足够了。 很显然,有些用户比其他用户更偏执,所以散列1个或多个这些标识符可能会很有用,这样字符串对于设备来说仍然是唯一的,但并不明确标识用户的实际设备。 例如,使用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;
最后更新:6/2/15
在阅读关于创建唯一ID,Google开发者博客和Android文档的每个Stack Overflow后,我觉得'Pseudo ID'是最好的选择。
主要问题:硬件vs软件
硬件
软件
使用Android进行全面细分
- 保证API => 9/10(99.5%的Android设备)的独特性(包括根植设备)
- 没有额外的权限
伪代码:
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发布我们所有的选项(在这个堆栈溢出问题)。
选项清单 - 为什么/为什么不使用它们的原因:
用户电子邮件 - 软件
<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,你真的只会遇到事实,即可能有重复的事实,有类似的设备。 你可以调整组合的方法,使其更独特; 然而,一些开发人员需要跟踪设备安装,这将基于类似的设备来实现技巧或性能。
API => 9:
如果他们的Android设备是API 9或以上版本,则由于“Build.SERIAL”字段,这保证是唯一的。
请记住 ,您在技术上只错过了大约0.5%API <9的用户。所以您可以专注于其余部分:这是99.5%的用户!
API <9:
如果用户的Android设备低于API 9; 希望他们没有重新设置工厂,他们的'Secure.ANDROID_ID'将被保留或不'空'。 (请参阅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服务的应用):
在Google Play开发者控制台中:
从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
我试图引用我从中获取信息的每一个环节。 如果您错过了并且需要收录,请评论!
Google Player服务实例ID
https://developers.google.com/instance-id/
链接地址: http://www.djcxy.com/p/617.html上一篇: Is there a unique Android device ID?
下一篇: How can I know which radio button is selected via jQuery?