
先来看看几种比较单一的方式:
IMEI
方式:TelephonyManager.getdeviceid():
问题
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
有兴趣的朋友可以再仔细看看
支持率比较高的(支持票数157):androIDID --> 剔除2.2版本(API 8)中有问题的手机,使用UUID替代
import androID.content.Context; import androID.content.SharedPreferences; import androID.provIDer.Settings.Secure; import androID.telephony.TelephonyManager; import java.io.UnsupportedEnCodingException; 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 volatile UUID 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) { // Use the IDs prevIoUsly computed and stored in the // prefs file uuID = UUID.fromString(ID); } else { final String androIDID = Secure.getString( context.getContentResolver(),Secure.ANDROID_ID); // Use the Android id unless it's broken,in which case // fallback on deviceid,// unless it's not available,then fallback on a random // number which we store to a prefs file try { if (!"9774d56d682e549c".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); } // Write the value out to the prefs file prefs.edit() .putString(PREFS_DEVICE_ID,uuID.toString()) .commit(); } } } } } /** * Returns a unique UUID for the current androID device. As with all UUIDs,* this unique ID is "very highly likely" to be unique across all AndroID * devices. Much more so than ANDROID_ID is. * * The UUID is generated by using ANDROID_ID as the base key if appropriate,* falling back on TelephonyManager.getdeviceid() if ANDROID_ID is kNown to * be incorrect,and finally falling back on a random UUID that's persisted * to SharedPreferences if getdeviceid() does not return a usable value. * * In some rare circumstances,this ID may change. In particular,if the * device is factory reset a new device ID may be generated. In addition,if * a user upgrades their phone from certain BUGgy implementations of AndroID * 2.2 to a newer,non-BUGgy version of AndroID,the device ID may change. * Or,if a user uninstalls your app on a device that has neither a proper * Android id nor a Device ID,this ID may change on reinstallation. * * Note that if the code falls back on using TelephonyManager.getdeviceid(),* the resulting ID will NOT change after a factory reset. Something to be * aware of. * * Works around a BUG in AndroID 2.2 for many devices when using ANDROID_ID * directly. * * @see http://code.Google.com/p/androID/issues/detail?ID=10603 * * @return a UUID that may be used to uniquely IDentify your device for most * purposes. */ public UUID getDeviceUuID() { return uuID; } } 根据版本进行判断的方式:Serial序列号-->UUID (支持数31)
通过Serial 即可,在覆盖率上,你已经成功的获得了98.4%的用户,剩下的1.6%的用户系统是在9 以下的。
通过AndroIDID获取,前面已经说过,在8上,有些商家的手机会有一些BUG,返回相同的AndroIDID,如果Serial和AndroIDID都不行
/** * 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 phone 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! // http://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 phone,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 e) { // String needs to be initialized serial = "serial"; // some value } // Thanks @Joe! // http://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(); } 不用READ_PHONE_STATE权限直接获取ROM信息的方式:(支持率较低 16)
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
最后贴上自己在项目中用的:
public static String getdeviceid(Context context) { String deviceid = ""; if (deviceid != null && !"".equals(deviceid)) { return deviceid; } if (deviceid == null || "".equals(deviceid)) { try { deviceid = getLocalMac(context).replace(":",""); } catch (Exception e) { e.printstacktrace(); } } if (deviceid == null || "".equals(deviceid)) { try { deviceid = getAndroIDID(context); } catch (Exception e) { e.printstacktrace(); } } if (deviceid == null || "".equals(deviceid)) { if (deviceid == null || "".equals(deviceid)) { UUID uuID = UUID.randomUUID(); deviceid = uuID.toString().replace("-",""); writedeviceid(deviceid); } } return deviceid; } // IMEI码 private static String getIMIEStatus(Context context) { TelephonyManager tm = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); String deviceid = tm.getdeviceid(); return deviceid; } // Mac地址 private static String getLocalMac(Context context) { WifiManager wifi = (WifiManager) context .getSystemService(Context.WIFI_SERVICE); WifiInfo info = wifi.getConnectionInfo(); return info.getMacAddress(); } // Android id private static String getAndroIDID(Context context) { String androIDID = Settings.Secure.getString( context.getContentResolver(),Settings.Secure.ANDROID_ID); return androIDID; } public static voID savedeviceid(String str) { try { fileOutputStream fos = new fileOutputStream(file); Writer out = new OutputStreamWriter(fos,"UTF-8"); out.write(str); out.close(); } catch (IOException e) { e.printstacktrace(); } } public static String readdeviceid() { StringBuffer buffer = new StringBuffer(); try { fileinputStream fis = new fileinputStream(file); inputStreamReader isr = new inputStreamReader(fis,"UTF-8"); Reader in = new BufferedReader(isr); int i; while ((i = in.read()) > -1) { buffer.append((char) i); } in.close(); return buffer.toString(); } catch (IOException e) { e.printstacktrace(); return null; } } 对于获取设备唯一ID并没有绝对的方案,这一点在androID的官方博客中也提到了,不过以上几种方案,应该可以满足平时的需求,大家可以选择其中自己认为比较好的,用于自己的项目中。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的详解Android获取设备唯一ID的几种方式全部内容,希望文章能够帮你解决详解Android获取设备唯一ID的几种方式所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)