You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android Studio中手机MAC与蓝牙地址均不可用时的读取方法咨询

How to Retrieve MAC Address When Both WiFi and Bluetooth Addresses Are Unavailable on Android

Hey there! Let’s dig into this MAC address problem you’re hitting on Android. First, it’s important to understand why this is happening: starting from Android 6.0 (API 23), Google restricted access to WiFi MAC addresses (you’ll get the dummy value 02:00:00:00:00:00 instead of the real one), and Android 10+ added similar restrictions for Bluetooth addresses—unless your app is a system-level application with special permissions.

Here are the practical solutions you can try, depending on your app’s use case:

1. Check for System-Level App Privileges

If your app is signed with the system signature (e.g., pre-installed by the device manufacturer), you can use the android.permission.LOCAL_MAC_ADDRESS permission. This allows you to bypass the standard restrictions and retrieve real MAC addresses for both WiFi and Bluetooth interfaces.

Note: This permission is not available to regular third-party apps—it’s reserved for system applications only.

2. Read MAC Address from System Files (Limited Compatibility)

For regular apps, you can attempt to read the MAC address directly from the device’s sysfs filesystem. This works on older Android versions (pre-11) and some devices with looser restrictions, but it’s not guaranteed to work across all models or newer OS versions.

Here’s a code snippet to try this approach:

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

private String getMacFromSysfs() {
    try {
        // Get all network interfaces except the loopback interface
        File netDir = new File("/sys/class/net/");
        if (!netDir.exists()) return null;

        File[] interfaceFiles = netDir.listFiles();
        if (interfaceFiles == null) return null;

        List<String> validInterfaces = new ArrayList<>();
        for (File file : interfaceFiles) {
            if (!file.getName().equals("lo")) {
                validInterfaces.add(file.getName());
            }
        }

        // Read the address file for each interface
        for (String iface : validInterfaces) {
            File addressFile = new File("/sys/class/net/" + iface + "/address");
            if (!addressFile.exists()) continue;

            String mac = new String(Files.readAllBytes(addressFile.toPath())).trim();
            // Skip the dummy MAC address
            if (!mac.equals("02:00:00:00:00:00")) {
                return mac;
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

Important caveats: Android 11+ restricts access to sysfs paths for third-party apps, so this method may fail on newer devices. Also, interface names (like wlan0 or eth0) can vary between manufacturers.

3. Use Alternative Unique Identifiers

If you can’t retrieve the real MAC address (which is increasingly common on modern Android), consider using a substitute unique identifier that fits your use case:

  • Android ID: Retrieve it using Settings.Secure.ANDROID_ID. On Android 8.0+, this ID is unique per app and user profile, and resets if the device is factory reset.
    import android.content.Context;
    import android.provider.Settings;
    
    private String getAndroidId(Context context) {
        return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
    }
    
  • Custom Persistent UUID: Generate a random UUID on first app launch and store it in SharedPreferences. This stays consistent across app updates and device reboots (unless the app is uninstalled).
    import android.content.Context;
    import android.preference.PreferenceManager;
    import java.util.UUID;
    
    private String getPersistentUniqueId(Context context) {
        String uuid = PreferenceManager.getDefaultSharedPreferences(context)
                .getString("persistent_device_id", null);
        if (uuid == null) {
            uuid = UUID.randomUUID().toString();
            PreferenceManager.getDefaultSharedPreferences(context)
                    .edit()
                    .putString("persistent_device_id", uuid)
                    .apply();
        }
        return uuid;
    }
    
  • Advertising ID: If your use case is related to advertising or analytics, you can use the Advertising ID. Users can reset this ID at any time, so it’s not suitable for device tracking.

4. Verify Required Permissions

Even though permissions won’t bypass the MAC restrictions on newer Android versions, make sure you’ve declared the necessary permissions in your AndroidManifest.xml to cover older devices:

<!-- For WiFi MAC access (pre-API 23) -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- For Bluetooth MAC access (pre-API 31) -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- For Bluetooth access on Android 12+ -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

Final Notes

For most third-party apps targeting modern Android versions, retrieving the real MAC address is no longer feasible due to privacy restrictions. Your best bet is to switch to one of the alternative unique identifiers mentioned above.

内容的提问来源于stack exchange,提问作者rezaj633

火山引擎 最新活动