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

Up close and personal with Nearby (DevFest Trondheim)

Hugo Visser
November 19, 2018

Up close and personal with Nearby (DevFest Trondheim)

Updated presentation for DevFest Trondheim

Hugo Visser

November 19, 2018
Tweet

More Decks by Hugo Visser

Other Decks in Technology

Transcript

  1. What is Nearby? Create features based on proximity Android (Play

    Services) + iOS https://developers.google.com/nearby/
  2. Messages Message is created an associated with a unique token

    Device emits the token using wifi, bluetooth, audio Subscribing devices look up message when receiving the token
  3. Publish a message // Create once and keep a reference

    val client = Nearby.getMessagesClient(this) val payload = byteArrayOf(...) val message = Message(payload, "my_message_type") client.publish(message).addOnSuccessListener { // yay }.addOnFailureListener({ // exception is ApiException })
  4. Receiving messages class MyMessageListener: MessageListener() { override fun onFound(message: Message)

    { } override fun onLost(message: Message) { } } client.subscribe(MyMessageListener()).addOnSuccessListener { // we're listening }.addOnFailureListener { // oh no! }
  5. Beacons Bluetooth device broadcasting id + tx power, telemetry Standards:

    iBeacon, Eddystone, Altbeacon Often used for (course) location
  6. Nearby + Google Beacon Platform The beacon id is a

    token Associate token to message → Proximity Beacon API Beacon Dashboard
  7. Nearby + beacons Subscribe to beacon messages only Background scanning

    (screen on) Distance and signal changes for foreground apps Abstracts out the physical beacon from the purpose (message)
  8. Subscribe to beacon messages client = Nearby.getMessagesClient(this, MessagesOptions.Builder(). setPermissions(NearbyPermissions.BLE).build()) //

    This requires android.permission.BLUETOOTH and ACCESS_COARSE_LOCATION // Android 6.0 and up requires location to be enabled too! client.subscribe(messageListener, SubscribeOptions.Builder(). setStrategy(Strategy.BLE_ONLY).build()). addOnFailureListener { }
  9. Subscribe to beacon messages class MyMessagesListener: MessageListener() { override fun

    onFound(message: Message) { // May receive non-project messages here (check message.namespace) } override fun onBleSignalChanged(message: Message, signal: BleSignal) { } override fun onDistanceChanged(message: Message, distance: Distance) { } }
  10. Background subscription client = Nearby.getMessagesClient(this, MessagesOptions.Builder(). setPermissions(NearbyPermissions.BLE).build()) // You can

    register up to 5 pending intents val pendingIntent = PendingIntent.getBroadcast(...) client.subscribe(pendingIntent, SubscribeOptions.Builder(). setStrategy(Strategy.BLE_ONLY).build()). addOnFailureListener { }
  11. Background subscription class MyReceiver: BroadcastReceiver() { override fun onReceive(context: Context,

    intent: Intent) { Nearby.getMessagesClient(context).handleIntent(intent, MyMessagesListener()) } }
  12. Just beacons, no attachments Use MessageFilter.Builder() to scan for specific

    beacons iBeacon proximity id w/ optional major and minor ids Eddystone namespace with optional instance Obtain beacon id from a Message using IBeaconId and EddystoneUid
  13. Nearby notifications Show notification on Android devices based on beacons

    Launch url or deep link to app Proxied, filtered, based on relevance, etc, etc Special type of attachment, set by beacon owners Will be turned off dec 6 2018
  14. How do you prove you own a beacon? A beacon

    signal is public... So what if I register a large portion of beacons at a national airport?
  15. Connections Connect devices in a P2P fashion Uses Bluetooth &

    WIFI Topologies: P2P_STAR, P2P_CLUSTER, P2P_POINT_TO_POINT
  16. Setup <manifest ...> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission

    android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- Request at runtime on M and up --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> </manifest>
  17. Advertising class MyConnectionCallback: ConnectionLifecycleCallback() { override fun onConnectionResult(endpoint: String, result:

    ConnectionResolution) { } override fun onDisconnected(endpoint: String) { } override fun onConnectionInitiated(endpoint: String, info: ConnectionInfo) { // Make sure to failures from the resulting task! // Instead of accepting, you can also reject or accept later // ConnectionInfo contains an auth token for OOB use client.acceptConnection(endpoint, MyPayloadCallback()) } }
  18. Advertising // Get a connections client client = Nearby.getConnectionsClient(this) //

    First argument is the name for this device // Empty string generates a name client.startAdvertising("", BuildConfig.APPLICATION_ID, MyConnectionCallback(), AdvertisingOptions(Strategy.P2P_CLUSTER)). addOnFailureListener { }
  19. Discovery class MyDiscoveryCallback: EndpointDiscoveryCallback() { override fun onEndpointFound(endpoint: String, info:

    DiscoveredEndpointInfo) { } override fun onEndpointLost(endpoint: String) { } }
  20. Connection // First parameter is the device name, or generated

    if empty client.requestConnection("", endpoint, MyConnectionCallback()). addOnFailureListener { // Use status code from ApiException // to check what went wrong }
  21. Transfer data class MyPayloadCallback : PayloadCallback() { override fun onPayloadReceived(endpoint:

    String, payload: Payload) { // Check payload type and handle the (partial) payload } override fun onPayloadTransferUpdate(endpoint: String, update: PayloadTransferUpdate) { // for Payload.Type.Bytes this is not needed, for other types // reports progress (both incoming and outgoing) } } // When accepting the connection client.acceptConnection(endpoint, MyPayloadCallback())
  22. Disconnect // Disconnect a single endpoint, keep other processes going

    client.disconnectFromEndpoint(endpoint) client.stopDiscovery() client.stopAdvertising() // Prevents accepting and requesting new connections & disconnects everything client.stopAllEndpoints()
  23. Connections Hit or miss due to bluetooth issues? Don’t forget

    to check for errors Stop discovery / advertising before connecting
  24. Conclusion Concise and small API Messages, beacon messages Notifications: nice

    try -- RIP. Connections powerful, but not always reliable