Android设备的唯一ID

我想要一些Android设备的唯一ID。 我用下面的代码试了一下

String ts = Context.TELEPHONY_SERVICE; TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(ts); 

但是我知道这只适用于手机。

如果我的应用程序在某些笔记本,上网本或其他types的设备上运行,该怎么办? 在这种情况下如何获得唯一的ID?

看看android.provider.Secure.Settings中的常量ANDROID_ID ,看看是否有帮助。

我正在从官方文档中添加一些有用的链接。

  • 唯一标识符的最佳实践
  • Android O中对设备标识符的更改

在android手机上有三种types的标识符。

  1. IMEI
  2. IMSI

     String ts = Context.TELEPHONY_SERVICE; TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(ts); String imsi = mTelephonyMgr.getSubscriberId(); String imei = mTelephonyMgr.getDeviceId(); 
  3. Android ID它是在设备第一次启动时生成的64位hexstring。 一般情况下,除非出厂重置,否则不会更改。

     Secure.getString(getContentResolver(), Secure.ANDROID_ID); 
 Secure.getString(getContentResolver(), Secure.ANDROID_ID); 

这不适用于所有设备。

某些android设备有问题有些设备在我们尝试获取设备ID时返回null。解决这个问题的唯一方法是创build一个应该由我们自己生成的伪设备ID。这个函数将为您生成一个唯一的设备ID您可以根据需要对此function进行更改。我们也为解决此问题而苦苦挣扎。

 public String getDeviceID() { /*String Return_DeviceID = USERNAME_and_PASSWORD.getString(DeviceID_key,"Guest"); return Return_DeviceID;*/ TelephonyManager TelephonyMgr = (TelephonyManager) getApplicationContext().getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); String m_szImei = TelephonyMgr.getDeviceId(); // Requires // READ_PHONE_STATE // 2 compute DEVICE ID 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 // 3 android ID - unreliable String m_szAndroidID = Secure.getString(getContentResolver(),Secure.ANDROID_ID); // 4 wifi manager, read MAC address - requires // android.permission.ACCESS_WIFI_STATE or comes as null WifiManager wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); String m_szWLANMAC = wm.getConnectionInfo().getMacAddress(); // 5 Bluetooth MAC address android.permission.BLUETOOTH required BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); String m_szBTMAC = m_BluetoothAdapter.getAddress(); System.out.println("m_szBTMAC "+m_szBTMAC); // 6 SUM THE IDs String m_szLongID = m_szImei + m_szDevIDShort + m_szAndroidID+ m_szWLANMAC + m_szBTMAC; System.out.println("m_szLongID "+m_szLongID); MessageDigest m = null; try { m = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } m.update(m_szLongID.getBytes(), 0, m_szLongID.length()); byte p_md5Data[] = m.digest(); String m_szUniqueID = new String(); for (int i = 0; i < p_md5Data.length; 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); } m_szUniqueID = m_szUniqueID.toUpperCase(); Log.i("-------------DeviceID------------", m_szUniqueID); Log.d("DeviceIdCheck", "DeviceId that generated MPreferenceActivity:"+m_szUniqueID); return m_szUniqueID; } 

对不起,碰到一个旧的线程,但这个问题让我头痛,我find了一个很好的文章供人阅读,这真的帮了我很多。

有时在Android应用程序开发过程中需要获取基于Android的智能手机设备的唯一ID。 这在用户想要跟踪应用程序的唯一设备安装的情况下是必要的。

这在Android开发人员只想将推送消息发送给less数特定设备的情况下也很有用。 所以在这里,每个设备都需要有一个UDID。

在Android中有许多设备的UDID的替代品。 下面列出了在android应用程序中获取UDID的一些方法,其优点和缺点以及获取设备ID的所有必要权限。

  • IMEI :(国际移动设备标识)
  • Android ID
  • WLAN MAC地址string
  • 蓝牙地址string

1)IMEI :(国际移动设备标识)

IMEI号码是获取设备ID的非常好的主要来源。 它是每个设备都是独一无二的,并依赖于设备硬件。 所以它对于每一个设备也是独一无二的,并且在设备的使用寿命中是永久的。

获取设备IMEI的代码片段如下所示,

 TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); String m_deviceId = TelephonyMgr.getDeviceId(); 

为此,您的应用程序将需要清单文件中给出的权限“android.permission.READ_PHONE_STATE”。

使用IMEI作为设备ID的优势:

IMEI是每个设备都独一无二的。 即使应用程序已重新安装,或者设备已根植或出厂重置,该设备仍然是唯一的设备。

使用IMEI作为设备ID的缺点:

IMEI取决于设备的SIM卡插槽,因此无法获取不使用SIM卡的设备的IMEI。 在双SIM设备中,我们针对相同的设备获得2个不同的IMEI,因为它具有2个SIM卡插槽。

