How to get the missing Wifi MAC Address in Android Marshmallow and later?

后端 未结 3 1883
清酒与你
清酒与你 2020-12-05 11:23

Android developers looking to get the Wifi MAC Address on Android M may have experienced an issue where the standard Android OS API to get the MAC Address returns a fake MAC

相关标签:
3条回答
  • 2020-12-05 11:53

    Resolved!

    The MAC Address can still be grabbed from the path:

    "/sys/class/net/" + networkInterfaceName + "/address";
    

    Simply doing a file read, or a cat of that file will show the Wifi MAC Address.

    Network interface names are usually along the lines of "wlan0" or "eth1"

    0 讨论(0)
  • 2020-12-05 12:03

    In Android M the MACAddress will be "unreadable" for WiFi and Bluetooth. You can get the WiFi MACAddress with (Android M Preview 2):

    public static String getWifiMacAddress() {
        try {
            String interfaceName = "wlan0";
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface intf : interfaces) {
                if (!intf.getName().equalsIgnoreCase(interfaceName)){
                    continue;
                }
    
                byte[] mac = intf.getHardwareAddress();
                if (mac==null){
                    return "";
                }
    
                StringBuilder buf = new StringBuilder();
                for (byte aMac : mac) {
                    buf.append(String.format("%02X:", aMac));
                }
                if (buf.length()>0) {
                    buf.deleteCharAt(buf.length() - 1);
                }
                return buf.toString();
            }
        } catch (Exception ex) { } // for now eat exceptions
        return "";
    }
    

    (got this code from this Post)

    Somehow I heared that reading the File from "/sys/class/net/" + networkInterfaceName + "/address"; will not work since Android N will be released and also there can be differences between the different manufacturers like Samsung etc.

    Hopefully this code will still work in later Android versions.

    EDIT: Also in Android 6 release this works

    0 讨论(0)
  • 2020-12-05 12:05

    You can get the MAC address from the IPv6 local address. E.g., the IPv6 address "fe80::1034:56ff:fe78:9abc" corresponds to the MAC address "12-34-56-78-9a-bc". See the code below. Getting the WiFi IPv6 address only requires android.permission.INTERNET.

    See the Wikipedia page IPv6 Address, particularly the note about "local addresses" fe80::/64 and the section about "Modified EUI-64".

    /**
     * Gets an EUI-48 MAC address from an IPv6 link-local address.
     * E.g., the IPv6 address "fe80::1034:56ff:fe78:9abc"
     * corresponds to the MAC address "12-34-56-78-9a-bc".
     * <p/>
     * See the note about "local addresses" fe80::/64 and the section about "Modified EUI-64" in
     * the Wikipedia article "IPv6 address" at https://en.wikipedia.org/wiki/IPv6_address
     *
     * @param ipv6 An Inet6Address object.
     * @return The EUI-48 MAC address as a byte array, null on error.
     */
    private static byte[] getMacAddressFromIpv6(final Inet6Address ipv6)
    {
        byte[] eui48mac = null;
    
        if (ipv6 != null) {
            /*
             * Make sure that this is an fe80::/64 link-local address.
             */
            final byte[] ipv6Bytes = ipv6.getAddress();
            if ((ipv6Bytes != null) &&
                    (ipv6Bytes.length == 16) &&
                    (ipv6Bytes[0] == (byte) 0xfe) &&
                    (ipv6Bytes[1] == (byte) 0x80) &&
                    (ipv6Bytes[11] == (byte) 0xff) &&
                    (ipv6Bytes[12] == (byte) 0xfe)) {
                /*
                 * Allocate a byte array for storing the EUI-48 MAC address, then fill it
                 * from the appropriate bytes of the IPv6 address. Invert the 7th bit
                 * of the first byte and discard the "ff:fe" portion of the modified
                 * EUI-64 MAC address.
                 */
                eui48mac = new byte[6];
                eui48mac[0] = (byte) (ipv6Bytes[8] ^ 0x2);
                eui48mac[1] = ipv6Bytes[9];
                eui48mac[2] = ipv6Bytes[10];
                eui48mac[3] = ipv6Bytes[13];
                eui48mac[4] = ipv6Bytes[14];
                eui48mac[5] = ipv6Bytes[15];
            }
        }
    
        return eui48mac;
    }
    
    0 讨论(0)
提交回复
热议问题