32
votes

Pre Marshmallow my app would obtain it's device MAC address via BluetoothAdapter.getDefaultAdapter().getAddress().

Now with Marshmallow Android is returning 02:00:00:00:00:00.

I saw some link(sorry not sure where now) that said you need to add the additional permission

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

to be able to get it. However it isn't working for me.

Is there some additional permission needed to get the mac address?

I am not sure it is pertinent here but the manifest also includes

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

So is there a way to get the local bluetooth mac address?

9

9 Answers

42
votes

zmarties is right but you can still get the mac address via reflection or Settings.Secure:

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

Access to the mac address has been deliberately removed:

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.

(from Android 6.0 Changes)

5
votes

You can access Mac address from the file "/sys/class/net/" + networkInterfaceName+ "/address" ,where networkInterfaceName can be wlan0 or eth1.But Its permission may be read-protected,so it may not work in some devices. I am also attaching the code part which i got from 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 "";
    }
5
votes

First the following permissions have to be added to Manifest;

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

Then,

public static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address";

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

After that the application has to be signed with OEM / System key. Tested and verified on Android 8.1.0.

4
votes

Please use the below code to get the bluetooth mac address. let me know if any issues.

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;
}
3
votes

Getting the MAC address via reflection can look like this:

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

using a reflection library (net.vidageek:mirror) but you'll get the idea.

1
votes

Since below method return null for android O.

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

I found new way to get Bluetooth Mac address, you can try by using below command line.

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

NOTE: In my case, i was working with root device so my app has super user permission.

0
votes

As it turns out, I ended up not getting the MAC address from Android. The bluetooth device ended up providing the Android device MAC address, which was stored and then used when needed. Yeah it seems a little funky but on the project I was on, the bluetooth device software was also being developed and this turned out to be the best way to deal with the situation.

-1
votes

Worked great

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