2)Android的ID

Android_ID是一个唯一的64位数字,在设备首次启动时生成并存储。 设备出厂重置并生成新的Android_ID将被清除。

获取Android_ID的代码如下所示,

 String m_androidId = Secure.getString(getContentResolver(), Secure.ANDROID_ID); 

使用Android_ID作为设备ID的优势:

它是所有types设备(智能手机和平板电脑)的唯一标识符。 不需要任何许可。

它将在所有设备中保持独特,并且在没有SIM卡插槽的手机上工作。

使用Android_ID作为设备ID的缺点:

如果用户升级Android操作系统版本,则可能会更改。 如果设备在设备上进行了根或出厂重置,则ID将被更改。 还有一个中国的Android设备制造商已知的问题,一些设备具有相同的Android_ID。

3)WLAN MAC地址string

我们也可以使用WLAN MAC地址获得Android手机的唯一ID。 MAC地址对于所有设备是唯一的,并且适用于各种设备。

获取设备的WLAN MAC地址的代码片段如下所示,

 WifiManager m_wm = (WifiManager)getSystemService(Context.WIFI_SERVICE); String m_wlanMacAdd = m_wm.getConnectionInfo().getMacAddress(); 

您的应用程序将需要清单文件中给出的权限“android.permission.ACCESS_WIFI_STATE”。

设备ID使用WLAN MAC地址的优点:

它是所有types设备(智能手机和平板电脑)的唯一标识符。 如果应用程序重新安装,它仍然是唯一的。

设备ID使用WLAN MAC地址的缺点:

如果设备没有wifi硬件,那么你会得到空MAC地址,但一般来说,大多数的Android设备都有wifi硬件,市面上没有wifi硬件的设备也很less。

4)蓝牙地址string

我们也可以使用蓝牙设备获得Android手机的唯一ID。 蓝牙设备地址对于具有蓝牙硬件的每个设备是唯一的。

获取蓝牙设备地址的代码片段如下所示,

 BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); String m_bluetoothAdd = m_BluetoothAdapter.getAddress(); 

为了得到上面的代码,你的应用程序需要清单文件中给出的权限“android.permission.BLUETOOTH”。

使用蓝牙设备地址作为设备ID的优点:它是所有types设备(智能手机和平板电脑)的唯一标识符。 所有设备中通常都有一个蓝牙硬件,它不会被改变。

使用蓝牙设备地址作为设备ID的缺点:如果设备没有蓝牙硬件,那么你得到空。

按照我的说法,这些都是获得Android智能手机设备唯一设备ID的最佳方法,以及使用它的优缺点。 现在,根据Android应用程序开发需求决定使用哪种方法。

如果还有其他的方法来获取UDID,并且覆盖了上述方法的缺点,那么我很乐意在Android应用程序中探索这些方法。 PL。 分享那些在评论框中,如果有任何build议或疑问。

这是文章

有关如何为安装应用程序的每个Android设备获取唯一标识符的详细说明,请参阅以下官方Android开发人员博客post:

http://android-developers.blogspot.com/2011/03/identifying-app-installations.html

看起来最好的方法是在安装时生成一个自己的文件,然后在应用程序重新启动时读取它。

我个人觉得这个可以接受但并不理想。 没有一个由Android提供的标识符在所有情况下工作,因为大多数依赖于电话的无线电状态(无线开/关,手机开/关,蓝牙开/关)。 其他像Settings.Secure.ANDROID_ID必须由制造商实施,并不保证是唯一的。

以下是将数据写入INSTALLATION文件的示例,该文件将与应用程序在本地保存的任何其他数据一起存储。

 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(); } } 

使用MAC地址 :

介质访问控制地址(MAC地址)是分配给networking接口的唯一标识符

任何连接到networking的设备都保证有一个MAC地址,您可以通过转到设置>关于手机>状态在Android上find它。

您应该能够使用蓝牙API获取蓝牙Mac地址。

我现在不能写评论,所以我写在这里。

如果networking设备(蓝牙等)在系统中启用(打开),您可以获得MAC地址。 但设备可能有蓝牙或Wi-Fi等或没有

你可以编写你自己的唯一Id生成器(例如随机有20个数字或符号)

Settings.Secure#ANDROID_ID将Android ID作为唯一的64位hexstring返回。

 import android.provider.Settings.Secure; private String android_id = Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID); 
 final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE); final String tmDevice, tmSerial, tmPhone, 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(), ((<span id="IL_AD3" class="IL_AD">long</span>)tmDevice.hashCode() << 32) | tmSerial.hashCode()); String deviceId = deviceUuid.toString(); 
 TextView textAndroidId = (TextView)findViewById(R.id.androidid); String AndroidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID); textAndroidId.setText("My ID is: " + AndroidId); 

你可以试试这个:

 String deviceId = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID);