63

How do i get Mac Id of android device programmatically. I have done with IMIE Code and I know how to check Mac id on device manually but have no idea how to find out programmatically.

Cœur
  • 37,241
  • 25
  • 195
  • 267
sami
  • 695
  • 2
  • 6
  • 11
  • I posted here working solution https://stackoverflow.com/a/47789324/5330408 – Android Developer Dec 13 '17 at 09:18
  • 1
    Does this answer your question? [Programmatically getting the MAC of an Android device](https://stackoverflow.com/questions/11705906/programmatically-getting-the-mac-of-an-android-device) – Mark Rotteveel Aug 27 '20 at 18:29

8 Answers8

132
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
String macAddress = wInfo.getMacAddress(); 

Also, add below permission in your manifest file

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

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.

Community
  • 1
  • 1
Raghu Nagaraju
  • 3,278
  • 1
  • 18
  • 25
  • 19
    You should also give the activity permission ACCESS_WIFI_STATE, otherwise it wont work. – Harry Mar 01 '13 at 13:25
  • 12
    Word of caution: This will not work if WiFi is disabled in the Settings – Ranhiru Jude Cooray Oct 17 '14 at 04:19
  • 4
    This used to work great, on my nexus 9 running marshmallow this returns 02:00:00:00:00:00 now. – AndyB Nov 03 '15 at 08:01
  • 3
    @AndyB http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id says that this method `WifiInfo.getMacAddress()` will return constant value, so to get mac address in Android M you amy use this answer http://stackoverflow.com/a/32948723/4308151 note that wifi must be on – Ahmed Mostafa Apr 02 '16 at 13:12
  • If you use this code as-is, you might get this error: The WIFI_SERVICE must be looked up on the Application context or memory will leak on devices < Android N. Try changing to .getApplicationContext() [WifiManagerLeak]. The following should work instead: WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); – David Airapetyan Jan 12 '18 at 18:35
  • What if I am using cellular data? – George Sp Aug 10 '19 at 18:05
21

See this post where I have submitted Utils.java example to provide pure-java implementations and works without WifiManager. Some android devices may not have wifi available or are using ethernet wiring.

Utils.getMACAddress("wlan0");
Utils.getMACAddress("eth0");
Utils.getIPAddress(true); // IPv4
Utils.getIPAddress(false); // IPv6 
Community
  • 1
  • 1
Whome
  • 10,181
  • 6
  • 53
  • 65
  • Some devices may have one or more ethernet ports (wired or wireless). This is just a linux jargon naming communication ports. Usuallay Android devices have only one wireless wlan0 port available. – Whome May 28 '13 at 12:22
  • how to see the name of device port – Zala Janaksinh May 28 '13 at 12:25
  • See source code in my post getMACAddress, it loops all network interfaces(device ports) you can print out names or do something else with them. http://stackoverflow.com/questions/6064510/how-to-get-ip-address-of-the-device/13007325#13007325 – Whome May 30 '13 at 13:54
  • Does this require some external libs? – hackjutsu Oct 29 '15 at 19:15
  • @Hackjustu: This does not require any external libs, altought my original answer is using InetAddressUtils.isIPv4Address(sAddr) function, it was removed from Android SDK. Instead should use `isIPv4=sAddr.indexOf(':')<0` trick. – Whome Nov 02 '15 at 11:59
  • @Whome, when my phone is connected to 4G data, gives null for "wlan0", "eth0" using Utils.getMACAddress("networkInterface")? Is there different networkInterface for 4G or 3G mobile data connection? – Prashant Mar 19 '18 at 06:27
  • @pcj Devices may use any interface name they want so I suggest you debug printout all the interfaces. See `getMACAddress()` how interfaces are looped. What happens if you call `getMACAddress(null)`? – Whome Mar 19 '18 at 13:44
  • @Whome I get following the list of interface name-mac pairs, ip6tnl0-NA, tunl0-NA, wlan0-{VALID_MAC} I am not pasting the mac for security reasons, I have question irrespective of interface MAC is unique for all interfaces or is it unique per interface? Most of the times I am getting MAC using wlan0 interface but some times it returns empty string ( This has observed when 4G data is connected ). MacUtils.getMACAddress(null) also given empty string. Is there any way I will get MAC address always? – Prashant Mar 20 '18 at 06:14
11

With this code you will be also able to get MacAddress in Android 6.0 also

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) + ":");
                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";
}

EDIT 1. 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 has been changed to take care of it.

André
  • 4,417
  • 4
  • 29
  • 56
Arth Tilva
  • 2,496
  • 22
  • 40
8

It's Working

    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) + ":");
                        res1.append(String.format("%02X:",b)); 
                    }
    
                    if (res1.length() > 0) {
                        res1.deleteCharAt(res1.length() - 1);
                    }
                    return res1.toString();
                }
            } catch (Exception ex) {
                //handle exception
            }
            return "";
        }
    }

UPDATE 1

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 has been changed to take care of it.

 StringBuilder res1 = new StringBuilder();
                for (byte b : macBytes) {
                    // res1.append(Integer.toHexString(b & 0xFF) + ":");
                    res1.append(String.format("%02X:",b)); 
                }
Community
  • 1
  • 1
Keshav Gera
  • 10,807
  • 1
  • 75
  • 53
6

Recent update from Developer.Android.com

Don't work with MAC addresses MAC addresses are globally unique, not user-resettable, and survive factory resets. For these reasons, it's generally not recommended to use MAC address for any form of user identification. Devices running Android 10 (API level 29) and higher report randomized MAC addresses to all apps that aren't device owner apps.

Between Android 6.0 (API level 23) and Android 9 (API level 28), local device MAC addresses, such as Wi-Fi and Bluetooth, aren't available via third-party APIs. The WifiInfo.getMacAddress() method and the BluetoothAdapter.getDefaultAdapter().getAddress() method both return 02:00:00:00:00:00.

Additionally, between Android 6.0 and Android 9, you must hold the following permissions to access MAC addresses of nearby external devices available via Bluetooth and Wi-Fi scans:

Method/Property Permissions Required

ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION

Source: https://developer.android.com/training/articles/user-data-ids.html#version_specific_details_identifiers_in_m

Community
  • 1
  • 1
hushed_voice
  • 3,161
  • 3
  • 34
  • 66
4

Here the Kotlin version of Arth Tilvas answer:

fun getMacAddr(): String {
    try {
        val all = Collections.list(NetworkInterface.getNetworkInterfaces())
        for (nif in all) {
            if (!nif.getName().equals("wlan0", ignoreCase=true)) continue

            val macBytes = nif.getHardwareAddress() ?: return ""

            val res1 = StringBuilder()
            for (b in 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 (ex: Exception) {
    }

    return "02:00:00:00:00:00"
}
Kevin Müller
  • 722
  • 6
  • 18
3
private fun getMac(): String? =
        try {
            NetworkInterface.getNetworkInterfaces()
                    .toList()
                    .find { networkInterface -> networkInterface.name.equals("wlan0", ignoreCase = true) }
                    ?.hardwareAddress
                    ?.joinToString(separator = ":") { byte -> "%02X".format(byte) }
        } catch (ex: Exception) {
            ex.printStackTrace()
            null
        }
Victor Raft
  • 41
  • 1
  • 4
-1

There is a simple way:

Android:

   String macAddress = 
android.provider.Settings.Secure.getString(this.getApplicationContext().getContentResolver(), "android_id");

Xamarin:

    Settings.Secure.GetString(this.ContentResolver, "android_id");