Android获取设备唯一ID的几种方式

来源:互联网 发布:完美红颜进阶数据 编辑:程序博客网 时间:2024/06/09 16:14

转至http://blog.csdn.net/u014651216/article/details/50767326

 IMEI

方式:TelephonyManager.getDeviceId():

问题

范围:只能支持拥有通话功能的设备,对于平板不可以。

持久性:返厂,数据擦除的时候不彻底,保留了原来的标识。

权限:需要权限:Android.permission.READ_PHONE_STATE

bug: 有些厂家的实现有bug,返回一些不可用的数据


 Mac地址

ACCESS_WIFI_STATE权限

有些设备没有WiFi,或者蓝牙,就不可以,如果WiFi没有打开,硬件也不会返回Mac地址,不建议使用


ANDROID_ID

2.2(Froyo,8)版本系统会不可信,来自主要生产厂商的主流手机,至少有一个普遍发现的bug,这些有问题的手机相同的ANDROID_ID: 9774d56d682e549c

但是如果返厂的手机,或者被root的手机,可能会变

 
 Serial Number

从Android 2.3 (“Gingerbread”)开始可用,可以通过android.os.Build.SERIAL获取,对于没有通话功能的设备,它会

返回一个唯一的device ID,


以下几个是stackoverflow上评论较多的几个,没贴完,还有其他,综合的,用到以上的部分方式:

地址:http://stackoverflow.com/questions/2785485/is-there-a-unique-android-device-id

google官方的相关博客:http://android-developers.blogspot.com/2011/03/identifying-app-installations.html

有兴趣的朋友可以再仔细看看


