RSS-Feed

David Hadizadeh

E-Mail

Xing-Profil

LinkedIn

Google+

Impressum

 




Bluetooth LE Technology with strength (rssi by UUIDs)

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 |


Impressum