我想获取Android设备的唯一标识符。我已经尝试使用以下代码
String ts = Context.TELEPHONY_SERVICE;
TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(ts);
但是我知道这只适用于手机。
那么如果我的应用程序在笔记本电脑、小型笔记本电脑或其他类型的设备上运行怎么办?在这种情况下,如何获取唯一标识符?
我想获取Android设备的唯一标识符。我已经尝试使用以下代码
String ts = Context.TELEPHONY_SERVICE;
TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(ts);
但是我知道这只适用于手机。
那么如果我的应用程序在笔记本电脑、小型笔记本电脑或其他类型的设备上运行怎么办?在这种情况下,如何获取唯一标识符?
在安卓手机上有三种标识符。
IMSI
String ts = Context.TELEPHONY_SERVICE;
TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(ts);
String imsi = mTelephonyMgr.getSubscriberId();
String imei = mTelephonyMgr.getDeviceId();
Android ID是在设备第一次启动时生成的一个64位十六进制字符串。 通常情况下,除非进行恢复出厂设置,否则不会更改。
Secure.getString(getContentResolver(), Secure.ANDROID_ID);
很抱歉打扰了一个旧帖子,但这个问题令我头痛。我找到了一篇好的文章供大家阅读,这确实帮了我很多。
在Android应用程序开发中,有时需要获取基于Android的智能手机设备的唯一标识符。这在用户想要跟踪应用程序的唯一设备安装情况的情况下是必要的。
这在Android开发人员想要仅向少数特定设备发送推送消息的情况下也很有用。因此,在这里对每个设备都拥有一个UDID变得必要。
在Android中,有许多替代设备UDID的方法。以下列出了一些获取Android应用程序中UDID的方法及其优缺点以及获取设备ID所需的任何必要权限:
1)IMEI:(International Mobile Equipment Identity)
IMEI号码是获取设备ID的非常好的主要来源。它对于每个设备都是唯一的,并且依赖于设备硬件。因此,它对于每个设备都是唯一的,并且在设备的整个生命周期内都是永久的。
获取设备IMEI的代码片段如下:
TelephonyManager TelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String m_deviceId = TelephonyMgr.getDeviceId();
为此,您的应用程序将需要在清单文件中给予“android.permission.READ_PHONE_STATE”权限。
使用IMEI作为设备标识的优点:
IMEI对于每个设备都是唯一的。 即使重新安装应用程序或设备进行根刷或出厂设置,它仍然是该设备的唯一标识。
使用IMEI作为设备标识的缺点:
IMEI依赖于设备的Sim卡槽,因此无法为不使用Sim卡的设备获取IMEI。 在双卡设备中,我们为同一设备获取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的优点:
它是所有类型设备(智能手机和平板电脑)的唯一标识符。无需任何权限。
它在所有设备上保持唯一,并且适用于没有Sim卡槽的手机。
使用Android_ID作为设备ID的缺点:
如果用户升级了Android操作系统版本,则可能会更改此ID。如果设备被root或设备进行了出厂设置,则ID将发生更改。此外,已知某些中国Android设备制造商存在同一Android_ID的问题。
3)WLAN MAC地址字符串
我们还可以使用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”权限。
使用 WLAN MAC 地址作为设备标识符的优点:
它是所有类型的设备(智能手机和平板电脑)的唯一标识符。 如果重新安装应用程序,它仍然是唯一的。
将 WLAN MAC 地址用作设备标识符的缺点:
如果设备没有 WiFi 硬件,则会得到空 MAC 地址,但通常情况下,大多数 Android 设备都有 WiFi 硬件,并且市场上几乎没有没有 WiFi 硬件的设备。
4) 蓝牙地址字符串
我们还可以使用 Bluetooth 设备获取 Android 手机的唯一 ID。每个具有蓝牙硬件的设备的蓝牙设备地址都是唯一的。
获取 Bluetooth 设备地址的代码片段如下所示,
BluetoothAdapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String m_bluetoothAdd = m_BluetoothAdapter.getAddress();
要获取上述代码,您的应用程序需要在清单文件中授予“android.permission.BLUETOOTH”权限。
使用蓝牙设备地址作为设备ID的优点: 它是所有类型设备(智能手机和平板电脑)的唯一标识符。 所有设备通常只有一个蓝牙硬件,并且它不会更改。
使用蓝牙设备地址作为设备ID的缺点: 如果设备没有蓝牙硬件,则会得到null。
我认为这些是用于获取Android智能手机设备的唯一设备ID的几种最佳方法以及使用它们的优缺点。现在轮到您根据Android应用程序开发需求来决定使用哪种方法。
如果还有其他获取UDID的方法,并且可以弥补上述方法的缺点,那么我很乐意在我的Android应用程序中尝试这些方法。请在评论框中分享,并提出任何建议或疑问。
Secure.getString(getContentResolver(), Secure.ANDROID_ID);
这并不适用于所有设备。
一些安卓设备存在问题,当我们尝试获取设备ID时,某些设备会返回null。解决这个问题的唯一方法是自己生成一个伪设备ID。这个函数将为您生成一个唯一的设备ID。您可以根据需要更改此函数。我也曾为解决这个问题而苦苦挣扎。
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;
}
请查看android.provider.Secure.Settings
中的常量ANDROID_ID是否有所帮助。
我从官方文档中添加了几个有用的链接;
如需了解有关如何为每个安装应用程序的Android设备获取唯一标识符的详细说明,请参阅此官方Android开发者博客文章:
http://android-developers.blogspot.com/2011/03/identifying-app-installations.html
似乎最好的方法是在安装时自动生成一个标识符,并在应用程序重新启动时随后读取它。
我个人认为这样做是可以接受的,但并不理想。 Android提供的没有一个标识符适用于所有情况,因为大多数标识符都依赖于手机的无线电状态(wifi开/关,蜂窝网络开/关,蓝牙开/关)。其他标识符(例如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();
}
}
String deviceId = Secure.getString(this.getContentResolver(),
Secure.ANDROID_ID);
使用 MAC 地址:
一个媒体访问控制地址(MAC地址)是分配给网络接口的唯一标识符。
任何连接到网络的设备都有一个 MAC 地址,你可以在 Android 设备上通过进入“设置” > “关于手机” > “状态”来查找它。
你可以使用Bluetooth API获取蓝牙 MAC 地址。
Settings.Secure#ANDROID_ID 返回 Android ID,它是一个唯一的 64 位十六进制字符串。
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
如果系统中启用了网络设备(例如蓝牙等),您可以获取MAC地址。但设备可能具有蓝牙、WiFi等或者没有任何设备。
您可以编写自己的唯一ID生成器(例如,随机生成20个数字或符号)。
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();