支持率比较高的(支持票数157):androidID --> 剔除2.2版本(API 8)中有问题的手机,使用UUID替代 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. import android.content.Context;  
  2. import android.content.SharedPreferences;  
  3. import android.provider.Settings.Secure;  
  4. import android.telephony.TelephonyManager;  
  5.   
  6. import java.io.UnsupportedEncodingException;  
  7. import java.util.UUID;  
  8.   
  9. public class DeviceUuidFactory {  
  10.   
  11.     protected static final String PREFS_FILE = "device_id.xml";  
  12.     protected static final String PREFS_DEVICE_ID = "device_id";  
  13.     protected static volatile UUID uuid;  
  14.   
  15.     public DeviceUuidFactory(Context context) {  
  16.         if (uuid == null) {  
  17.             synchronized (DeviceUuidFactory.class) {  
  18.                 if (uuid == null) {  
  19.                     final SharedPreferences prefs = context  
  20.                             .getSharedPreferences(PREFS_FILE, 0);  
  21.                     final String id = prefs.getString(PREFS_DEVICE_ID, null);  
  22.                     if (id != null) {  
  23.                         // Use the ids previously computed and stored in the  
  24.                         // prefs file  
  25.                         uuid = UUID.fromString(id);  
  26.                     } else {  
  27.                         final String androidId = Secure.getString(  
  28.                             context.getContentResolver(), Secure.ANDROID_ID);  
  29.                         // Use the Android ID unless it's broken, in which case  
  30.                         // fallback on deviceId,  
  31.                         // unless it's not available, then fallback on a random  
  32.                         // number which we store to a prefs file  
  33.                         try {  
  34.                             if (!"9774d56d682e549c".equals(androidId)) {  
  35.                                 uuid = UUID.nameUUIDFromBytes(androidId  
  36.                                         .getBytes("utf8"));  
  37.                             } else {  
  38.                                 final String deviceId = ((TelephonyManager)   
  39.                                         context.getSystemService(  
  40.                                             Context.TELEPHONY_SERVICE)  
  41.                                             .getDeviceId();  
  42.                                 uuid = deviceId != null ? UUID  
  43.                                         .nameUUIDFromBytes(deviceId  
  44.                                                 .getBytes("utf8")) : UUID  
  45.                                         .randomUUID();  
  46.                             }  
  47.                         } catch (UnsupportedEncodingException e) {  
  48.                             throw new RuntimeException(e);  
  49.                         }  
  50.                         // Write the value out to the prefs file  
  51.                         prefs.edit()  
  52.                                 .putString(PREFS_DEVICE_ID, uuid.toString())  
  53.                                 .commit();  
  54.                     }  
  55.                 }  
  56.             }  
  57.         }  
  58.     }  
  59.   
  60.     /** 
  61.      * Returns a unique UUID for the current android device. As with all UUIDs, 
  62.      * this unique ID is "very highly likely" to be unique across all Android 
  63.      * devices. Much more so than ANDROID_ID is. 
  64.      *  
  65.      * The UUID is generated by using ANDROID_ID as the base key if appropriate, 
  66.      * falling back on TelephonyManager.getDeviceID() if ANDROID_ID is known to 
  67.      * be incorrect, and finally falling back on a random UUID that's persisted 
  68.      * to SharedPreferences if getDeviceID() does not return a usable value. 
  69.      *  
  70.      * In some rare circumstances, this ID may change. In particular, if the 
  71.      * device is factory reset a new device ID may be generated. In addition, if 
  72.      * a user upgrades their phone from certain buggy implementations of Android 
  73.      * 2.2 to a newer, non-buggy version of Android, the device ID may change. 
  74.      * Or, if a user uninstalls your app on a device that has neither a proper 
  75.      * Android ID nor a Device ID, this ID may change on reinstallation. 
  76.      *  
  77.      * Note that if the code falls back on using TelephonyManager.getDeviceId(), 
  78.      * the resulting ID will NOT change after a factory reset. Something to be 
  79.      * aware of. 
  80.      *  
  81.      * Works around a bug in Android 2.2 for many devices when using ANDROID_ID 
  82.      * directly. 
  83.      *  
  84.      * @see http://code.google.com/p/android/issues/detail?id=10603 
  85.      *  
  86.      * @return a UUID that may be used to uniquely identify your device for most 
  87.      *         purposes. 
  88.      */  
  89.     public UUID getDeviceUuid() {  
  90.         return uuid;  
  91.     }  
  92. }  


根据版本进行判断的方式:Serial序列号-->UUID (支持数31)

通过Serial 即可,在覆盖率上,你已经成功的获得了98.4%的用户,剩下的1.6%的用户系统是在9 以下的。

通过AndroidID获取,前面已经说过,在8上,有些商家的手机会有一些bug,返回相同的AndroidID,如果Serial和AndroidID都不行

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * Return pseudo unique ID 
  3.  * @return ID 
  4.  */  
  5. public static String getUniquePsuedoID()  
  6. {  
  7.     // If all else fails, if the user does have lower than API 9 (lower  
  8.     // than Gingerbread), has reset their phone or 'Secure.ANDROID_ID'  
  9.     // returns 'null', then simply the ID returned will be solely based  
  10.     // off their Android device information. This is where the collisions  
  11.     // can happen.  
  12.     // Thanks http://www.pocketmagic.net/?p=1662!  
  13.     // Try not to use DISPLAY, HOST or ID - these items could change.  
  14.     // If there are collisions, there will be overlapping data  
  15.     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);  
  16.   
  17.     // Thanks to @Roman SL!  
  18.     // http://stackoverflow.com/a/4789483/950427  
  19.     // Only devices with API >= 9 have android.os.Build.SERIAL  
  20.     // http://developer.android.com/reference/android/os/Build.html#SERIAL  
  21.     // If a user upgrades software or roots their phone, there will be a duplicate entry  
  22.     String serial = null;  
  23.     try  
  24.     {  
  25.         serial = android.os.Build.class.getField("SERIAL").get(null).toString();  
  26.   
  27.         // Go ahead and return the serial for api => 9  
  28.         return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();  
  29.     }  
  30.     catch (Exception e)  
  31.     {  
  32.         // String needs to be initialized  
  33.         serial = "serial"// some value  
  34.     }  
  35.   
  36.     // Thanks @Joe!  
  37.     // http://stackoverflow.com/a/2853253/950427  
  38.     // Finally, combine the values we have found by using the UUID class to create a unique identifier  
  39.     return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();  
  40. }  


不用READ_PHONE_STATE权限直接获取ROM信息的方式:(支持率较低 16)

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. String m_szDevIDShort = "35" + //we make this look like a valid IMEI  
  2.             Build.BOARD.length()%10+ Build.BRAND.length()%10 +  
  3.             Build.CPU_ABI.length()%10 + Build.DEVICE.length()%10 +  
  4.             Build.DISPLAY.length()%10 + Build.HOST.length()%10 +  
  5.             Build.ID.length()%10 + Build.MANUFACTURER.length()%10 +  
  6.             Build.MODEL.length()%10 + Build.PRODUCT.length()%10 +  
  7.             Build.TAGS.length()%10 + Build.TYPE.length()%10 +  
  8.             Build.USER.length()%10 ; //13 digits  


