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

3

15

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 Address (02:00:00:00:00:00) instead of the real value.

The normal way to get the Wifi MAC address is below:

final WifiManager wifiManager = (WifiManager) getApplication().getApplicationContext().getSystemService(Context.WIFI_SERVICE);

final String wifiMACaddress = wifiManager.getConnectionInfo().getMacAddress();
Minnie answered 9/7, 2015 at 22:59 Comment(4)
Stack Overflow is for programming questions. What is your question? If you are trying to provide some sort of FAQ entry, please follow the site instructions, and ask a question, then provide your own answer to that question.Phonetics
It seems that Mac Address is randomized even you can catch it! developer.android.com/about/versions/marshmallow/…Allsopp
Possible duplicate of Getting MAC address in Android 6.0Symer
I posted here working solution https://mcmap.net/q/11550/-programmatically-getting-the-mac-of-an-android-deviceAdversity
P
32

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

Planish answered 5/10, 2015 at 12:32 Comment(5)
what permission do you think we need for retrieving the networkInterface? and how does this approach diff from the official solution of Android developer.android.com/about/versions/marshmallow/…?Scarletscarlett
there isn't a solution. To access the hardware identifiers of -->nearby external devices<-- your app must now have the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permissions. I am not sure what permission is needed for retrieving networkInterfaces. But to access the smartphones WiFi-MAC-Address, this is the only way right now and it will be gone with one of the next versions of androidPlanish
It seems that Mac Address is randomized even you can catch it! developer.android.com/about/versions/marshmallow/…Allsopp
It works flawlessly +1 for that, Is it appropriate to use this method.. will it work in any sdk from 1 to upcoming sdkMowery
I would recommend to just use it from api-23 (Android M), for older versions I would use the normal way and from N you should check if it is still working.Planish
M
8

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"

Minnie answered 10/7, 2015 at 17:50 Comment(1)
It may need to be noted that on some devices this is read-protected, so you may need root.Incompliant
G
2

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;
}
Gouache answered 22/6, 2016 at 23:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.