You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 06:34:58