以编程方式获取Android设备的MAC地址

106

我需要使用Java获取我的Android设备的MAC地址。我已经在网上搜索过,但没有找到有用的信息。


1
http://programminglinuxblog.blogspot.pt/2011/06/mac-address-string-to-byte.html - Ismael
3
可能是如何获取WiFi网络接口的MAC地址?的重复问题。 - A.H.
1
可能是重复的问题:如何以编程方式查找Android设备的MAC地址 - Pang
请检查这个解决方案,它对我有效。https://dev59.com/1l0Z5IYBdhLWcg3wiw0v - Gorio
从Android M开始,此API已被弃用,请暂时使用以下链接:https://dev59.com/1l0Z5IYBdhLWcg3wiw0v - Ehud
这个命令 ip link | grep -A1 wlan0 可以在 Android 9 上运行,来源于 https://stackoverflow.com/questions/58463658/how-to-determine-wifi-hardware-address-in-termux。 - S D Rausty
14个回答

124

正如评论中已经指出的那样,可以通过WifiManager获取MAC地址。

WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = manager.getConnectionInfo();
String address = info.getMacAddress();

还要别忘了在你的AndroidManifest.xml中添加适当的权限。

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
请参考Android 6.0 更改。为了提供更高的数据保护性,在此版本中,Android 删除了使用 Wi-Fi 和 Bluetooth API 的应用对设备本地硬件标识符的编程访问。现在,WifiInfo.getMacAddress() 和 BluetoothAdapter.getAddress() 方法返回一个固定值 02:00:00:00:00:00。要通过蓝牙和 Wi-Fi 扫描访问附近外部设备的硬件标识符,您的应用现在必须具有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 权限。

12
请注意,有时候设备的Wi-Fi关闭,因此无法获取MAC地址。 - sbrichards
3
这篇博客还解释了如何以一种更普遍的方式找到MAC地址,而不是假定网络接口使用WiFi连接的方式。 - Stephen C
记住使用上下文来调用getSystemService。 - Tito Leiva
这对于使用Wifi的Android手机和平板电脑非常好,但我正在尝试获取一个旧的Gingerbread Android平板电脑上的以太网MAC地址,该平板电脑可以使用Wifi或以太网。有没有关于如何检查以太网MAC地址的想法?谢谢。 - Seth
@sbrichards,您所说的WiFi关闭是什么意思? - Peter Chaula
它已经不能使用了! - Wahaj Mubeen

43

4
替代方案是什么? - Sam
2
@SameerThigale 这取决于你想实现什么目标。这背后的想法是你可能不应该尝试获取MAC地址。 - minipif
我不确定为什么,在链接的 API 文档中找不到弃用注释。也许他们改变了主意? - DBX12
1
@DBX12 这个方法本身没有被标记为过时,尽管它没有被文档化。第二个链接指向了一个官方的关于它的说明。 - minipif

30
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";
}

3
在Android 7.1上,它一直显示给我“02:00:00:00:00:00”。 - android developer
这种解决方法是否仍然有效?或者操作系统方面已经修补了它? - CasualT
1
它仍然可以工作。不要忘记在清单文件中授予网络权限。 - pm dubey
2
它在Android Marshmallow及以上版本上不再起作用,因为它将返回“02:00:00:00:00:00”的值。 - Hiraeths
2
它可以运行。我已经使用这段代码很长时间了。它仍然可以在Android Q上运行。 - Rupam Das
显示剩余2条评论

17

我从http://robinhenniges.com/en/android6-get-mac-address-programmatically找到了这个解决方案,它对我很有效!希望能帮助到你!

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) {
                String hex = Integer.toHexString(b & 0xFF);
                if (hex.length() == 1)
                    hex = "0".concat(hex);
                res1.append(hex.concat(":"));
            }

            if (res1.length() > 0) {
                res1.deleteCharAt(res1.length() - 1);
            }
            return res1.toString();
        }
    } catch (Exception ex) {
    }
    return "";
}

我猜测这是因为我们需要删除最后一个“:”字符。这段代码已经两年了,可能不是做这件事情的最佳方式,你应该优化它。 - Tiziano Bruschetta

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

public String getMacAddress(Context context) {
    WifiManager wimanager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    String macAddress = wimanager.getConnectionInfo().getMacAddress();
    if (macAddress == null) {
        macAddress = "Device don't have mac address or wi-fi is disabled";
    }
    return macAddress;
}

有其他方法这里


macAddress会是null吗? - Max Heiber
在函数调用时需要传递哪个参数作为上下文? - Donal
@Donal 你是指 Context context 吗?如果是的话,任何上下文都可以使用。https://developer.android.com/reference/android/content/Context.html#WIFI_SERVICE - ademar111190

9

它能够与Marshmallow操作系统兼容

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 "";
    }
}

5

你现在无法获取安卓设备的硬件MAC地址。WifiInfo.getMacAddress() 和 BluetoothAdapter.getAddress() 方法将返回 02:00:00:00:00:00。这个限制是在Android 6.0中引入的。

但Rob Anderson找到了一个适用于< Marshmallow的解决方案:https://dev59.com/0lwY5IYBdhLWcg3wCD6W#35830358


3
使用这种简单的方法
WifiManager wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            String WLANMAC = wm.getConnectionInfo().getMacAddress();

3

您可以获取Mac地址:

WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
String mac = wInfo.getMacAddress();

在Manifest.xml文件中设置权限

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

问题是关于获取安卓设备的 MAC 地址,而不是 WiFi 路由器的。 - hina abbasi

2

这段代码来自Android源代码 这里。这是在系统设置应用程序中显示您的MAC地址的实际代码。

private void refreshWifiInfo() {
    WifiInfo wifiInfo = mWifiManager.getConnectionInfo();

    Preference wifiMacAddressPref = findPreference(KEY_MAC_ADDRESS);
    String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
    wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress
            : getActivity().getString(R.string.status_unavailable));

    Preference wifiIpAddressPref = findPreference(KEY_CURRENT_IP_ADDRESS);
    String ipAddress = Utils.getWifiIpAddresses(getActivity());
    wifiIpAddressPref.setSummary(ipAddress == null ?
            getActivity().getString(R.string.status_unavailable) : ipAddress);
}

我应该如何在非活动类或片段中访问它? - Hunt
你需要一个上下文来获取WifiManager(例如:WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);)。 - fernandohur
5
当我尝试运行这段代码时,返回的MAC地址是02:00:00:00:00:00,而不是实际的WiFi MAC地址。 - Hunt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接