Target SDK为29的Android应用在Android13无法获取真实WiFi MAC地址
Android 13下无法获取WiFi真实MAC地址的解决方案
问题背景
应用的Target SDK和Compile SDK均为29,在Android 10、11、12系统中能正常获取WiFi真实MAC地址,但在Android 13系统中只能拿到默认的02:00:00:00:00:00,无法获取真实地址。
相关代码配置
Build.gradle 文件
plugins { id("com.android.application") } android { namespace = "com.mantra.wifimacaddress" compileSdk = 29 defaultConfig { applicationId = "com.mantra.wifimacaddress" minSdk = 24 targetSdk = 29 versionCode = 1 versionName = "1.0" multiDexEnabled = true } buildTypes { release { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } } dependencies { implementation("androidx.appcompat:appcompat:1.1.0") implementation("com.google.android.material:material:1.2.1") implementation("androidx.constraintlayout:constraintlayout:1.1.3") implementation("com.karumi:dexter:6.2.3") }
获取MAC地址代码
public String getMacAddr() { try { WifiManager wifiManager = (WifiManager) MainActivity.this.getSystemService(Context.WIFI_SERVICE); WifiInfo info = wifiManager.getConnectionInfo(); String ssid = info.getSSID(); String bssid = info.getBSSID(); System.out.println("Get SSID ====> " + ssid + " Get BSSID====> " + bssid); List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces()); for (NetworkInterface nif : all) { if (!nif.getName().equalsIgnoreCase("wlan0")) continue; byte[] macBytes = nif.getHardwareAddress(); if (macBytes == null) { return ""; } StringBuilder res1 = new StringBuilder(); for (byte b : macBytes) { // res1.append(Integer.toHexString(b & 0xFF) + ":"); res1.append(String.format("%02X:", b)); } if (res1.length() > 0) { res1.deleteCharAt(res1.length() - 1); } return res1.toString(); } } catch (Exception ex) { ex.printStackTrace(); } return "02:00:00:00:00:00"; }
问题原因
Android 13(API 33)强化了隐私保护规则,无论应用的Target SDK版本是多少,系统都会禁止应用获取自身WiFi的真实MAC地址,强制返回默认占位地址。这是Google为防止应用通过MAC地址追踪用户而推出的限制,和Target SDK 29的兼容性无关。
解决方案
1. 改用合规的设备标识替代
如果你的需求是设备唯一标识,完全没必要纠结MAC地址,以下两种方案更稳定合规:
- ANDROID_ID:Android 8.0+版本中,同一设备同一用户下,
ANDROID_ID是稳定的字符串,恢复出厂设置会重置。代码示例:String androidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID); - 自定义UUID:首次启动应用时生成一个UUID,存储在
SharedPreferences或本地文件中,作为设备标识,不受系统版本限制。代码示例:private String getCustomDeviceId() { SharedPreferences sp = getSharedPreferences("device_info", MODE_PRIVATE); String uuid = sp.getString("device_uuid", null); if (uuid == null) { uuid = UUID.randomUUID().toString(); sp.edit().putString("device_uuid", uuid).apply(); } return uuid; }
2. 调整现有MAC地址获取逻辑
针对Android 13做特殊处理,避免无效的获取尝试,直接返回替代标识或占位地址:
修改后的getMacAddr()方法:
public String getMacAddr() { // Android 13及以上直接返回替代标识或占位地址 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { return getCustomDeviceId(); // 或者返回"02:00:00:00:00:00" } try { WifiManager wifiManager = (WifiManager) MainActivity.this.getSystemService(Context.WIFI_SERVICE); WifiInfo info = wifiManager.getConnectionInfo(); String ssid = info.getSSID(); String bssid = info.getBSSID(); System.out.println("Get SSID ====> " + ssid + " Get BSSID====> " + bssid); List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces()); for (NetworkInterface nif : all) { if (!nif.getName().equalsIgnoreCase("wlan0")) continue; byte[] macBytes = nif.getHardwareAddress(); if (macBytes == null) { return ""; } StringBuilder res1 = new StringBuilder(); for (byte b : macBytes) { res1.append(String.format("%02X:", b)); } if (res1.length() > 0) { res1.deleteCharAt(res1.length() - 1); } return res1.toString(); } } catch (Exception ex) { ex.printStackTrace(); } return "02:00:00:00:00:00"; } private String getCustomDeviceId() { SharedPreferences sp = getSharedPreferences("device_info", MODE_PRIVATE); String uuid = sp.getString("device_uuid", null); if (uuid == null) { uuid = UUID.randomUUID().toString(); sp.edit().putString("device_uuid", uuid).apply(); } return uuid; }
3. 局域网场景的特殊处理
如果是需要在局域网内识别设备(比如设备间通信),可以考虑让设备通过局域网广播或多播的方式交换标识,但无法直接获取真实MAC地址。
关键注意点
- 不要尝试绕过Android 13的MAC地址限制,这是系统级的隐私保护措施,所有应用都必须遵守。
- 升级Target SDK到33也无法解决这个问题,规则是强制执行的。
内容的提问来源于stack exchange,提问作者prakash joshi
相关产品推荐
相关产品推荐