最后贴上自己在项目中用的:

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public static String getDeviceId(Context context) {  
  2.         String deviceId = "";  
  3.         <span style="white-space:pre">  </span>if (deviceId != null && !"".equals(deviceId)) {  
  4. <span style="white-space:pre">              </span>return deviceId;  
  5. <span style="white-space:pre">      </span>}  
  6.         if (deviceId == null || "".equals(deviceId)) {  
  7.             try {  
  8.                 deviceId = getLocalMac(context).replace(":""");  
  9.             } catch (Exception e) {  
  10.                 e.printStackTrace();  
  11.             }  
  12.         }  
  13.         if (deviceId == null || "".equals(deviceId)) {  
  14.             try {  
  15.                 deviceId = getAndroidId(context);  
  16.             } catch (Exception e) {  
  17.                 e.printStackTrace();  
  18.             }  
  19.         }  
  20.         if (deviceId == null || "".equals(deviceId)) {  
  21.               
  22.             if (deviceId == null || "".equals(deviceId)) {  
  23.                 UUID uuid = UUID.randomUUID();  
  24.                 deviceId = uuid.toString().replace("-""");  
  25.                 writeDeviceID(deviceId);  
  26.             }  
  27.         }  
  28.         return deviceId;  
  29.     }  


[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. // IMEI码  
  2.     private static String getIMIEStatus(Context context) {  
  3.         TelephonyManager tm = (TelephonyManager) context  
  4.                 .getSystemService(Context.TELEPHONY_SERVICE);  
  5.         String deviceId = tm.getDeviceId();  
  6.         return deviceId;  
  7.     }  
  8.   
  9.     // Mac地址  
  10.     private static String getLocalMac(Context context) {  
  11.         WifiManager wifi = (WifiManager) context  
  12.                 .getSystemService(Context.WIFI_SERVICE);  
  13.         WifiInfo info = wifi.getConnectionInfo();  
  14.         return info.getMacAddress();  
  15.     }  
  16.   
  17.     // Android Id  
  18.     private static String getAndroidId(Context context) {  
  19.         String androidId = Settings.Secure.getString(  
  20.                 context.getContentResolver(), Settings.Secure.ANDROID_ID);  
  21.         return androidId;  
  22.     }  
  23.   
  24.     public static void saveDeviceID(String str) {  
  25.         try {  
  26.             FileOutputStream fos = new FileOutputStream(file);  
  27.             Writer out = new OutputStreamWriter(fos, "UTF-8");  
  28.             out.write(str);  
  29.             out.close();  
  30.         } catch (IOException e) {  
  31.             e.printStackTrace();  
  32.         }  
  33.     }  
  34.   
  35.     public static String readDeviceID() {  
  36.         StringBuffer buffer = new StringBuffer();  
  37.         try {  
  38.             FileInputStream fis = new FileInputStream(file);  
  39.             InputStreamReader isr = new InputStreamReader(fis, "UTF-8");  
  40.             Reader in = new BufferedReader(isr);  
  41.             int i;  
  42.             while ((i = in.read()) > -1) {  
  43.                 buffer.append((char) i);  
  44.             }  
  45.             in.close();  
  46.             return buffer.toString();  
  47.         } catch (IOException e) {  
  48.             e.printStackTrace();  
  49.             return null;  
  50.         }  
  51.     }  

对于获取设备唯一ID并没有绝对的方案,这一点在android的官方博客中也提到了,不过以上几种方案,应该可以满足平时的需求,大家可以选择其中自己认为比较好的,用于自己的项目中。不知道其他朋友在项目中是如何处理的,欢迎交流讨论。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 神笔添加视频尺码不符合怎么办 闲鱼卖家单号填错了怎么办 户户通没有信号强度怎么办 全民k歌qq登不上怎么办 手机直播没电了怎么办 淘宝退货卖家拒收怎么办 充的会员卡店家关门了怎么办 淘宝手机号码被注册了怎么办 淘宝不支持七天无理由退货怎么办 微信视频横屏怎么办 房子里潮气太重怎么办 淘宝不小心注销了怎么办 淘宝号不小心注销了怎么办 xp网络驱动没了怎么办 淘宝卖家客服态度差怎么办 怀孕吃辣椒喉咙好痛怎么办 淘宝店铺建议不要提交认证怎么办 淘宝买东西商家不退款怎么办 淘宝买东西商家不发货怎么办 在微信上买东西被骗了怎么办 新浪微博自动关注人怎么办 搜淘宝找不到关键词和店铺怎么办 小超市开在一起竞争太大怎么办 淘宝店铺被投诉盗图怎么办 充电宝ic坏了怎么办 淘宝店宝贝权重下降怎么办 淘宝卖家评分低怎么办 淘宝买东西客服不理人怎么办 支付宝本次交易嫌疑违规怎么办 支付宝一年的交易总额怎么办 交易关闭钱扣了怎么办 交易猫账号绑定支付宝打不开怎么办 拼多多涉假处罚怎么办 淘宝店铺重复铺货扣6分怎么办 帆布鞋子买大了怎么办 开淘宝店没销量怎么办 开淘宝店没有销量怎么办 淘宝买东西支付密码错了怎么办 淘宝登入密码忘记了怎么办 逛街时手机没电了怎么办 逛街手机没有电了怎么办