数字联盟的可信计算联盟ID能做安卓设备唯一识别吗?

15453人阅读
android(45)
转自 http://blog.csdn.net/yansanjianke/article/details/7859966
& 唯一标识码这东西在网络应用中非常有用,例如检测是否重复注册之类的。
import android.provider.Settings.S&private String android_id = Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);&&&
import&android.provider.Settings.S&&private&String&android_id&=&Secure.getString(getContext().getContentResolver(),&Secure.ANDROID_ID);&&&&&
&& 我们在项目过程中或多或少会使用到设备的唯一识别码,我们希望能够得到一个稳定、可靠的设备唯一识别码。今天我们将介绍几种方式。
1. DEVICE_ID
假设我们确实需要用到真实设备的标识,可能就需要用到DEVICE_ID。在以前,我们的Android设备是手机,这个DEVICE_ID可以同通过TelephonyManager.getDeviceId()获取,它根据不同的手机设备返回IMEI,MEID或者ESN码,但它在使用的过程中会遇 到很多问题:
非手机设备: 如果只带有Wifi的设备或者音乐播放器没有通话的硬件功能的话就没有这个DEVICE_ID权限: 获取DEVICE_ID需要READ_PHONE_STATE权限,但如果我们只为了获取它,没有用到其他的通话功能,那这个权限有点大才小用bug:在少数的一些手机设备上,该实现有漏洞,会返回垃圾,如:zeros或者asterisks的产品
2. MAC ADDRESS
我们也可以通过手机的Wifi或者蓝牙设备获取MAC ADDRESS作为DEVICE ID,但是并不建议这么做,因为并不是所有的设备都有Wifi,并且,如果Wifi没有打开,那硬件设备无法返回MAC ADDRESS.
3. Serial Number
在Android 2.3可以通过android.os.Build.SERIAL获取,非手机设备可以通过该接口获取。
4. ANDROID_ID
ANDROID_ID是设备第一次启动时产生和存储的64bit的一个数,当设备被wipe后该数重置
ANDROID_ID似乎是获取Device ID的一个好选择,但它也有缺陷:
它在Android &=2.1 or Android &=2.3的版本是可靠、稳定的,但在2.2的版本并不是100%可靠的在主流厂商生产的设备上,有一个很经常的bug,就是每个设备都会产生相同的ANDROID_ID:e549c
5. Installtion ID : UUID
以上四种方式都有或多或少存在的一定的局限性或者bug,在这里,有另外一种方式解决,就是使用UUID,该方法无需访问设备的资源,也跟设备类型无关。
这 种方式是通过在程序安装后第一次运行后生成一个ID实现的,但该方式跟设备唯一标识不一样,它会因为不同的应用程序而产生不同的ID,而不是设备唯一ID。因此经常用来标识在某个应用中的唯一ID(即Installtion ID),或者跟踪应用的安装数量。很幸运的,Google& Developer Blog提供了这样的一个框架:
public class Installation {&&&& private static String sID =null;&
&&& private staticfinal String INSTALLATION =
&INSTALLATION&;&&&& public synchronizedstatic String id(Context context) {&
&&&&&&& if (sID == null) {&&&&&&&&&&&&&& File installation = new File(context.getFilesDir(), INSTALLATION);&&&&&&&&&&&& try {& &&&&&&&&&&&&&&& if (!installation.exists())&&&&&&&&&&&&&&&&&&&& writeInstallationFile(installation);& &&&&&&&&&&&&&&& sID = readInstallationFile(installation);& &&&&&&&&&&& } catch (Exception e) {&&&&&&&&&&&&&&&& throw new RuntimeException(e);&&&&&&&&&&&& }& &&&&&&& }& &&&&&&& return sID;& &&& }& &&& private static String readInstallationFile(File installation)throws IOException {&
&&&&&&& RandomAccessFile f = new RandomAccessFile(installation,&r&);&
&&&&&&& byte[] bytes = newbyte[(int) f.length()];&&&&&&&& f.readFully(bytes);& &&&&&&& f.close();& &&&&&&& return new String(bytes);&&&& }& &&& private staticvoid writeInstallationFile(File installation)throws IOException {&
&&&&&&& FileOutputStream out = new FileOutputStream(installation);&&&&&&&& String id = UUID.randomUUID().toString();& &&&&&&& out.write(id.getBytes());& &&&&&&& out.close();& &&& }& }&
public&class&Installation&{&&&&&&private&static&String&sID&=&null;&&&&&&private&static&final&String&INSTALLATION&=&&INSTALLATION&;&&&&&&public&synchronized&static&String&id(Context&context)&{&&&&&&&&&&if&(sID&==&null)&{&&&&&&&&&&&&&&&&File&installation&=&new&File(context.getFilesDir(),&INSTALLATION);&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&if&(!installation.exists())&&&&&&&&&&&&&&&&&&&&&&writeInstallationFile(installation);&&&&&&&&&&&&&&&&&&sID&=&readInstallationFile(installation);&&&&&&&&&&&&&&}&catch&(Exception&e)&{&&&&&&&&&&&&&&&&&&throw&new&RuntimeException(e);&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&&&&&return&sID;&&&&&&}&&&&&&private&static&String&readInstallationFile(File&installation)&throws&IOException&{&&&&&&&&&&RandomAccessFile&f&=&new&RandomAccessFile(installation,&&r&);&&&&&&&&&&byte[]&bytes&=&new&byte[(int)&f.length()];&&&&&&&&&&f.readFully(bytes);&&&&&&&&&&f.close();&&&&&&&&&&return&new&String(bytes);&&&&&&}&&&&&&private&static&void&writeInstallationFile(File&installation)&throws&IOException&{&&&&&&&&&&FileOutputStream&out&=&new&FileOutputStream(installation);&&&&&&&&&&String&id&=&UUID.randomUUID().toString();&&&&&&&&&&out.write(id.getBytes());&&&&&&&&&&out.close();&&&&&&}&&}&&
综 合以上所述,为了实现在设备上更通用的获取设备唯一标识,我们可以实现这样的一个类,为每个设备产生唯一的UUID,以ANDROID_ID为基础,在获 取失败时以TelephonyManager.getDeviceId()为备选方法,如果再失败,使用UUID的生成策略。
重申下,以下方法是生成Device ID,在大多数情况下Installtion ID能够满足我们的需求,但是如果确实需要用到Device ID,那可以通过以下方式实现:
import android.content.C&
import android.content.SharedP&import android.provider.Settings.S&import android.telephony.TelephonyM&import java.io.UnsupportedEncodingE&import java.util.UUID;& public class DeviceUuidFactory {&&&& protected staticfinal String PREFS_FILE =
&device_id.xml&;&&&& protected staticfinal String PREFS_DEVICE_ID =
&device_id&;&&&& protected static UUID&& &&& public DeviceUuidFactory(Context context) {&&&&&&&& if( uuid ==null ) {&&&&&&&&&&&& synchronized (DeviceUuidFactory.class) {&&&&&&&&&&&&&&&& if( uuid == null) {&&&&&&&&&&&&&&&&&&&& final SharedPreferences prefs = context.getSharedPreferences( PREFS_FILE,0);&
&&&&&&&&&&&&&&&&&&& final String id = prefs.getString(PREFS_DEVICE_ID,null );&
&&&&&&&&&&&&&&&&&&& if (id !=
null) {& &&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&& uuid = UUID.fromString(id);& &&&&&&&&&&&&&&&&&&& } else {&
&&&&&&&&&&&&&&&&&&&&&&& final String androidId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&& try {&
&&&&&&&&&&&&&&&&&&&&&&&&&&& if (!&e549c&.equals(androidId)) {&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& uuid = UUID.nameUUIDFromBytes(androidId.getBytes(&utf8&));&&&&&&&&&&&&&&&&&&&&&&&&&&&& } else {&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& uuid = deviceId!=null ? UUID.nameUUIDFromBytes(deviceId.getBytes(&utf8&)) : UUID.randomUUID();&&&&&&&&&&&&&&&&&&&&&&&&&&&& }& &&&&&&&&&&&&&&&&&&&&&&& } catch (UnsupportedEncodingException e) {&&&&&&&&&&&&&&&&&&&&&&&&&&&& throw
new RuntimeException(e);& &&&&&&&&&&&&&&&&&&&&&&& }& &&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&& prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).commit();&&&&&&&&&&&&&&&&&&&& }& &&&&&&&&&&&&&&& }& &&&&&&&&&&& }& &&&&&&& }& &&& }& & &&&
& &&& public UUID getDeviceUuid() {&
&&&&&&& return& &&& }& }&
import&android.content.C&&import&android.content.SharedP&&import&android.provider.Settings.S&&import&android.telephony.TelephonyM&&import&java.io.UnsupportedEncodingE&&import&java.util.UUID;&&public&class&DeviceUuidFactory&{&&&&&&protected&static&final&String&PREFS_FILE&=&&device_id.xml&;&&&&&&protected&static&final&String&PREFS_DEVICE_ID&=&&device_id&;&&&&&&protected&static&UUID&&&&&&&&&public&DeviceUuidFactory(Context&context)&{&&&&&&&&&&if(&uuid&==null&)&{&&&&&&&&&&&&&&synchronized&(DeviceUuidFactory.class)&{&&&&&&&&&&&&&&&&&&if(&uuid&==&null)&{&&&&&&&&&&&&&&&&&&&&&&final&SharedPreferences&prefs&=&context.getSharedPreferences(&PREFS_FILE,&0);&&&&&&&&&&&&&&&&&&&&&&final&String&id&=&prefs.getString(PREFS_DEVICE_ID,&null&);&&&&&&&&&&&&&&&&&&&&&&if&(id&!=&null)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&uuid&=&UUID.fromString(id);&&&&&&&&&&&&&&&&&&&&&&}&else&{&&&&&&&&&&&&&&&&&&&&&&&&&&final&String&androidId&=&Secure.getString(context.getContentResolver(),&Secure.ANDROID_ID);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(!&e549c&.equals(androidId))&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&uuid&=&UUID.nameUUIDFromBytes(androidId.getBytes(&utf8&));&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&else&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&final&String&deviceId&=&((TelephonyManager)&context.getSystemService(&Context.TELEPHONY_SERVICE&)).getDeviceId();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&uuid&=&deviceId!=null&?&UUID.nameUUIDFromBytes(deviceId.getBytes(&utf8&))&:&UUID.randomUUID();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&}&catch&(UnsupportedEncodingException&e)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&throw&new&RuntimeException(e);&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&prefs.edit().putString(PREFS_DEVICE_ID,&uuid.toString()&).commit();&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&public&UUID&getDeviceUuid()&{&&&&&&&&&&return&&&&&&&}&&}&&
如何获取Android手机的唯一标识?
代码: 这里是你在Android里读出 唯一的 IMSI-ID / IMEI-ID 的方法。
String myIMSI = android.os.SystemProperties.get(android.telephony.TelephonyProperties.PROPERTY_IMSI);&&&
& String myIMEI = android.os.SystemProperties.get(android.telephony.TelephonyProperties.PROPERTY_IMEI);&&&
String&myIMSI&=&android.os.SystemProperties.get(android.telephony.TelephonyProperties.PROPERTY_IMSI);&&&&&&&String&myIMEI&=&android.os.SystemProperties.get(android.telephony.TelephonyProperties.PROPERTY_IMEI);&&&&&
注:android.os.SystemProperties的标签被打上@hide了,所以sdk中并不会存在。如果需要使用,需要有android的source code支持。
转自:/weizi/item/f1de68d88a95638
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:372305次
积分:3773
积分:3773
排名:第7898名
原创:27篇
转载:165篇
评论:29条获取Android设备唯一的ID - 简书
获取Android设备唯一的ID
(1)DEVICE_IDAndroid系统为开发者提供的用于标识手机设备的串号
TelephoneManager tm=TelephoneManager.getSystemService(Context.TELEPHONE_SERVICE);
tm.getDeviceId();
缺陷:(1)非手机设备(2)权限问题
(2)ANDROID_ID在设备首次启动时,系统会随机生成一个64位的数字,并把这个数字以16进制字符串的形式保存下来,这个16进制的字符串就是ANDROID_ID
String ANDROID_ID=Setting.System.getString(getContentResolver(),Setting.System.ANDROID_ID);
缺陷:(1)厂商Bug:不同的设备可能会产生相同的ANDROID_ID(2)厂商Bug:有些设备返回的值为null
(3)Serial NumberAndroid系统2.3版本以上可以通过下面的方法得到Serial Number,且非手机设备也可以通过该接口获取。
String serial=Andorid.os.Build.SERIAL;1668人阅读
android(2)
有很多场景和需求你需要用到手机设备的唯一标识符。
在Android中,有以下几种方法获取这样的ID。
The IMEI: 仅仅只对Android手机有效:
public String getIMEI() {
TelephonyManager TelephonyMgr = (TelephonyManager) mContext.getSystemService(TELEPHONY_SERVICE);
String szImei = TelephonyMgr.getDeviceId();
return szI
采用此种方法,需要在AndroidManifest.xml中加入一个许可:android.permission.READ_PHONE_STATE,并且用户应当允许安装此应用。作为手机来讲,IMEI是唯一的,它应该类似于 356(除非你有一个没有量产的手机(水货)它可能有无效的IMEI,如:0)。
Pseudo-Unique ID, 这个在任何Android手机中都有效
有一些特殊的情况,一些如平板电脑的设置没有通话功能,或者你不愿加入READ_PHONE_STATE许可。而你仍然想获得唯一序列号之类的东西。这时你可以通过取出ROM版本、制造商、CPU型号、以及其他硬件信息来实现这一点。这样计算出来的ID不是唯一的(因为如果两个手机应用了同样的硬件以及Rom 镜像)。但应当明白的是,出现类似情况的可能性基本可以忽略。要实现这一点,你可以使用Build类:
public String getPesudoUniqueID() {
String m_szDevIDShort = “35” + //we make this look like a valid IMEI
Build.BOARD.length() % 10 +
Build.BRAND.length() % 10 +
Build.CPU_ABI.length() % 10 +
Build.DEVICE.length() % 10 +
Build.DISPLAY.length() % 10 +
Build.HOST.length() % 10 +
Build.ID.length() % 10 +
Build.MANUFACTURER.length() % 10 +
Build.MODEL.length() % 10 +
Build.PRODUCT.length() % 10 +
Build.TAGS.length() % 10 +
Build.TYPE.length() % 10 +
Build.USER.length() % 10; //13 digits
return m_szDevIDS
大多数的Build成员都是字符串形式的,我们只取他们的长度信息。我们取到13个数字,并在前面加上“35”。这样这个ID看起来就和15位IMEI一样了。
The Android ID
通常被认为不可信,因为它有时为null。开发文档中说明了:这个ID会改变如果进行了出厂设置。并且,如果某个Andorid手机被Root过的话,这个ID也可以被任意改变。
public String getAndroidID() {
String m_szAndroidID = Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.ANDROID_ID);
return m_szAndroidID;
Returns: e549c . 无需任何许可。
The WLAN MAC Address string
是另一个唯一ID。但是你需要为你的工程加入android.permission.ACCESS_WIFI_STATE 权限,否则这个地址会为null。
public String getWLANMACAddress() {
WifiManager wm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
return m_szWLANMAC;
Returns: 00:11:22:33:44:55 (这不是一个真实的地址。而且这个地址能轻易地被伪造。).WLan不必打开,就可读取些值。
The BT MAC Address string
只在有蓝牙的设备上运行。并且要加入
public String getBTMACAddress() {
BluetoothAdapter m_BluetoothAdapter = // Local Bluetooth adapter
m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_szBTMAC = m_BluetoothAdapter.getAddress();
return m_szBTMAC;
Returns: 43:25:78:50:93:38 . 蓝牙没有必要打开,也能读取。
Combined Device ID
综上所述,我们一共有五种方式取得设备的唯一标识。它们中的一些可能会返回null,或者由于硬件缺失、权限问题等获取失败。
但你总能获得至少一个能用。所以,最好的方法就是通过拼接,或者拼接后的计算出的MD5值来产生一个结果。
public String getUniqueID() {
String m_szLongID = getIMEI() + getPesudoUniqueID()
+ getAndroidID() + getWLANMACAddress() + getBTMACAddress();
String m_szLongID = getPesudoUniqueID() + getWLANMACAddress() + getBTMACAddress();
// compute md5
MessageDigest m =
m = MessageDigest.getInstance(“MD5”);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
m.update(m_szLongID.getBytes(), 0, m_szLongID.length());
// get md5 bytes
byte p_md5Data[] = m.digest();
// create a hex string
String m_szUniqueID = new String();
for (int i = 0; i & p_md5Data. i++) {
int b = (0xFF & p_md5Data[i]);
// if it is a single digit, make sure it have 0 in front (proper padding)
if (b &= 0xF)
m_szUniqueID += “0”;
// add number to string
m_szUniqueID += Integer.toHexString(b);
// hex string to uppercase
m_szUniqueID = m_szUniqueID.toUpperCase();
return m_szUniqueID;
通过以上算法,可产生32位的16进制数据:
9DDDF85AFF0A8BD94D5F55
现在你就可以对其进行你的应用了。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3015次
排名:千里之外如果你是该公司的创始人、项目/产品经理等,欢迎认领公司主页,以享有更多编辑管理权限。
真实姓名 *
请尽量使用企业邮箱
手机号码 *
个人名片 *
请上传真实有效的个人名片,名片上的公司名称应该与所认领的公司名称保持一致;请确保你是该公司的创始人或者其他相关在职成员;请勿上传其他不相关的证件,以免影响审核通过率;上传图片支持2M以内的PNG、JPG、GIF格式。
内容责任声明: 用户作为内容的发表或采集者,需自行对所发表或采集的内容负责,因所发表或采集的内容引发的一切纠纷、损失,由该内容的发表或采集者承担全部直接或间接(连带)法律责任,IT桔子不承担任何法律责任。
Slogan:请用一句话描述产品方向和公司主要业务。(15字以内)
完善微博等企业账号,方便投资人、创业者更全面地了解公司。
内容责任声明: 用户作为内容的发表或采集者,需自行对所发表或采集的内容负责,因所发表或采集的内容引发的一切纠纷、损失,由该内容的发表或采集者承担全部直接或间接(连带)法律责任,IT桔子不承担任何法律责任。
(公司TAG部分暂不开放用户编辑。)
下载IT桔子客户端App
互联网创投信息一手掌握
,更新 里程碑
,更新 基础信息
北京数字联盟网络科技有限公司,提供安卓设备可信ID服务。
通过使用数字联盟的可信ID服务,可有效的应对推广中渠道造假,刷单,数据不准确的情况。
北京数字联盟网络科技有限公司,是国内唯一的安卓商用ID服务提供商。
公司全称:北京数字联盟网络科技有限公司
成立时间:2014.5 &&
公司规模:30-50人
上传公司截图
北京数字联盟网络科技有限公司,提供安卓设备可信ID服务。
通过使用数字联盟的可信ID服务,可有效的应对推广中渠道造假,刷单,数据不准确的情况。
北京数字联盟网络科技有限公司,是国内唯一的安卓商用ID服务提供商。
请以客观中立地语言描述产品和公司主营业务。(150字以内)
工商注册全称
500-1000人
2000人以上
内容责任声明: 用户作为内容的发表或采集者,需自行对所发表或采集的内容负责,因所发表或采集的内容引发的一切纠纷、损失,由该内容的发表或采集者承担全部直接或间接(连带)法律责任,IT桔子不承担任何法律责任。
投资方未透露
企业服务行业热度图
孙未然,北京固爱普网络联合创始人,数盟科技联合创始人及CEO。
杨从安,数盟网络创始人,北京固爱普网络创始人,连续创业者。
未收录相关信息
法定代表人
工商变更信息
数据来源 权大师

我要回帖

更多关于 中关村可信联盟 的文章

 

随机推荐