Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Eddystone Beacons Demo
Lecture on Eddystone, an open Bluetooth Smart Beacon format
from Google
+Angelo Rüggeberg
@s3xy4ngyc
agenda
- Introductions to Beacons
- Introduction to Eddystone
- Coding Session
Introduction to Beacons
Image: Google
Context or
exact Location
Location, Accuracy,
Range, and alike
Image: Google
…
Use Cases
Image: Estimote
Opportunities
Presence (e.g. sights)
Image: Google
Opportunities
Tracking and Securing
Image: Google
Opportunities
• Contextual fencing
(aka Geo-fence)
• Contextual content
(e.g. reader circle)
• …
Image: Bundesarchiv
Landscape
• AltBeacon
• Apple‘s property: iBeacon™
• Estimote
• Gimbal™
• PayPal™ Beacon
• yoints
• …
• Bluetooth® SIG
(Sp...
Introduction to Eddystone
Eddystone™, what’s so special?
Openness
• It is an open Bluetooth 4.0 protocol
• While iBeacon™ is officially
supported by...
Hardware
Phones can become Smart Beacons
themselves
• TxEddystone-UID (Android Lollipop 5.0)
Almost all devices with BLE c...
Some Bluetooth® Facts
• Bluetooth / BLE
is a wireless protocol
• Bluetooth uses UHF radio waves in
the ISM band from 2.4 t...
Coding a Simple BLE Scanner
Prerequisites
• Real device with BLE (emulator has
no Bluetooth™ support)
• Alternative emulator http:
//stackoverflow.
co...
BLE Permissions for an App
•
<!– Allow any Bluetooth communication -->
<uses-permission android:name="android.permission.B...
•
•
•
•
•
•
public class MainActivity extends AppCompatActivity {
// Declare Bluetooth adapter
private BluetoothManager bluetoothManag...
public class MainActivity extends AppCompatActivity {
// Declare Bluetooth adapter
private BluetoothManager bluetoothManag...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout...
bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device...
bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device...
bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device...
bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device...
bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device...
bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device...
Move away from deprecated Methods
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
bluetoothLeScanner.startScan(new ScanCallback() {
@Override...
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
bluetoothLeScanner.startScan(new ScanCallback() {
@Override...
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
bluetoothLeScanner.startScan(new ScanCallback() {
@Override...
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
bluetoothLeScanner.startScan(new ScanCallback() {
@Override...
bluetoothLeScanner.startScan(filters, settings, new ScanCallback() {
@Override
public void onScanResult(int callbackType, ...
bluetoothLeScanner.startScan(filters, settings, new ScanCallback() {
@Override
public void onScanResult(int callbackType, ...
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
List<ScanFil...
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
List<ScanFil...
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
List<ScanFil...
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
List<ScanFil...
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
List<ScanFil...
Coding Proximity and Presence
There is only one packet format for BLE
which
Payload consists of 2 Bytes Header, 6
Bytes Mac Address and up to 31 Bytes
data.
Image: Google
Fixed: 02 01 06 03 03 aa fe
Length: 15
Fixed: 16 aa fe
Frame Type: 00
TX Power: ed
Namespace: ed d1 eb ea c0 4e 5d ef a0 1...
Fixed: 02 01 06 03 03 aa fe
Length: 11
Fixed: 16 aa fe
Frame Type: 20
Version: 00
Volt: 0c 06
Temo: 13 00
Adv. Count: 00 0...
// The Eddystone Service UUID, 0xFEAA.
private static final ParcelUuid EDDYSTONE_SERVICE_UUID
= ParcelUuid.fromString("000...
// The Eddystone Service UUID, 0xFEAA.
private static final ParcelUuid EDDYSTONE_SERVICE_UUID
= ParcelUuid.fromString("000...
// The Eddystone Service UUID, 0xFEAA.
private static final ParcelUuid EDDYSTONE_SERVICE_UUID
= ParcelUuid.fromString("000...
// The Eddystone Service UUID, 0xFEAA.
private static final ParcelUuid EDDYSTONE_SERVICE_UUID
= ParcelUuid.fromString("000...
// The Eddystone Service UUID, 0xFEAA.
private static final ParcelUuid EDDYSTONE_SERVICE_UUID
= ParcelUuid.fromString("000...
•
•
Image: Estimote
bluetoothLeScanner.startScan(filters, settings, new ScanCallback() {
@Override
public void onScanResult(int callbackType, ...
bluetoothLeScanner.startScan(filters, settings, new ScanCallback() {
@Override
public void onScanResult(int callbackType, ...
bluetoothLeScanner.startScan(filters, settings, new ScanCallback() {
@Override
public void onScanResult(int callbackType, ...
bluetoothLeScanner.startScan(filters, settings, new ScanCallback() {
@Override
public void onScanResult(int callbackType, ...
Fixed: 02 01 06 03 03 aa fe
Length: 11
Fixed: 16 aa fe
Frame Type: 20
Version: 00
Volt: 0c 06
Temo: 13 00
Adv. Count: 00 0...
bluetoothLeScanner.startScan(filters, settings, new ScanCallback() {
@Override
public void onScanResult(int callbackType, ...
bluetoothLeScanner.startScan(filters, settings, new ScanCallback() {
@Override
public void onScanResult(int callbackType, ...
bluetoothLeScanner.startScan(filters, settings, new ScanCallback() {
@Override
public void onScanResult(int callbackType, ...
Outlook and helpers
,
etc.
http://on.google.com/hub/
•
•
• …
•
•
•
•
• …
Image: https://commons.wikimedia.org/wiki/File:Zinkh%C3%BCtter_Hof_Messing_Werkzeuge.jpg
Eddystone beacons demo
Eddystone beacons demo
Eddystone beacons demo
Eddystone beacons demo
Upcoming SlideShare
Loading in …5
×

Eddystone beacons demo

1,642 views

Published on

Slides from my Eddystone Beacons Talk with Texted Version of Live Coding Demo.

Published in: Engineering
  • Be the first to comment

Eddystone beacons demo

  1. 1. Eddystone Beacons Demo Lecture on Eddystone, an open Bluetooth Smart Beacon format from Google +Angelo Rüggeberg @s3xy4ngyc
  2. 2. agenda - Introductions to Beacons - Introduction to Eddystone - Coding Session
  3. 3. Introduction to Beacons
  4. 4. Image: Google Context or exact Location
  5. 5. Location, Accuracy, Range, and alike Image: Google …
  6. 6. Use Cases Image: Estimote
  7. 7. Opportunities Presence (e.g. sights) Image: Google
  8. 8. Opportunities Tracking and Securing Image: Google
  9. 9. Opportunities • Contextual fencing (aka Geo-fence) • Contextual content (e.g. reader circle) • … Image: Bundesarchiv
  10. 10. Landscape • AltBeacon • Apple‘s property: iBeacon™ • Estimote • Gimbal™ • PayPal™ Beacon • yoints • … • Bluetooth® SIG (Special Interest Group) • Bluetooth® Smart Beacon • Eddystone™ • https://github. com/google/eddystone/tree/mast er/branding
  11. 11. Introduction to Eddystone
  12. 12. Eddystone™, what’s so special? Openness • It is an open Bluetooth 4.0 protocol • While iBeacon™ is officially supported by iOS devices only, Eddystone™ has official support for both iOS and Android Packet types / frames • Eddystone-UID (identifier) • Namespace as UUID • Instance (6 bytes), much like Major and Minor • Eddystone-URL • Eddystone-TLM (telemetry) • battery voltage • temperature • number of packets since last reboot • beacon uptime since last reboot
  13. 13. Hardware Phones can become Smart Beacons themselves • TxEddystone-UID (Android Lollipop 5.0) Almost all devices with BLE can become Smart Beacons themselves • BlueGiga BLED112 Dongle • Cambridge Silicon Radio CSR1010 (Beacon Development Board) • Rfduino • Linux (bluez) • ARM mbed (Nordic nRF51-dongle, nRF51-DK) • Node.js (node-eddystone-beacon using bleno) • Arduino (BLEPeripheral), using Nordic Semiconductor's nRF8001 or nR51822 https://github. com/google/eddystone/tree/master/eddyst one-uid/tools/txeddystone-uid
  14. 14. Some Bluetooth® Facts • Bluetooth / BLE is a wireless protocol • Bluetooth uses UHF radio waves in the ISM band from 2.4 to 2.485 GHz divided into channels with frequency hopping • Signal strength is an indicator for proximity (RSSI, received signal strength indicator) • BLE has reduced power consumption • Bluetooth SIG predicts more than 90% of Bluetooth-enabled smartphones will support the low energy standard by 2018.
  15. 15. Coding a Simple BLE Scanner
  16. 16. Prerequisites • Real device with BLE (emulator has no Bluetooth™ support) • Alternative emulator http: //stackoverflow. com/questions/20348743/blue tooth-low-energy-on-android- emulator/27712017 • Android 4.3 (Jelly Bean, API Level 18) • Android 4.4.4 (KitKat, API Level 19) fixes some issues (e.g. https://code.google. com/p/android/issues/detail? id=67272) • Android 5.0 (Lollipop, API Level 21) recommended due to some API changes (e.g. Advertisement and LE Scanner)
  17. 17. BLE Permissions for an App • <!– Allow any Bluetooth communication --> <uses-permission android:name="android.permission.BLUETOOTH"/> <!– Allow device discovery --> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> • <uses-feature android:name="android.hardware.bluetooth_le" android:required="true“ />
  18. 18. • • • • • •
  19. 19. public class MainActivity extends AppCompatActivity { // Declare Bluetooth adapter private BluetoothManager bluetoothManager; private BluetoothAdapter bluetoothAdapter;
  20. 20. public class MainActivity extends AppCompatActivity { // Declare Bluetooth adapter private BluetoothManager bluetoothManager; private BluetoothAdapter bluetoothAdapter;
  21. 21. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize Bluetooth adapter bluetoothManager = (BluetoothManager) getSystemService(Context. BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); …
  22. 22. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize Bluetooth adapter bluetoothManager = (BluetoothManager) getSystemService(Context. BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); …
  23. 23. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Initialize Bluetooth adapter bluetoothManager = (BluetoothManager) getSystemService(Context. BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); …
  24. 24. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } });
  25. 25. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } });
  26. 26. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } });
  27. 27. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } });
  28. 28. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { if(device.getAddress().equals("C1:4F:F1:FF:9B:90")) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } } });
  29. 29. bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { if(device.getAddress().equals("C1:4F:F1:FF:9B:90")) { Log.d(TAG, "Device-Adress: " + device.getAddress()); Log.d(TAG, "RSSI: " + rssi); } } });
  30. 30. Move away from deprecated Methods
  31. 31. bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); bluetoothLeScanner.startScan(new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } });
  32. 32. bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); bluetoothLeScanner.startScan(new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } });
  33. 33. bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); bluetoothLeScanner.startScan(new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } });
  34. 34. bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); bluetoothLeScanner.startScan(new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } });
  35. 35. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } });
  36. 36. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); } });
  37. 37. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> filters = new ArrayList<>(); ScanFilter filter = new ScanFilter.Builder() .setDeviceAddress("C1:4F:F1:FF:9B:90") .build(); filters.add(filter);
  38. 38. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> filters = new ArrayList<>(); ScanFilter filter = new ScanFilter.Builder() .setDeviceAddress("C1:4F:F1:FF:9B:90") .build(); filters.add(filter);
  39. 39. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> filters = new ArrayList<>(); ScanFilter filter = new ScanFilter.Builder() .setDeviceAddress("C1:4F:F1:FF:9B:90") .build(); filters.add(filter);
  40. 40. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> filters = new ArrayList<>(); ScanFilter filter = new ScanFilter.Builder() .setDeviceAddress("C1:4F:F1:FF:9B:90") .build(); filters.add(filter);
  41. 41. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); List<ScanFilter> filters = new ArrayList<>(); ScanFilter filter = new ScanFilter.Builder() .setDeviceAddress("C1:4F:F1:FF:9B:90") .build(); filters.add(filter);
  42. 42. Coding Proximity and Presence
  43. 43. There is only one packet format for BLE which
  44. 44. Payload consists of 2 Bytes Header, 6 Bytes Mac Address and up to 31 Bytes data.
  45. 45. Image: Google
  46. 46. Fixed: 02 01 06 03 03 aa fe Length: 15 Fixed: 16 aa fe Frame Type: 00 TX Power: ed Namespace: ed d1 eb ea c0 4e 5d ef a0 17 Instance: c5 61 2a 8c c2 53 ... 04 09 ... 45 53 54 03 03 Bat. Service: 0f 18 0e ... 16 0a 18 Mac: 53 c2 8c 2a 61 c5 ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  47. 47. Fixed: 02 01 06 03 03 aa fe Length: 11 Fixed: 16 aa fe Frame Type: 20 Version: 00 Volt: 0c 06 Temo: 13 00 Adv. Count: 00 0f 70 77 Sec. Count: 00 14 4e 70 ... 04 09 ... 45 53 54 03 03 Bat. Service: 0f 18 0e ... 16 0a 18 Mac: 53 c2 8c 2a 61 c5 ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  48. 48. // The Eddystone Service UUID, 0xFEAA. private static final ParcelUuid EDDYSTONE_SERVICE_UUID = ParcelUuid.fromString("0000FEAA-0000-1000-8000- 00805F9B34FB"); // Eddystone frame types private static final byte TYPE_UID = 0x00; private static final byte TYPE_URL = 0x10; private static final byte TYPE_TLM = 0x20;
  49. 49. // The Eddystone Service UUID, 0xFEAA. private static final ParcelUuid EDDYSTONE_SERVICE_UUID = ParcelUuid.fromString("0000FEAA-0000-1000-8000- 00805F9B34FB"); // Eddystone frame types private static final byte TYPE_UID = 0x00; private static final byte TYPE_URL = 0x10; private static final byte TYPE_TLM = 0x20;
  50. 50. // The Eddystone Service UUID, 0xFEAA. private static final ParcelUuid EDDYSTONE_SERVICE_UUID = ParcelUuid.fromString("0000FEAA-0000-1000-8000- 00805F9B34FB"); // Eddystone frame types private static final byte TYPE_UID = 0x00; private static final byte TYPE_URL = 0x10; private static final byte TYPE_TLM = 0x20;
  51. 51. // The Eddystone Service UUID, 0xFEAA. private static final ParcelUuid EDDYSTONE_SERVICE_UUID = ParcelUuid.fromString("0000FEAA-0000-1000-8000- 00805F9B34FB"); // Eddystone frame types private static final byte TYPE_UID = 0x00; private static final byte TYPE_URL = 0x10; private static final byte TYPE_TLM = 0x20;
  52. 52. // The Eddystone Service UUID, 0xFEAA. private static final ParcelUuid EDDYSTONE_SERVICE_UUID = ParcelUuid.fromString("0000FEAA-0000-1000-8000- 00805F9B34FB"); // Eddystone frame types private static final byte TYPE_UID = 0x00; private static final byte TYPE_URL = 0x10; private static final byte TYPE_TLM = 0x20;
  53. 53. • • Image: Estimote
  54. 54. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  55. 55. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  56. 56. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  57. 57. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  58. 58. Fixed: 02 01 06 03 03 aa fe Length: 11 Fixed: 16 aa fe Frame Type: 20 Version: 00 Volt: 0c 06 Temo: 13 00 Adv. Count: 00 0f 70 77 Sec. Count: 00 14 4e 70 ... 04 09 ... 45 53 54 03 03 Bat. Service: 0f 18 0e ... 16 0a 18 Mac: 53 c2 8c 2a 61 c5 ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  59. 59. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  60. 60. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  61. 61. bluetoothLeScanner.startScan(filters, settings, new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); byte[] data = result.getScanRecord().getServiceData(EDDYSTONE_SERVICE_UUID); byte frameType = data[0]; if (frameType != TYPE_TLM) { return; } // Beacon temperature double temp = new BigInteger(Arrays.copyOfRange(data, 4, 6)).intValue() / 256.0; Log.d(TAG, String.format("%.2f°C", temp)); } });
  62. 62. Outlook and helpers
  63. 63. , etc. http://on.google.com/hub/
  64. 64. • • • … • • • • • …
  65. 65. Image: https://commons.wikimedia.org/wiki/File:Zinkh%C3%BCtter_Hof_Messing_Werkzeuge.jpg

×