Android 获取棉花糖中的蓝牙本地mac地址

Android 获取棉花糖中的蓝牙本地mac地址,android,bluetooth,mac-address,android-6.0-marshmallow,Android,Bluetooth,Mac Address,Android 6.0 Marshmallow,Pre Marshmallow my app将通过BluetoothAdapter.getDefaultAdapter().getAddress()获取其设备MAC地址。 现在,有了棉花糖,Android正在返回02:00:00:00:00 我看到一些链接(抱歉,不知道现在在哪里)说你需要添加额外的权限 <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS"/> 为了能得到它。然而,这对我不起作

Pre Marshmallow my app将通过
BluetoothAdapter.getDefaultAdapter().getAddress()获取其设备MAC地址。

现在,有了棉花糖,Android正在返回
02:00:00:00:00

我看到一些链接(抱歉,不知道现在在哪里)说你需要添加额外的权限

<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地址的访问:

为了向用户提供更好的数据保护,从本版本开始,Android将删除使用Wi-Fi和蓝牙API的应用程序对设备本地硬件标识符的编程访问


(从)

您可以从该文件访问Mac地址 “/sys/class/net/”+networkInterfaceName+“/address”,其中networkInterfaceName可以是wlan0或eth1。但其权限可能受读取保护,因此在某些设备中可能无法工作。 我也附上代码部分,我从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 "";
    }
公共静态字符串getWifiMacAddress(){
试一试{
字符串interfaceName=“wlan0”;
列表接口=集合
.list(NetworkInterface.getNetworkInterfaces());
用于(网络接口intf:接口){
如果(!intf.getName().equalsIgnoreCase(interfaceName)){
继续;
}
字节[]mac=intf.getHardwareAddress();
如果(mac==null){
返回“”;
}
StringBuilder buf=新的StringBuilder();
for(字节aMac:mac){
追加(String.format(“%02X:”,aMac));
}
如果(buf.length()>0){
buf.deleteCharAt(buf.length()-1);
}
返回buf.toString();
}
}捕获(异常扩展){
exp.printStackTrace();
} 
返回“”;
}

zParties是正确的,但您仍然可以通过反射或设置获取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" />
之后,必须使用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;
    }

因为下面的方法为android O返回null

String macAddress = android.provider.Settings.Secure.getString(context.getContentResolver(), "bluetooth_address");
我找到了获取蓝牙Mac地址的新方法,您可以使用下面的命令行进行尝试

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


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

是。我读过。但API 23 BluetoothAdapter具有以下内容:/***向没有*android.permission.LOCAL_MAC_address权限的客户端报告的默认MAC地址。**@hide*/public静态最终字符串DEFAULT\u MAC\u ADDRESS=“02:00:00:00:00”;因此,这意味着应该有某种方法来获得它。(可能还没有实施?我抱着希望。)本地MAC地址权限只能由系统应用程序使用,谷歌不太可能改变这一点。wifi地址呢,你能处理mac地址吗?这是给不同的bdaddr(但一个有效的mac)。反射方法给出了正确的bdaddr。@Rilwan对隐藏/黑名单API使用反射将在下一次操作系统更新时使您的应用程序崩溃,这永远不是正确的解决方案,只是暂时的解决方法。android.provider.Settings.Secure.getString(context.getContentResolver(),“bluetooth_address”)在android中返回空值10谢谢。它可以在我尝试过的Nexus平板电脑上运行。Android N和更新版本也会使用这种方法返回错误的MAC地址。我测试过的两台设备都有两个甚至稍有不同的WiFi和Bluetooth MAC地址……我在Android 10上试过这种方法,效果不错,但正如你提到的,这是本地WiFi MAC地址,是否有任何方法可以使用这样的方法获取蓝牙mac地址?代码不起作用。对于lib,它总是在具有不同API级别的服务器设备上返回null。我只是在一些设备上尝试了该代码,并且在Pixel 2版本的Android 8.0 Oreo上总是返回mac地址(在具有4.4、5.0、5.1和6.0的设备上使用targetSDK 22进行了测试)。这种方法不再有效。我得到了java.lang.reflect.InvocationTargetException,原因是:java.lang.SecurityException:需要本地\u MAC\u地址权限:用户10141和当前进程都没有android.permission.LOCAL\u MAC\u地址。谷歌似乎已经对任何获得android 8.1的设备进行了“修复”。更新到8.1预览版的Nexus 5X也会出现异常。作为一个小小的安慰,谷歌已经开始在蓝牙设置界面上展示自己的蓝牙MAC,因此,至少用户可以手动将其复制到需要的应用程序中。我可以确认,手动输入并使用MAC地址对我的应用程序建立无对连接是有效的。提示:使用黑名单API的反思从来都不是一个好的解决方案,它可能会在下一次Android更新中击中你的脸。该应用程序的软件包名称是什么Field@Vinayak我发现有很多Field类。在Android 10中,还需要权限。@Kotd
su strings /data/misc/bluedroid/bt_config.conf | grep Address