Search code examples
androidbluetooth-lowenergyibeacon

Retrieving Android BluetoothLE device information (Major / minor / identifier / ProximityUUID) on scan?


I've been looking around and unfortunately the android ibeacon library has been deprecated, so I am attempting to do this native. I have implemented the BluetoothAdapter.LeScanCallback and the built in onLeScan() method that will fire when a device is picked up. I would like to read in that device's ProximityUUID, major and minor characteristics and identifier. I'm not sure how to get that information out of the Android object BluetoothDevice.

How do I extract that information (ProximityUUID, major, minor, & identifier characteristics) from the Android BluetoothDevice, or is there another way to do it?

Thanks!


Solution

  • you can refer this post to fully understand what those bytes means in LeScanCallback . And this is my code to parse all information needed:

    // an object with all information embedded from LeScanCallback data
    public class ScannedBleDevice implements Serializable {
        // public BluetoothDevice BLEDevice;
    
        /**
        * Returns the hardware address of this BluetoothDevice.
        * <p>
        * For example, "00:11:22:AA:BB:CC".
        * 
        * @return Bluetooth hardware address as string
        */
        public String MacAddress;
    
        public String DeviceName;
        public double RSSI;
        public double Distance;
    
        public byte[] CompanyId;
        public byte[] IbeaconProximityUUID;
        public byte[] Major;
        public byte[] Minor;
        public byte Tx;
    
        public long ScannedTime;
    }
    
    // use this method to parse those bytes and turn to an object which defined proceeding.
    // the uuidMatcher works as a UUID filter, put null if you want parse any BLE advertising data around.
    private ScannedBleDevice ParseRawScanRecord(BluetoothDevice device,
            int rssi, byte[] advertisedData, byte[] uuidMatcher) {
        try {
            ScannedBleDevice parsedObj = new ScannedBleDevice();
            // parsedObj.BLEDevice = device;
            parsedObj.DeviceName = device.getName();
            parsedObj.MacAddress = device.getAddress();
            parsedObj.RSSI = rssi;
            List<UUID> uuids = new ArrayList<UUID>();
            int skippedByteCount = advertisedData[0];
            int magicStartIndex = skippedByteCount + 1;
            int magicEndIndex = magicStartIndex
                    + advertisedData[magicStartIndex] + 1;
            ArrayList<Byte> magic = new ArrayList<Byte>();
            for (int i = magicStartIndex; i < magicEndIndex; i++) {
                magic.add(advertisedData[i]);
            }
    
            byte[] companyId = new byte[2];
            companyId[0] = magic.get(2);
            companyId[1] = magic.get(3);
            parsedObj.CompanyId = companyId;
    
            byte[] ibeaconProximityUUID = new byte[16];
            for (int i = 0; i < 16; i++) {
                ibeaconProximityUUID[i] = magic.get(i + 6);
            }
    
            if (uuidMatcher != null) {
                if (ibeaconProximityUUID.length != uuidMatcher.length) {
                    Log.e(LOG_TAG,
                            "Scanned UUID: "
                                    + Util.BytesToHexString(
                                            ibeaconProximityUUID, " ")
                                    + " filtered by UUID Matcher "
                                    + Util.BytesToHexString(uuidMatcher, " ")
                                    + " with length requirment.");
                    return null;
                }
    
                for (int i = 0; i < 16; i++) {
                    if (ibeaconProximityUUID[i] != uuidMatcher[i]) {
                        Log.e(LOG_TAG,
                                "Scanned UUID: "
                                        + Util.BytesToHexString(
                                                ibeaconProximityUUID, " ")
                                        + " filtered by UUID Matcher "
                                        + Util.BytesToHexString(uuidMatcher,
                                                " "));
                        return null;
                    }
                }
    
            }
    
            parsedObj.IbeaconProximityUUID = ibeaconProximityUUID;
    
            byte[] major = new byte[2];
            major[0] = magic.get(22);
            major[1] = magic.get(23);
            parsedObj.Major = major;
    
            byte[] minor = new byte[2];
            minor[0] = magic.get(24);
            minor[1] = magic.get(25);
            parsedObj.Minor = minor;
    
            byte tx = 0;
            tx = magic.get(26);
            parsedObj.Tx = tx;
    
            parsedObj.ScannedTime = new Date().getTime();
            return parsedObj;
        } catch (Exception ex) {
            Log.e(LOG_TAG, "skip one unknow format data...");
            // Log.e(LOG_TAG,
            // "Exception in ParseRawScanRecord with advertisedData: "
            // + Util.BytesToHexString(advertisedData, " ")
            // + ", detail: " + ex.getMessage());
            return null;
        }
    }