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

Up close and personal with Nearby

Up close and personal with Nearby

Talk presented at the Android Makers conference
Recording: https://www.youtube.com/watch?v=5kL5MLaRVg0

Hugo Visser

April 24, 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. 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 })
  3. 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! }
  4. Beacons Bluetooth device broadcasting id + tx power, telemetry Standards:

    iBeacon, Eddystone Often used for (course) location
  5. Nearby + Beacons The beacon id is a token Associate

    token to message → Proximity Beacon API Google Beacon Platform → Beacon Dashboard
  6. Beacon console Set beacon status Manage attachments → associate different

    projects! Shared infrastructure Proximity Beacon API
  7. Nearby + beacons Subscribe to beacon messages only Background scanning

    (screen on) Distance and signal changes for foreground apps
  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
  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. For beacon owners Always register / claim your beacons Google

    beacon platform is vendor agnostic Share beacons with developers! Still works with platform beacon scanning
  16. Connections Connect devices in a P2P fashion Uses Bluetooth &

    WIFI Topologies: P2P_STAR, P2P_CLUSTER, P2P_POINT_TO_POINT
  17. 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>
  18. 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()) } }
  19. 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 { }
  20. Discovery class MyDiscoveryCallback: EndpointDiscoveryCallback() { override fun onEndpointFound(endpoint: String, info:

    DiscoveredEndpointInfo) { } override fun onEndpointLost(endpoint: String) { } }
  21. 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 }
  22. 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) } }
  23. 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()
  24. Connections Hit or miss due to bluetooth issues? Don’t forget

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

    on experimenting and register your beacons :) Connections powerful, but not always reliable