如何以编程方式查找 Android 设备的 MAC 地址

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10831578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:08:42  来源:igfitidea点击:

How to find MAC address of an Android device programmatically

android

提问by sami

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.

如何以编程方式获取 android 设备的 Mac Id。我已经完成了 IMIE 代码,我知道如何手动检查设备上的 Mac id,但不知道如何以编程方式找出。

回答by Raghu Nagaraju

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.

请参阅Android 6.0 变更

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.

为了向用户提供更好的数据保护,从本版本开始,Android 删除了使用 Wi-Fi 和蓝牙 API 的应用程序对设备本地硬件标识符的编程访问。WifiInfo.getMacAddress() 和 BluetoothAdapter.getAddress() 方法现在返回一个常量值 02:00:00:00:00:00。

要通过蓝牙和 Wi-Fi 扫描访问附近外部设备的硬件标识符,您的应用现在必须具有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 权限。

回答by Whome

See this postwhere 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.java 示例以提供纯 Java 实现并且无需 WifiManager 即可工作。某些 android 设备可能没有可用的 wifi 或正在使用以太网接线。

Utils.getMACAddress("wlan0");
Utils.getMACAddress("eth0");
Utils.getIPAddress(true); // IPv4
Utils.getIPAddress(false); // IPv6 

回答by Arth Tilva

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

使用此代码,您还可以在Android 6.0 中获取 MacAddress

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.

编辑 1.这个答案有一个错误,即十六进制形式的字节只有一个数字,在它之前不会出现“0”。附加到 res1 已更改以处理它。

回答by Keshav Gera

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

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

这个答案有一个错误,即十六进制形式的字节只有一个数字,在它之前不会出现“0”。附加到res1已更改以处理它。

 StringBuilder res1 = new StringBuilder();
                for (byte b : macBytes) {
                    // res1.append(Integer.toHexString(b & 0xFF) + ":");
                    res1.append(String.format("%02X:",b)); 
                }

回答by Kevin Müller

Here the Kotlin version of Arth Tilvas answer:

这里是 Arth Tilvas 的 Kotlin 版本的回答:

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

回答by Victor Raft

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
        }

回答by hushed_voice

Recent update from Developer.Android.com

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

不使用 MAC 地址 MAC 地址是全球唯一的,用户不可重置,并且在恢复出厂设置后仍然有效。出于这些原因,通常不建议将 MAC 地址用于任何形式的用户识别。运行 Android 10(API 级别 29)及更高版本的设备向所有不是设备所有者应用的应用报告随机 MAC 地址。

在 Android 6.0(API 级别 23)和 Android 9(API 级别 28)之间,本地设备 MAC 地址(例如 Wi-Fi 和蓝牙)无法通过第三方 API 获得。WifiInfo.getMacAddress() 方法和 BluetoothAdapter.getDefaultAdapter().getAddress() 方法都返回 02:00:00:00:00:00。

此外,在 Android 6.0 和 Android 9 之间,您必须持有以下权限才能访问附近通过蓝牙和 Wi-Fi 扫描可用的外部设备的 MAC 地址:

所需的方法/属性权限

ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION

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

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

回答by Dvir ben ishay

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