Getting MAC address in Android 6.0
Asked Answered
S

11

42

I'm developing an app that gets the MAC address of the device, but since Android 6.0 my code doesn't work, giving me an incorrect value.

Here's my code...

public String ObtenMAC()
{
    WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    WifiInfo info = manager.getConnectionInfo();

    return(info.getMacAddress().toUpperCase());
}

Instead of the real MAC address, it returns an strange code: 02:00:00:00:00:00.

Swagerty answered 15/10, 2015 at 21:59 Comment(5)
Did you made sure that you checked for the ACCESS_WIFI_STATE before getting the MAC-Address? In M it won't work if you only ask for it in the Manifest you have to implemet it in rumtime like that: youtube.com/…Phene
Thanks for the answer. I have that permission in my Manifest, but when I go to check it programatically as shown in the video, Android Studio doesn't recognize "checkSelfPermission", I don't know if could be because I`m targeting API 21 Lollipop and hasn't installed API 23 Marshmallow.Swagerty
Before you call checkSelfPermission you should check if the SDK Version is lass than API 23 Marshmallow like here: #3424254Phene
It is always good to have the newest Android API version at the target levelPhene
Please check this solution, it works for me #31330233Zeculon
A
35

Please refer to Android 6.0 Changes.

To provide users with greater data protection, starting in this release, Android removes programmatic access to the device’s local hardware identifier for apps using the Wi-Fi and Bluetooth APIs. The WifiInfo.getMacAddress() and the BluetoothAdapter.getAddress() methods now return a constant value of 02:00:00:00:00:00.

To access the hardware identifiers of nearby external devices via Bluetooth and Wi-Fi scans, your app must now have the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permissions.

Avocet answered 16/10, 2015 at 8:31 Comment(4)
I have those permissions on my app and still doesn't work.Slogan
@Hrodger, you can't get your own MACs even having those permissions. Read carefully. It is said that you can get other devices MACs having those permissions, but not yourthManageable
So there is no way to do it?Slogan
You can still get mac address through java.net.NetworkInterface apparently. Yes, I'm of very high opinion about Google developers abilities;).Deadhead
T
27

Use below code to get Mac address in Android 6.0

public static String getMacAddr() {
    try {
        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) + ":");
            }

            if (res1.length() > 0) {
                res1.deleteCharAt(res1.length() - 1);
            }
            return res1.toString();
        }
    } catch (Exception ex) {
        //handle exception
    }
    return "";
}
Tallinn answered 25/8, 2016 at 11:39 Comment(4)
The above answer was taken from this blog post: robinhenniges.com/en/android6-get-mac-address-programmaticallyMascarenas
This answer got a bug where a byte that in hex form got a single digit, will not appear with a "0" before it. The append to res1 should be changed to res1.append(String.format("%02X:",b));Badajoz
Works in Android 7 as well.Oberon
WiFi MAC address is not always the same as Bluetooth interface. On my phone only first 3 octaves matches (which btw inform about vendor).Divulsion
B
15

I didn't get the above answer to work, but stumbled upon another answer.

Here is a complete and simple method on getting the IPv6 address and then getting the mac address from it.

How to get Wi-Fi Mac address in Android Marshmallow

public static String getMacAddr() {
    try {
        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) {
    }
    return "02:00:00:00:00:00";
}

Tested it already and it works. Many thanks to Rob Anderson!

Benzo answered 24/8, 2016 at 17:44 Comment(1)
Thanks, as stated elsewhere this needs <uses-permission android:name="android.permission.INTERNET" /> to work.Disruptive
G
11

this is the complete 2 ways code of getting it successfully on Marshmallow , just copy past this and it will work !

//Android 6.0 : Access to mac address from WifiManager forbidden
    private static final String marshmallowMacAddress = "02:00:00:00:00:00";
    private static final String fileAddressMac = "/sys/class/net/wlan0/address";    

public static String recupAdresseMAC(WifiManager wifiMan) {
        WifiInfo wifiInf = wifiMan.getConnectionInfo();

        if(wifiInf.getMacAddress().equals(marshmallowMacAddress)){
            String ret = null;
            try {
                ret= getAdressMacByInterface();
                if (ret != null){
                    return ret;
                } else {
                    ret = getAddressMacByFile(wifiMan);
                    return ret;
                }
            } catch (IOException e) {
                Log.e("MobileAccess", "Erreur lecture propriete Adresse MAC");
            } catch (Exception e) {
                Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
            }
        } else{
            return wifiInf.getMacAddress();
        }
        return marshmallowMacAddress;
    }

private static String getAdressMacByInterface(){
        try {
            List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface nif : all) {
                if (nif.getName().equalsIgnoreCase("wlan0")) {
                    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 e) {
            Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
        }
        return null;
    }

private static String getAddressMacByFile(WifiManager wifiMan) throws Exception {
        String ret;
        int wifiState = wifiMan.getWifiState();

        wifiMan.setWifiEnabled(true);
        File fl = new File(fileAddressMac);
        FileInputStream fin = new FileInputStream(fl);
        StringBuilder builder = new StringBuilder();
    int ch;
    while((ch = fin.read()) != -1){
        builder.append((char)ch);
    }

    ret = builder.toString();
    fin.close();

        boolean enabled = WifiManager.WIFI_STATE_ENABLED == wifiState;
        wifiMan.setWifiEnabled(enabled);
        return ret;
    }

manifest :

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
  • Summary : this code will try to get the MAC address first by Interface and if its failed it get it by file system.

  • Note:for file System way, you need to enable WIFI to access the file.

thnx to Sam's answer here https://mcmap.net/q/11128/-getting-mac-address-in-android-6-0

Glaring answered 14/12, 2016 at 12:43 Comment(0)
D
6

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;
}
Dilute answered 22/6, 2016 at 22:58 Comment(5)
It seems that Mac Address is randomized even you can catch it! developer.android.com/about/versions/marshmallow/…Radiology
The WifiManager API was changed in Android 6.0 to return a fake MAC address. But you can still get the IPv6 link local address for the Wi-Fi network and then extract the MAC address as above. This works on every device I have tried.Dilute
Hi @Yojimbo, will this code return the MAC address of the router, or that of the device?Unwatched
This is the WiFi MAC address of the device. You may be able to get the MAC of the WiFi access point using WiFiManager.getScanResults(). For a WAP, the BSSID equals the MAC address.Dilute
You can enumerate the network interfaces using NetworkInterface. See this SO question for an example. Use the Java instanceof operator to determine which IP addresses are Inet6AddressDilute
A
5

I try to get mac address with 2 methods, first by Interface and if its failed, i get it by file system, but you need to enable wifi to access the file.

//Android 6.0 : Access to mac address from WifiManager forbidden
    private static final String marshmallowMacAddress = "02:00:00:00:00:00";
    private static final String fileAddressMac = "/sys/class/net/wlan0/address";    

public static String recupAdresseMAC(WifiManager wifiMan) {
        WifiInfo wifiInf = wifiMan.getConnectionInfo();

        if(wifiInf.getMacAddress().equals(marshmallowMacAddress)){
            String ret = null;
            try {
                ret= getAdressMacByInterface();
                if (ret != null){
                    return ret;
                } else {
                    ret = getAddressMacByFile(wifiMan);
                    return ret;
                }
            } catch (IOException e) {
                Log.e("MobileAccess", "Erreur lecture propriete Adresse MAC");
            } catch (Exception e) {
                Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
            }
        } else{
            return wifiInf.getMacAddress();
        }
        return marshmallowMacAddress;
    }

private static String getAdressMacByInterface(){
        try {
            List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface nif : all) {
                if (nif.getName().equalsIgnoreCase("wlan0")) {
                    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 e) {
            Log.e("MobileAcces", "Erreur lecture propriete Adresse MAC ");
        }
        return null;
    }

private static String getAddressMacByFile(WifiManager wifiMan) throws Exception {
        String ret;
        int wifiState = wifiMan.getWifiState();

        wifiMan.setWifiEnabled(true);
        File fl = new File(fileAddressMac);
        FileInputStream fin = new FileInputStream(fl);
        ret = convertStreamToString(fin);
        fin.close();

        boolean enabled = WifiManager.WIFI_STATE_ENABLED == wifiState;
        wifiMan.setWifiEnabled(enabled);
        return ret;
    }

Add this line to your manifest.

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

I recommend you to persist your mac address in your preferences like here

mac = activity.getSharedPreferences("MAC_ADDRESS", Context.MODE_PRIVATE).getString("MAC_ADDRESS", "");
                if(mac == null || mac.equals("")){
                    WifiManager wifiMan = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);
                    mac = MobileAccess.recupAdresseMAC(wifiMan);
                    if(mac != null && !mac.equals("")){
                        SharedPreferences.Editor editor = activity.getSharedPreferences("MAC_ADDRESS", Context.MODE_PRIVATE).edit();
                        editor.putString("MAC_ADDRESS", mac).commit();
                    }
                }
Alleviative answered 2/9, 2016 at 9:22 Comment(0)
D
5

Its Perfectly Fine

package com.keshav.fetchmacaddress;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.e("keshav","getMacAddr -> " +getMacAddr());
    }

    public static String getMacAddr() {
        try {
            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) + ":");
                }

                if (res1.length() > 0) {
                    res1.deleteCharAt(res1.length() - 1);
                }
                return res1.toString();
            }
        } catch (Exception ex) {
            //handle exception
        }
        return "";
    }
}
Dagoba answered 15/6, 2017 at 12:13 Comment(2)
Welcome zums for like meDagoba
With Android 12 it wont't work. developer.android.com/about/versions/12/…Cuff
P
1

First you need to add Internet user permission.

<uses-permission android:name="android.permission.INTERNET" />

Then you can find the mac over the NetworkInterfaces API.

public static String getMacAddr() {
    try {
        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) {
    }
    return "02:00:00:00:00:00";
}
Particle answered 26/9, 2016 at 10:43 Comment(1)
The above answer was taken from this blog post: robinhenniges.com/en/android6-get-mac-address-programmaticallyMascarenas
F
1

The answers are mostly correct, but keep care, that there is a change in android 7. You will need to use the

DevicePolicyManager and the Method getWifiMacAddress. The official docs has a typo, which means that you shouldnt copy/paste it from there.

DevicePolicyManager.getWifiMacAddress()

Refs: https://developer.android.com/about/versions/nougat/android-7.0-changes.html

Get Device mac adress in Android Nougat and O programmatically

Fixing answered 11/4, 2017 at 8:15 Comment(0)
K
1

Use wifiInfo.getBSSID() to get Mac Address of AccessPoint instead of getMacAddress method.

Konstanze answered 22/3, 2020 at 16:38 Comment(1)
Only provides the mac address of the device your connected to like a wifi router. Not the device itselfOeo
E
0

This is a more kotlin way to get Mac Address

fun getMacAddress(): String =
        NetworkInterface.getNetworkInterfaces().toList()
                .firstOrNull { it.name.equals("wlan0", ignoreCase = true) }?.let {
                    it.hardwareAddress?.let { macBytes ->
                        StringBuilder().apply {
                            for (b in macBytes) {
                                append(String.format("%02X:", b))
                            }
                            if (isNotEmpty()) {
                                deleteCharAt(lastIndex)
                            }
                        }
                    }.toString()
                } ?: "02:00:00:00:00:00"
Encrust answered 25/3, 2021 at 20:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.