- 所有添加有谷歌账户的设备可以返回一个 ANDROID_ID
- 所有的CDMA设备对于 ANDROID_ID 和 TelephonyManager.getDeviceId() 返回相同的值(只要在设置时添加了谷歌账户)
唯一标识码这东西在网络应用中非常有用,例如检测是否重复注册之类的。
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
我们在项目过程中或多或少会使用到设备的唯一识别码,我们希望能够得到一个稳定、可靠的设备唯一识别码。今天我们将介绍几种方式。
1. DEVICE_ID
假设我们确实需要用到真实设备的标识,可能就需要用到DEVICE_ID。在以前,我们的Android设备是手机,这个DEVICE_ID可以同通过getSystemService(Context.TELEPHONY_SERVICE).getDeviceId()获取,它根据不同的手机设备返回IMEI,MEID或者ESN码,但它在使用的过程中会遇到很多问题:
- 非手机设备: 如果只带有Wifi的设备或者音乐播放器没有通话的硬件功能的话就没有这个DEVICE_ID
- 权限: 采用此种方法,需要在AndroidManifest.xml中加入一个许可:android.permission.READ_PHONE_STATE,并且用户应当允许安装此应用。作为手机来讲,IMEI是唯一的,它应该类似于 359881030314356(除非你有一个没有量产的手机(水货)它可能有无效的IMEI,如:0000000000000)。,但如果我们只为了获取它,没有用到其他的通话功能,那这个权限有点大才小用
- bug:在少数的一些手机设备上,该实现有漏洞,会返回垃圾,如:zeros或者asterisks的产品
2. MAC ADDRESS
我们也可以通过手机的Wifi或者蓝牙设备获取MAC ADDRESS作为DEVICE ID,但是并不建议这么做,因为并不是所有的设备都有Wifi,并且,如果Wifi没有打开,那硬件设备无法返回MAC ADDRESS.
The WLAN MAC Address string, 是另一个唯一ID。但是你需要为你的工程加入android.permission.ACCESS_WIFI_STATE 权限,否则这个地址会为null。
WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE); String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
Returns: 00:11:22:33:44:55 (这不是一个真实的地址。而且这个地址能轻易地被伪造。).WLan不必打开,就可读取些值。
The BT MAC Address string, 只在有蓝牙的设备上运行。并且要加入android.permission.BLUETOOTH 权限.
BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); String m_szBTMAC = m_BluetoothAdapter.getAddress();
Returns: 43:25:78:50:93:38 . 蓝牙没有必要打开,也能读取。
3. Serial Number
装有SIM卡的设备可以通过getSystemService(Context.TELEPHONY_SERVIEC).getSimSerialNumber();获取到
sim serial number。 注意对CDMA设备,返回的是一个空值。
在Android 2.3可以通过android.os.Build.SERIAL获取,非手机设备可以通过该接口获取。
4. ANDROID_ID
ANDROID_ID是设备第一次启动时产生和存储的64bit的一个数,当设备被wipe后该数重置
ANDROID_ID似乎是获取Device ID的一个好选择,但它也有缺陷:
- 它在Android <=2.1 or Android >=2.3的版本是可靠、稳定的,但在2.2的版本并不是100%可靠的
- 在主流厂商生产的设备上,有一个很经常的bug,就是每个设备都会产生相同的ANDROID_ID:9774d56d682e549c
- String m_szAndroidID = Secure.getString(getContentResolver(), Secure.ANDROID_ID)
5. Installtion ID : UUID
以上四种方式都有或多或少存在的一定的局限性或者bug,在这里,有另外一种方式解决,就是使用UUID,该方法无需访问设备的资源,也跟设备类型无关。
这种方式是通过在程序安装后第一次运行后生成一个ID实现的,但该方式跟设备唯一标识不一样,它会因为不同的应用程序而产生不同的ID,而不是设备唯一ID。因此经常用来标识在某个应用中的唯一ID(即Installtion ID),或者跟踪应用的安装数量。很幸运的,Google Developer Blog提供了这样的一个框架:
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();
}
}
6 Pseudo-Unique ID, 这个在任何Android手机中都有效
有一些特殊的情况,一些如平板电脑的设置没有通话功能,或者你不愿加入READ_PHONE_STATE许可。而你仍然想获得唯一序列号之类的东西。这时你可以通过取出ROM版本、制造商、CPU型号、以及其他硬件信息来实现这一点。这样计算出来的ID不是唯一的(因为如果两个手机应用了同样的硬件以及Rom 镜像)。但应当明白的是,出现类似情况的可能性基本可以忽略。要实现这一点,你可以使用Build类:
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
大多数的Build成员都是字符串形式的,我们只取他们的长度信息。我们取到13个数字,并在前面加上“35”。这样这个ID看起来就和15位IMEI一样了。
总结
综合以上所述,为了实现在设备上更通用的获取设备唯一标识,我们可以实现这样的一个类,为每个设备产生唯一的UUID,以ANDROID_ID为基础,在获取失败时以TelephonyManager.getDeviceId()为备选方法,如果再失败,使用UUID的生成策略
相关推荐
在Android操作系统中,寻找一个设备的唯一标识是一个常见的需求,特别是在开发...综上所述,"Android手机唯一标识"涉及多个标识的获取、使用和组合,需要在尊重用户隐私的同时,找到一个尽可能稳定且独特的设备标识。
1. **IMEI(国际移动设备识别码)**:这是GSM和UMTS网络中手机的唯一标识,可以通过`TelephonyManager`获取。IMEI对于具有物理SIM卡槽的设备是有效的,但在没有SIM卡或使用Wi-Fi连接的设备上可能不可用。 2. **...
1. **IMEI(国际移动设备识别码)**:这是手机硬件的全球唯一标识,通常用于区分物理设备。每个带有蜂窝数据功能的Android设备都有一个IMEI。不过,IMEI在非手机设备(如平板、手表、电视)上可能不可用。 2. **...
在早期,IMEI(国际移动设备识别码)是广泛使用的设备唯一标识,但随着隐私保护政策的加强,IMEI的获取和使用受到了限制。在这种背景下,使用UUID作为IMEI的替代方案变得越来越常见。本文将深入探讨如何在Android中...
在Android平台上,开发人员有时需要访问设备的特定标识符,以实现特定功能,如设备唯一标识、定位服务或网络状态检测。本文将详细介绍如何在Android应用中获取IMSI(国际移动用户识别码)、IMEI(国际移动设备识别码...
而MAC地址(Media Access Control Address)则是物理网络接口控制器的唯一标识,通常用于局域网内的设备识别。 在Android应用中获取IP地址,我们主要依赖于网络连接的状态。以下是一段简单的代码示例,展示了如何...
在开发针对Windows Mobile设备的应用程序时,...需要注意的是,随着移动平台的发展,如Windows Phone和现代的Android、iOS,获取设备唯一标识的方法可能会有所变化,因此开发者应始终关注最新的平台文档和技术更新。
2. **IMEI(国际移动设备识别码)**:IMEI是手机的唯一标识,通常用于区分不同的手机。在Android中,可以通过`TelephonyManager`的`getDeviceId()`方法获取,但需要注意,这需要`READ_PHONE_STATE`权限。 3. **MAC...
MAC地址是设备在网络中的唯一物理标识。在Android中,可以通过`WifiManager`类来获取MAC地址。首先需要请求`ACCESS_WIFI_STATE`权限,然后通过`Context.getSystemService(Context.WIFI_SERVICE)`获取`WifiManager`...
在Android平台上,开发移动应用时有时需要获取设备的物理MAC(Media Access Control)地址,这在设备定位、网络连接管理或者其他需要唯一标识设备的场景中非常有用。MAC地址是网络接口控制器(NIC)的硬件地址,它在...
5. **手机MAC地址**:物理设备的唯一标识,但出于隐私考虑,Android 6.0及以后版本不再允许直接访问,需要依赖网络接口。在iOS中,自iOS 7起,Apple也限制了直接获取MAC地址,通常会返回一个随机值。 6. **IMEI...
在Android平台上,IMEI(International Mobile Equipment Identity)和MAC(Media Access Control)地址是两种用于唯一标识设备的重要标识。IMEI是手机的国际移动设备识别码,通常用于区分不同的手机设备,而MAC地址...
MAC地址(Media Access Control Address)是网络设备的物理地址,每个网络接口控制器都有一个唯一的MAC地址,用于标识网络上的设备。在Android系统中,由于隐私和安全原因,直接通过Java API获取MAC地址的方法已被...
标题"通过NDK获得UUID"和描述涉及到利用Native Development Kit (NDK) 在Android系统底层获取UUID,以及通过Java层获取Android的唯一标识码。NDK允许开发者用C/C++编写部分应用,从而提高性能,特别是对于计算密集型...
MAC地址是一个物理网络接口控制器的唯一标识符,用于在局域网(LAN)中区分不同的设备。以下是Android获取MAC地址的三种常见方法: ### 1. 使用`WifiManager` `WifiManager`是Android提供的一个系统服务,主要用于...
IMSI(International Mobile Subscriber Identity)是国际移动用户识别码,是运营商分配给SIM卡的唯一标识。获取IMSI同样需要`TelephonyManager`: ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {...
在现代网络通信中,MAC(Media Access Control)地址是设备在网络中的唯一标识,通常由六组两进制数字组成,用于区分同一网络中的不同设备。在Android操作系统中,出于某些特殊需求,例如测试、隐私保护或者模拟不同...
在Android平台上,获取设备的MAC地址是一个常见的需求,特别是在实现设备唯一标识或者网络通信时。MAC(Media Access Control)地址是设备在网络层的物理地址,它是一个48位的二进制数,通常以冒号或破折号分隔的12...
在Android平台上,Mac地址是设备网络接口控制器的物理地址,通常用于唯一标识网络硬件。由于隐私和安全原因,从Android 6.0(API级别23)开始,系统对此进行了限制,不再允许应用直接获取Mac地址。不过,仍有一些...
4. **Wi-Fi MAC地址**:在安卓设备上,每个无线网络接口都有一个物理地址,即MAC地址,用于在网络中唯一识别设备。Wi-Fi MAC地址可通过编程方式获取,一般使用`WifiManager`类的`getMacAddress()`方法。然而,从...