uni-app中无法稳定获取mac地址,因android 6.0+限制、ios完全不可用,且mac易变;推荐用plus.device.uuid持久化+device.model/systemversion哈希生成设备指纹。

uni-app里直接调用plus.networkinfo.getNetworkInfo拿不到MAC地址
这个API只返回网络类型和信号强度,不包含硬件标识。Android从6.0(API 23)开始,系统就限制了普通应用通过标准API读取真实MAC地址的能力——WifiManager.getConnectionInfo().getMacAddress()在未开启WiFi或权限不足时返回"02:00:00:00:00:00"或null,不是bug,是系统行为。
- 必须手动申请
android.permission.ACCESS_FINE_LOCATION(即使你只想要MAC) - Android 10+(API 29)起,即使有定位权限,
wlan0的MAC也默认被随机化,除非你的App声明了android.permission.LOCAL_MAC_ADDRESS(需用户手动在设置里开启“本地网络设备地址”权限) - 蓝牙MAC(
BluetoothAdapter.getAddress())同样受限制,且设备未开启蓝牙时返回null
三种可行路径:按Android SDK版本分层适配getDeviceMac
不能只写一个方法硬扛所有机型。要根据Build.VERSION.SDK_INT动态选路,否则在华为EMUI、小米MIUI、ColorOS上大概率失败。
- SDK WifiInfo.getMacAddress(),稳定但仅限老设备
- SDK == 23(Android 6.0):尝试读取
/sys/class/net/wlan0/address文件,需root或系统签名,普通App基本不可行,建议fallback到随机UUID - SDK > 23(Android 7.0+):优先用
NetworkInterface.getByName("wlan0").getHardwareAddress(),失败则试"eth0"或"en0";注意捕获SecurityException和NullPointerException
示例关键逻辑:
const Build = plus.android.importClass('android.os.Build');
if (Build.VERSION.SDK_INT > 23) {
const NetworkInterface = plus.android.importClass('java.net.NetworkInterface');
let ni = NetworkInterface.getByName('wlan0');
if (!ni) ni = NetworkInterface.getByName('eth0');
if (ni) {
const macBytes = ni.getHardwareAddress();
if (macBytes) return macBytes.map(b => (b & 0xFF).toString(16).padStart(2, '0')).join(':');
}
}
别依赖MAC做设备唯一标识,它随时可能变
用户开关WiFi、重置网络设置、升级系统、甚至换SIM卡,都可能导致MAC值变化。iOS根本拿不到MAC,uni-app跨端项目若用MAC做登录绑定或设备锁,上线后必出问题。
- 真正稳定的方案是组合使用:
plus.device.uuid(首次生成后持久化) +plus.device.imei(需额外申请READ_PHONE_STATE,且Android 10+不可用) - 如果必须硬件级标识,建议用
plus.device.getDeviceInfo()里的sn(序列号),但部分厂商(如华为Nova系列)会返回"UNKNOWN" - 测试时务必在真机上验证:模拟器的
wlan0通常不存在,getByName直接返回null
权限配置和manifest.json容易漏掉的点
光在代码里申请运行时权限不够,manifest.json里没配对的uses-permission,Android系统连弹窗机会都不给你。
- 必须显式添加:
"android.permission.ACCESS_FINE_LOCATION"(获取MAC的强制前置) - 若想尝试读取蓝牙MAC,加:
"android.permission.BLUETOOTH"和"android.permission.BLUETOOTH_ADMIN" - targetSdkVersion ≥ 31(Android 12)时,还需声明
queries字段,否则BluetoothAdapter.getDefaultAdapter()返回null - 华为/荣耀设备需额外在
nativeplugins/android/config.xml中启用<feature name="NATIVE-BLE"></feature>才可能拿到蓝牙MAC
MAC地址现在不是“能不能拿到”的问题,而是“拿回来有没有用、值不值得为它加一堆兼容逻辑”的问题。真要设备指纹,优先考虑uuid存本地,再辅以device.model和systemVersion做哈希,比死磕MAC靠谱得多。










