在 Marshmallow 中获取蓝牙本地 mac 地址

Get Bluetooth local mac address in Marshmallow

Pre Marshmallow 我的应用程序将通过 BluetoothAdapter.getDefaultAdapter().getAddress().

获取它的设备 MAC 地址

棉花糖 Android 现在回归 02:00:00:00:00:00

我看到一些 link(抱歉现在不确定在哪里)说您需要添加额外的权限

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

能够得到它。但是它对我不起作用。

获取 mac 地址需要一些额外的权限吗?

我不确定它在这里是否相关,但清单还包括

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

那么有没有办法获取本地蓝牙mac地址?

已故意删除对 mac 地址的访问:

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.

(来自 Android 6.0 Changes

您可以从文件中访问 Mac 地址 "/sys/class/net/" + networkInterfaceName+ "/address" ,其中 networkInterfaceName 可以是 wlan0 或 eth1.But 它的权限可能被读保护,所以它可能无法在某些设备上工作。 我还附上了我从 SO 获得的代码部分。

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 exp) {

            exp.printStackTrace();
        } 
        return "";
    }

zmarties 是对的,但您仍然可以通过反射或 Settings.Secure:

获得 mac 地址
  String macAddress = android.provider.Settings.Secure.getString(context.getContentResolver(), "bluetooth_address");

通过反射获取MAC地址可以是这样的:

private static String getBtAddressViaReflection() {
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    Object bluetoothManagerService = new Mirror().on(bluetoothAdapter).get().field("mService");
    if (bluetoothManagerService == null) {
        Log.w(TAG, "couldn't find bluetoothManagerService");
        return null;
    }
    Object address = new Mirror().on(bluetoothManagerService).invoke().method("getAddress").withoutArgs();
    if (address != null && address instanceof String) {
        Log.w(TAG, "using reflection to get the BT MAC address: " + address);
        return (String) address;
    } else {
        return null;
    }
}

使用反射库 (net.vidageek:mirror) 但你会明白的。

事实证明,我最终没有从 Android 获得 MAC 地址。蓝牙设备最终提供了 Android 设备 MAC 地址,该地址被存储并在需要时使用。是的,这看起来有点古怪,但在我参与的项目中,蓝牙设备软件也在开发中,事实证明这是处理这种情况的最佳方式。

请使用以下代码获取蓝牙 mac 地址。如果有任何问题,请告诉我。

private String getBluetoothMacAddress() {
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    String bluetoothMacAddress = "";
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
        try {
            Field mServiceField = bluetoothAdapter.getClass().getDeclaredField("mService");
            mServiceField.setAccessible(true);

            Object btManagerService = mServiceField.get(bluetoothAdapter);

            if (btManagerService != null) {
                bluetoothMacAddress = (String) btManagerService.getClass().getMethod("getAddress").invoke(btManagerService);
            }
        } catch (NoSuchFieldException e) {

        } catch (NoSuchMethodException e) {

        } catch (IllegalAccessException e) {

        } catch (InvocationTargetException e) {

        }
    } else {
        bluetoothMacAddress = bluetoothAdapter.getAddress();
    }
    return bluetoothMacAddress;
}

首先必须将以下权限添加到清单;

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />

然后,

public static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";

String macAddress = Settings.Secure.getString(getContentResolver(), SECURE_SETTINGS_BLUETOOTH_ADDRESS);

之后必须使用 OEM / 系统密钥对应用程序进行签名。在 Android 8.1.0.

上测试和验证

效果很好

 private String getBluetoothMacAddress() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        String bluetoothMacAddress = "";
        try {
            Field mServiceField = bluetoothAdapter.getClass().getDeclaredField("mService");
            mServiceField.setAccessible(true);

            Object btManagerService = mServiceField.get(bluetoothAdapter);

            if (btManagerService != null) {
                bluetoothMacAddress = (String) btManagerService.getClass().getMethod("getAddress").invoke(btManagerService);
            }
        } catch (NoSuchFieldException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignore) {

        }
        return bluetoothMacAddress;
    }

因为下面的方法 return 对于 android O.

无效
String macAddress = android.provider.Settings.Secure.getString(context.getContentResolver(), "bluetooth_address");

我找到了获取蓝牙 Mac 地址的新方法,您可以尝试使用以下命令行。

su strings /data/misc/bluedroid/bt_config.conf | grep Address

注意:就我而言,我使用的是根设备,因此我的应用程序具有超级用户权限。