04.06.2015
Here is an implementation for Bluetooth LE on Android which filters them by UUID and uses their rssi. The other bluetooth addons will just take the iBeacon with the strongest signal. This one will take all signal rssi and map them. You can add this technology to the positioning manager with a single line of code:
1 | positionManager.addTechnology(new BluetoothLeStrengthTechnology("BLUETOOTH_LE_STRENGTH", 4000, null)); |
The second parameter is the validity time for each scanned iBeacon. You can filter the devices with the third parameter. It is a list which contains all allowed iBeacon UUIDs.
Add the following classes to your technology package:
Model for the technology:
BluetoothLeDevice.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | import android.bluetooth.BluetoothDevice; public class BluetoothLeDevice implements Comparable<BluetoothLeDevice> { private String name; private String address; private String companyId; private String uuid; private int rssi; private int major; private int minor; private int txPower; private long timeStamp; public BluetoothLeDevice(String name, String address, String companyId, String uuid, int rssi, int major, int minor, int txPower, long timeStamp) { initialize(name, address, companyId, uuid, rssi, major, minor, txPower, timeStamp); } public BluetoothLeDevice(String name, String address, String companyId, String uuid, int rssi, String major, String minor, String txPower, long timeStamp) { initialize(name, address, companyId, uuid, rssi, Integer.parseInt(major, 16), Integer.parseInt(minor, 16), Integer.valueOf(txPower, 16).shortValue(), timeStamp); } public BluetoothLeDevice(BluetoothDevice device, byte[] scanRecord, int rssi) { String uuid = ""; String companyId = String.format("%02x", scanRecord[5]) + String.format("%02x", scanRecord[6]); String major = String.format("%02x", scanRecord[25]) + String.format("%02x", scanRecord[26]); String minor = String.format("%02x", scanRecord[27]) + String.format("%02x", scanRecord[28]); String txPower = String.format("%02x", scanRecord[29]); for (int i = 0; i < scanRecord.length; i++) { if (i >= 9 && i <= 24) { uuid += String.format("%02x", scanRecord[i]); } } initialize(device.getName(), device.getAddress(), companyId, uuid, rssi, Integer.parseInt(major, 16), Integer.parseInt(minor, 16), Integer.valueOf(txPower, 16).shortValue(), System.currentTimeMillis()); } private void initialize(String name, String address, String companyId, String uuid, int rssi, int major, int minor, int txPower, long timeStamp) { this.name = name; this.address = address; this.companyId = companyId; this.uuid = uuid; this.rssi = rssi; this.major = major; this.minor = minor; this.txPower = txPower; this.timeStamp = timeStamp; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getCompanyId() { return companyId; } public void setCompanyId(String companyId) { this.companyId = companyId; } public int getRssi() { return rssi; } public void setRssi(int rssi) { this.rssi = rssi; } public long getTimeStamp() { return timeStamp; } public void setTimeStamp(long timeStamp) { this.timeStamp = timeStamp; } public int getMajor() { return major; } public void setMajor(int major) { this.major = major; } public int getMinor() { return minor; } public void setMinor(int minor) { this.minor = minor; } public String getIdentificator() { return major+"|"+minor; } public String getUuid() { return uuid; } public void setUuid(String uuid) { this.uuid = uuid; } public int getTxPower() { return txPower; } public void setTxPower(int txPower) { this.txPower = txPower; } @Override public int compareTo(BluetoothLeDevice another) { if(rssi > another.rssi) { return 1; } else if(rssi < another.rssi) { return -1; } return 0; } @Override public String toString() { return "BluetoothLeDevice{" + "name='" + name + '\'' + ", address='" + address + '\'' + ", companyId='" + companyId + '\'' + ", uuid='" + uuid + '\'' + ", rssi=" + rssi + ", major=" + major + ", minor=" + minor + ", txPower=" + txPower + ", timeStamp=" + timeStamp + '}'; } } |
The technology:
BluetoothLeStrengthTechnology.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import de.hadizadeh.positioning.controller.Technology; import de.hadizadeh.positioning.model.SignalInformation; import java.util.HashMap; import java.util.List; import java.util.Map; public class BluetoothLeStrengthTechnology extends Technology { private Map<String, SignalInformation> signalData; private BluetoothAdapter bluetoothAdapter; private Map<String, BluetoothLeDevice> btLeDevices; private List<String> allowedBtLeDevices; private long validityTime; private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { BluetoothLeDevice btDevice = new BluetoothLeDevice(device, scanRecord, rssi); if ("4c00".equals(btDevice.getCompanyId()) && (allowedBtLeDevices == null || allowedBtLeDevices.contains(btDevice.getUuid()))) { btLeDevices.put(btDevice.getUuid(), btDevice); } } }; public BluetoothLeStrengthTechnology(String name, long validityTime, List<String> allowedBtLeDevices) { super(name, null); this.validityTime = validityTime; this.allowedBtLeDevices = allowedBtLeDevices; this.btLeDevices = new HashMap<String, BluetoothLeDevice>(); this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); this.signalData = new HashMap<String, SignalInformation>(); bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); bluetoothAdapter.startLeScan(leScanCallback); } @Override public Map<String, SignalInformation> getSignalData() { signalData.clear(); long currentTime = System.currentTimeMillis(); for (Map.Entry<String, BluetoothLeDevice> btLeDevice : btLeDevices.entrySet()) { if (btLeDevice.getValue().getTimeStamp() + validityTime >= currentTime) { signalData.put(btLeDevice.getValue().getAddress(), new SignalInformation(btLeDevice.getValue().getRssi())); } } return signalData; } @Override public void stopScanning() { super.stopScanning(); bluetoothAdapter.stopLeScan(leScanCallback); } } |
Kategorie: Indoor-Positioning Addons |