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的标识符。
- IMEI
-
IMSI
String ts = Context.TELEPHONY_SERVICE; TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(ts); String imsi = mTelephonyMgr.getSubscriberId(); String imei = mTelephonyMgr.getDeviceId();
-
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);