Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android iBeacon Development @ IT Weekend Dnipro II

Android iBeacon Development @ IT Weekend Dnipro II

Kseniia Shumelchyk

October 31, 2015
Tweet

More Decks by Kseniia Shumelchyk

Other Decks in Programming

Transcript

  1. Android iBeacon development Kseniia Shumelchyk Software Engineer, Softserve Inc. Women

    Techmakers Ukraine Leader GDG Dnipropetrovsk Lead Organiser
  2. iBeacon - iBeacon is a protocol standardised by Apple and

    introduced at the WWDC in 2013 - Based on top of BLE - BLE works starting from 4S on Apple - BLE works starting from 4.3 on Android
  3. What is BLE? Bluetooth low energy (Bluetooth Smart) is a

    wireless personal area network technology aimed for novel applications in the healthcare, fitness, beacons, security, and home entertainment industries
  4. What is BLE? - Not backward-compatible (with classic Bluetooth protocol)

    - Uses same radio frequencies - 2.4 GGZ - 1 Mbps (1-3 Mbps with regular bluetooth) - Embedded devices & wearables
  5. Specification Technical Specification Classic Bluetooth technology Bluetooth Smart technology Distance/Range

    (theoretical max.) 100 m (330 ft) >100 m (>330 ft) Over the air data rate 1–3 Mbit/s 1 Mbit/s Active slaves 7 Not defined; implementation dependent Minimum total time to send data 100 ms 3 ms Power consumption 1 W as the reference 0.01 to 0.5 W (depending on use case)
  6. Generic Attribute Profile (GATT) - Client - A device that

    initiates GATT commands and requests, and accepts responses, for example a computer or smartphone - Server - A device that receives GATT commands and requests, and returns responses, for example a temperature sensor. - Characteristic - A data value transferred between client and server, for example the current battery voltage.
  7. Generic Attribute Profile (GATT) - Service - A collection of

    related characteristics, which operate together to perform a particular function. For instance, the Health Thermometer service includes characteristics for a temperature measurement value, and a time interval between measurements. - Descriptor - A descriptor provides additional information about a characteristic. For instance, a temperature value characteristic may have an indication of its units (e.g. Celsius), and the maximum and minimum values which the sensor can measure.
  8. GATT Operations - Discover UUIDs for all primary services -

    Find a service with a given UUID - Find secondary services for a given primary service - Discover all characteristics for a given service - Find characteristics matching a given UUID - Read all descriptors for a particular characteristic
  9. Beacon’s Advertisement - Beacon advertises a data package called the

    Scan Response Data - This Data can be up to 31 bytes. - The scan response is divided into AD structures
  10. Packet structure (2) Ad Structure 2 0x1B 0xFF 0xE0 0x00

    0xBE 0xAC Remaining length AD Type Manufacturer ID Beacon prefix 27 Manufacturer specific 224 (Google)
  11. Packet structure (2) Ad Structure 2 0x0C […] 0xBB 0x00

    0x09 0x00 0x06 0xBA UUID (16 bytes) Major Minor TX Power 9 6 -70
  12. Internals 02 01 06 1A FF 4C 00 02 15:

    prefix (fixed except for 3rd byte - flags) B9 40 7F 30 F5 F8 46 6E AF F9 25 55 6B 57 FE 6D: UUID 00 49: major 00 0A: minor C5: measured TX power
  13. Android - Built in support for Android 4.3+ - Central

    & peripheral roles - GATT server & GATT client - android.hardware.bluetooth_le feature
  14. Android 4.3 for Beacons detection (1) <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

    Check for permission <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/> Check for hardware
  15. Android 4.3 for Beacons detection (2) ENTER FILENAME/LANG final BluetoothManager

    bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); Get the BluetoothAdapter if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } 4. Enable Bluetooth
  16. Android 4.3 for Beacons detection (3) private LeScanCallback mLeScanCallback =

    new LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { … // Parsing beacon data }); } }; Define callback mBluetoothAdapter.startLeScan(mLeScanCallback); Start BLE scanning
  17. Android 5.0+ for Beacons detection - New api to work

    with BLE devices - Background scanning - Filtering possibility - SCAN_MODE_LOW_POWER mode - SCAN_MODE_LOW_LATENCY mode
  18. LOW_POWER LOW_LATENCY Test duration 134 minutes 152 minutes Battery Level

    Change -13% -25% Battery Drain Rate 268mA 454mA Relative Battery Savings 41% -- Typical time between detections 4400 ms 100 ms http://developer.radiusnetworks.com/2014/10/28/android-5.0-scanning.html
  19. Android 5.0 for Beacons detection (1) private void setScanFilter() {

    ScanFilter.Builder mBuilder = new ScanFilter.Builder(); ByteBuffer mManufacturerData = ByteBuffer.allocate(23); ByteBuffer mManufacturerDataMask = ByteBuffer.allocate(24); byte[] uuid = getIdAsByte(UUID.fromString("0CF052C297CA407C84F8B62AAC4E9020"); mManufacturerData.put(0, (byte)0xBE); mManufacturerData.put(1, (byte)0xAC); for (int i=2; i<=17; i++) { mManufacturerData.put(i, uuid[i-2]); } for (int i=0; i<=17; i++) { mManufacturerDataMask.put((byte)0x01); } mBuilder.setManufacturerData(224, mManufacturerData.array(), mManufacturerDataMask.array()); mScanFilter = mBuilder.build(); } Creating filter for scanning
  20. Android 5.0 for Beacons detection (2) ENTER FILENAME/LANG private void

    setScanSettings() { ScanSettings.Builder mBuilder = new ScanSettings.Builder(); mBuilder.setReportDelay(0); mBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER); mScanSettings = mBuilder.build(); } Setting scanner settings
  21. Android 5.0 for Beacons detection (3) ENTER FILENAME/LANG protected ScanCallback

    mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { ScanRecord mScanRecord = result.getScanRecord(); int[] manufacturerData = mScanRecord.getManufacturerSpecificData(224); int mRssi = result.getRssi(); } } Setting up callback
  22. Android Beacon emitter - Works starting from 5.0 - Currently

    only Nexus 6, Nexus 9 and later models supported - BluetoothLeAdvertiser & AdvertiseData & AdvertiseSettings support classes - Different levels of transmitter power
  23. Android iBeacon emitter (1) ENTER FILENAME/LANG protected void setAdvertiseData() {

    AdvertiseData.Builder mBuilder = new AdvertiseData.Builder() ByteBuffer mManufacturerData = ByteBuffer.allocate(24); byte[] uuid = getIdAsByte(UUID.fromString("0CF052C297CA407C84F8B62AAC4E9020")); mManufacturerData.put(0, (byte)0xBE); // Beacon Identifier mManufacturerData.put(1, (byte)0xAC); // Beacon Identifier for (int i=2; i<=17; i++) { mManufacturerData.put(i, uuid[i-2]); // adding the UUID } mManufacturerData.put(18, (byte)0x00); // first byte of Major mManufacturerData.put(19, (byte)0x09); // second byte of Major mManufacturerData.put(20, (byte)0x00); // first minor mManufacturerData.put(21, (byte)0x06); // second minor mManufacturerData.put(22, (byte)0xB5); // txPower mBuilder.addManufacturerData(224, mManufacturerData.array()); mAdvertiseData = mBuilder.build(); } Setting emitter
  24. Android iBeacon emitter (2) ENTER FILENAME/LANG protected void setAdvertiseSettings() {

    AdvertiseSettings.Builder mBuilder = new AdvertiseSettings.Builder(); mBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER); mBuilder.setConnectable(false); mBuilder.setTimeout(0); mBuilder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM); mAdvertiseSettings = mBuilder.build(); } Setting up setting
  25. Good to go, we can start advertising :) Good to

    go, we can start advertising :-D ENTER FILENAME/LANG mBluetoothLeAdvertiser.startAdvertising(mAdvertiseSettings, mAdvertiseData, mAdvertiseCallback); Start advertising