来自:http://syawlaus.com/remindme-%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96android%E8%AE%BE%E5%A4%87%E5%94%AF%E4%B8%80%E8%AF%86%E5%88%AB%E7%A0%81%EF%BC%9F/
如果我们想唯一识别一台Android设备,就需要获取设备的唯一识别码。怎么获取呢?
下面是Android设备一些可供选择的唯一识别码及其适用范围:
IMEI (International Mobile Equipment Identity Number,国际移动设备识别码)
- 用于在手机网络中识别每一部独立的手机
- 对于不在手机网络的设备(如Android平板),就不能使用IMEI来识别。
IMSI (International Mobile Subscriber Identity,国际移动用户识别码)
- 它是在公众陆地移动电话网(PLMN)中用于唯一识别移动用户的一个号码,在GSM网络,这个号码通常被存放在SIM卡中
- 跟IMEI一样,对于不在手机网络的设备就不能使用IMSI来识别。
- 64位的十六进制字符串,设备首次启动时会随时生成
- 如果设备恢复了出厂设置,这个值可能会改变
- 设备root了之后,这个值可以手动修改
- Android 2.2发现bug,部分设备具有相同Android ID(9774d56d682e549c),模拟器的Android ID也是这个
- 这个值有时会为null
- 一般不推荐使用
Java
12 private String androidId = Secure . getString ( getContext ( ) . getContentResolver ( ) ,Secure . ANDROID_ID ) ;
- 唯一的设备ID,如GSM网络的IMEI,CDMA网络的MEID / ESN,可能返回null(API文档的描述)
- 只对手机设备有效,对于不在手机网络的设备,会返回null
- 获取到的Device ID值,即使设备恢复出厂设置也不会改变
- 需要READ_PHONE_STATE权限
- 某些设备的Device ID实现有bug,会返回0或*
Java
12 TelephonyManager tm = ( TelephonyManager ) getSystemService ( TELEPHONY_SERVICE ) ;String deviceId = tm . getDeviceId ( ) ;
Serial Number
- 从Android 2.3开始(API level 9),可以通过android.os.Build.SERIAL获取
- 需要READ_PHONE_STATE权限
WiFi MAC Address
- 不是所有Android设备都有WiFi
- 对于有WiFi的设备,如果WiFi没有开启,可能获取不了WiFi MAC地址
- 需要ACCESS_WIFI_STATE权限
Java
12 WifiManager wm = ( WifiManager ) Context . getSystemService ( Context . WIFI_SERVICE ) ;String wifiMac = wm . getConnectionInfo ( ) . getMacAddress ( ) ;
BlueTooth MAC Address
- 如果没有开启BlueTooth,可能获取不了BlueTooth MAC地址
- 需要BLUETOOTH权限
Java
123 BluetoothAdapter bluetoothAdapter = null ; // Local Bluetooth adapterbluetoothAdapter = BluetoothAdapter . getDefaultAdapter ( ) ;String bluetoothMac = bluetoothAdapter . getAddress ( ) ;
UUID(Universally unique identifier,通用唯一标识符)
Java
12345678910111213141516171819202122232425262728293031323334 // 方法1public 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 ( ) ;}}
Java
123456789101112 // 方法2TelephonyManager tm = ( TelephonyManager ) getBaseContext ( ) . getSystemService ( Context . TELEPHONY_SERVICE ) ;final String DeviceId , SerialNum , androidId ;DeviceId = tm . getDeviceId ( ) ;SerialNum = tm . getSimSerialNumber ( ) ;androidId = Secure . getString ( getContentResolver ( ) , Secure . ANDROID_ID ) ;UUID deviceUuid = new UUID ( androidId . hashCode ( ) , ( ( long ) DeviceId . hashCode ( ) << 32 ) | SerialNum . hashCode ( ) ) ;String mydeviceId = deviceUuid . toString ( ) ;Log . v ( "My Id" , "Android DeviceId is: " + DeviceId ) ;Log . v ( "My Id" , "Android SerialNum is: " + SerialNum ) ;Log . v ( "My Id" , "Android androidId is: " + androidId ) ;
Java
123456789 // 方法3final 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 ( ) ;
Java
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 // 方法4import 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 volatile static 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 fileuuid = 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 filetry {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 fileprefs . 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 ;}}
Java
12345678910111213141516171819 // 方法5// Here is the code that Reto Meier used in the google I/O presentation this year to get a unique id for the user:private static String uniqueID = null ;private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID" ;public synchronized static String id ( Context context ) {if ( uniqueID == null ) {SharedPreferences sharedPrefs = context . getSharedPreferences (PREF_UNIQUE_ID , Context . MODE_PRIVATE ) ;uniqueID = sharedPrefs . getString ( PREF_UNIQUE_ID , null ) ;if ( uniqueID == null ) {uniqueID = UUID . randomUUID ( ) . toString ( ) ;Editor editor = sharedPrefs . edit ( ) ;editor . putString ( PREF_UNIQUE_ID , uniqueID ) ;editor . commit ( ) ;}}return uniqueID ;}
Java
123456789101112131415 // 方法6String 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