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

The Human Context: Exploring Google's Nearby APIs (Video)

The Human Context: Exploring Google's Nearby APIs (Video)

A high-level overview of the cross-platform Nearby APIs introduced in 2015. Covers capabilities, practicalities, responsibilities, and opportunities!

Video: https://www.youtube.com/watch?v=fKSqMsCTDiI
Venue: Self Conference 2016

3a6060bc7ace07fa75791cd5dac2d46a?s=128

Stuart Kent

May 20, 2016
Tweet

Transcript

  1. Exploring Google's Nearby APIs The Human Context

  2. Stuart Kent, @skentphd Mobile developer @ Detroit Labs 2¼ years

    9 months ~2 months
  3. The Nearby APIs "Build simple interactions between nearby devices and

    people"
  4. The Process friedomelet.wordpress.com

  5. Google I/O

  6. Roadmap Background & Motivation

  7. Roadmap Background & Motivation Capabilities

  8. Roadmap Background & Motivation Practicalities Capabilities

  9. Roadmap Background & Motivation Practicalities Responsibilities Capabilities

  10. Roadmap Background & Motivation Practicalities Responsibilities Opportunities Capabilities

  11. Context Aware Apps Background & Motivation

  12. Context Aware Apps Observe, interpret, and act based on their

    environment.
  13. Context Aware Apps Environment

  14. Context Aware Apps Environment Observers

  15. Context Aware Apps Environment Interpreters/Actors Observers

  16. 2001 "My internet browser heard us saying the word Fry

    and it found a movie about Philip J. Fry for us. It also opened my calendar to Friday and ordered me some french fries."
  17. 2016

  18. The Human Context "Man is by nature a social animal"

  19. The Nearby APIs Environment Interpreters/Actors Observers Easier Refined

  20. Capabilities

  21. The Nearby APIs "Build simple interactions between nearby devices and

    people"
  22. Current Categories Nearby Connections Local Multiplayer Games Nearby Messages General

    purpose
  23. Current Categories Nearby Connections Local Multiplayer Games Nearby Messages General

    purpose
  24. Current Categories Nearby Connections Local Multiplayer Games Nearby Messages General

    purpose
  25. • detect and communicate with nearby devices The Nearby Messages

    API
  26. • detect and communicate with nearby devices • simple pub/sub

    API The Nearby Messages API
  27. • detect and communicate with nearby devices • simple pub/sub

    API • iOS & Android The Nearby Messages API
  28. • detect and communicate with nearby devices • simple pub/sub

    API • iOS & Android • unauthenticated* The Nearby Messages API
  29. • detect and communicate with nearby devices • simple pub/sub

    API • iOS & Android • unauthenticated* • default (~100ft) and earshot (~ 5ft) ranges The Nearby Messages API
  30. • detect and communicate with nearby devices • simple pub/sub

    API • iOS & Android • unauthenticated* • default (~100ft) and earshot (~ 5ft) ranges • [BLE beacon support] The Nearby Messages API
  31. Roles Publisher 0 or 1 messages Subscriber Multiple messages

  32. Roles Publisher 0 or 1 messages Handheld (dynamic) Subscriber Multiple

    messages Handheld
  33. Roles Publisher 0 or 1 messages Handheld (dynamic) + Beacon

    (static) Subscriber Multiple messages Handheld
  34. Roles Publisher 0 or 1 messages Handheld (dynamic) + Beacon

    (static) Subscriber Multiple messages Handheld
  35. • Byte array (JSON, protocol buffers) • Reco iOS) 


    Messages
  36. • Byte array (JSON, protocol buffers) • Recommended: < 3kb

    (Android); "fairly small" (iOS) 
 Messages
  37. • Byte array (JSON, protocol buffers) • Recommended: < 3kb

    (Android); "fairly small" (iOS) • Max: 100kb (Android & iOS)
 Messages
  38. • Byte array (JSON, protocol buffers) • Recommended: < 3kb

    (Android); "fairly small" (iOS) • Max: 100kb (Android & iOS)
 ↳ Send references, not resources Messages
  39. Communication Methods Practicalities

  40. Discovery & Messaging Image credit: p2pkit.io

  41. Discovery & Messaging Image credit: p2pkit.io

  42. Discovery & Messaging Image credit: p2pkit.io

  43. Discovery & Messaging Image credit: p2pkit.io

  44. Discovery & Messaging Image credit: p2pkit.io

  45. Discovery & Messaging Image credit: p2pkit.io

  46. Discovery & Messaging Image credit: p2pkit.io

  47. Discovery & Messaging Image credit: p2pkit.io

  48. Ultrasound Image credit: p2pkit.io

  49. Ultrasound Image credit: p2pkit.io

  50. • Tokens communicated using Bluetooth/speaker+mic Summary

  51. • Tokens communicated using Bluetooth/speaker+mic
 ↳ range control Summary

  52. • Tokens communicated using Bluetooth/speaker+mic
 ↳ range control
 ↳ heavy

    battery usage Summary
  53. • Tokens communicated using Bluetooth/speaker+mic
 ↳ range control
 ↳ heavy

    battery usage • Message content delivered via Google servers Summary
  54. • Tokens communicated using Bluetooth/speaker+mic
 ↳ range control
 ↳ heavy

    battery usage • Message content delivered via Google servers
 ↳ security/insecurity? Summary
  55. • Tokens communicated using Bluetooth/speaker+mic
 ↳ range control
 ↳ heavy

    battery usage • Message content delivered via Google servers
 ↳ security/insecurity? 
 ↳ connectivity requirement Summary
  56. • Tokens communicated using Bluetooth/speaker+mic
 ↳ range control
 ↳ heavy

    battery usage • Message content delivered via Google servers
 ↳ security/insecurity?
 ↳ connectivity requirement • Apps must share Google Developers Console project Summary
  57. • Tokens communicated using Bluetooth/speaker+mic
 ↳ range control
 ↳ heavy

    battery usage • Message content delivered via Google servers
 ↳ security/insecurity?
 ↳ connectivity requirement • Apps must share Google Developers Console project
 ↳ more security Summary
  58. Demo & Code! Practicalities

  59. Calling Card

  60. • Auth with Google account • Publish photo, name, email

    • See nearby users (100ft) • Save users Calling Card
  61. • Auth with Google account • Publish photo, name, email

    • See nearby users (100ft) • Save users Calling Card
  62. • Auth with Google account • Publish photo, name, email

    • See nearby users (100ft) Calling Card
  63. • Auth with Google account • Publish photo, name, email

    • See nearby users (100ft) • Save contact info Calling Card
  64. Calling Card Android
 
 Play Store
 goo.gl/dkmGxa
 
 GitHub
 stkent/calling-card

    iOS
 
 
 
 
 GitHub
 stkent/calling-card-ios
  65. Apps must handle: • runtime permission (Bluetooth/Audio) Implementation Notes

  66. Apps must handle: • runtime permission (Bluetooth/Audio) • message serialization

    & deserialization Implementation Notes
  67. Apps must handle: • runtime permission (Bluetooth/Audio) • message serialization

    & deserialization • notification kill (Android) Implementation Notes
  68. Apps must handle: • runtime permission (Bluetooth/Audio) • message serialization

    & deserialization • notification kill (Android) • teardown Implementation Notes
  69. Android

  70. dependencies { ... 
 compile 'com.google.android.gms:play-services-nearby:9.0.0' ... } build.gradle

  71. <application>
 ... <!-- API key from Google API Console -->


    <meta-data
 android:name="com.google.android.nearby.messages.API_KEY"
 android:value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" /> 
 ... 
 </application> AndroidManifest.xml
  72. Nearby.Messages.publish(googleApiClient, message, pubOptions) NearbyActivity.java

  73. Nearby.Messages.publish(googleApiClient, message, pubOptions) //////////////////////////////////////////////////////////////////// googleApiClient = new GoogleApiClient.Builder(this)
 .addApi(Nearby.MESSAGES_API)
 .addConnectionCallbacks(this)


    .addOnConnectionFailedListener(this)
 .build(); NearbyActivity.java
  74. Nearby.Messages.publish(googleApiClient, message, pubOptions) //////////////////////////////////////////////////////////////////// @Override
 protected void onStart() {
 super.onStart();


    googleApiClient.connect();
 } NearbyActivity.java
  75. Nearby.Messages.publish(googleApiClient, message, pubOptions) //////////////////////////////////////////////////////////////////// @Override
 public void onConnectionFailed(ConnectionResult result) {


    if (result.hasResolution()) {
 try {
 result.startResolutionForResult(this, NEARBY_CODE);
 } catch (final IntentSender.SendIntentException e) {
 // cancel all Nearby operations
 }
 } else { // cancel all Nearby operations }
 } NearbyActivity.java
  76. Nearby.Messages.publish(googleApiClient, message, pubOptions) //////////////////////////////////////////////////////////////////// @Override
 public void onConnectionFailed(ConnectionResult result) {


    if (result.hasResolution()) {
 try {
 result.startResolutionForResult(this, NEARBY_CODE);
 } catch (final IntentSender.SendIntentException e) {
 // cancel all Nearby operations
 }
 } else { // cancel all Nearby operations }
 } NearbyActivity.java
  77. Nearby.Messages.publish(googleApiClient, message, pubOptions) //////////////////////////////////////////////////////////////////// NearbyActivity.java

  78. Nearby.Messages.publish(googleApiClient, message, pubOptions) //////////////////////////////////////////////////////////////////// @Override
 protected void onActivityResult( int requestCode,

    int resultCode, Intent data) {
 
 if (requestCode == NEARBY_CODE) {
 if (resultCode == RESULT_OK) { googleApiClient.connect(); } else { // cancel all Nearby operations }
 } else {
 super.onActivityResult(requestCode, resultCode, data);
 }
 } NearbyActivity.java
  79. Nearby.Messages.publish(googleApiClient, message, pubOptions) //////////////////////////////////////////////////////////////////// @Override
 protected void onActivityResult( int requestCode,

    int resultCode, Intent data) {
 
 if (requestCode == NEARBY_CODE) {
 if (resultCode == RESULT_OK) { googleApiClient.connect(); } else { // cancel all Nearby operations }
 } else {
 super.onActivityResult(requestCode, resultCode, data);
 }
 } NearbyActivity.java
  80. Nearby.Messages.publish(googleApiClient, message, pubOptions) //////////////////////////////////////////////////////////////////// private Message message; ... User user

    = getIntent().getParcelableExtra(USER_EXTRA_KEY); message = new Message(GSON.toJson(user).getBytes()); NearbyActivity.java
  81. Nearby.Messages.publish(googleApiClient, message, pubOptions) //////////////////////////////////////////////////////////////////// // can also be used to

    set role and range private PublishOptions pubOptions = new PublishOptions.Builder() .setCallback(publishCallback) .build(); NearbyActivity.java
  82. Nearby.Messages.publish(googleApiClient, message, pubOptions) //////////////////////////////////////////////////////////////////// // can also be used to

    set role and range private PublishOptions pubOptions = new PublishOptions.Builder() .setCallback(publishCallback) .build(); ... private PublishCallback publishCallback = new PublishCallback() {
 @Override
 public void onExpired() { // cancel all Nearby operations }
 }; NearbyActivity.java
  83. private Message message; ... 
 Nearby.Messages.unpublish(googleApiClient, message); // show inactive

    UI NearbyActivity.java
  84. private Message message; ... 
 Nearby.Messages.unpublish(googleApiClient, message); // show inactive

    UI NearbyActivity.java
  85. Nearby.Messages.subscribe(googleApiClient, listener, subOptions) NearbyActivity.java

  86. Nearby.Messages.subscribe(googleApiClient, listener, subOptions) //////////////////////////////////////////////////////////////////// NearbyActivity.java As before.

  87. Nearby.Messages.subscribe(googleApiClient, listener, subOptions) //////////////////////////////////////////////////////////////////// private MessageListener listener = new MessageListener()

    {
 @Override
 public void onFound(Message message) {
 // received once; deserialize data and cache it }
 
 @Override
 public void onLost(Message message) {
 // received once; deserialize data and remove from cache
 }
 }; NearbyActivity.java
  88. Nearby.Messages.subscribe(googleApiClient, listener, subOptions) //////////////////////////////////////////////////////////////////// NearbyActivity.java Same API as publish options.

  89. private MessageListener listener; ... 
 Nearby.Messages.unsubscribe(googleApiClient, listener); // show inactive

    UI NearbyActivity.java
  90. private MessageListener listener; ... 
 Nearby.Messages.unsubscribe(googleApiClient, listener); // show inactive

    UI NearbyActivity.java
  91. @Override
 protected void onStop() {
 // cancel all Nearby operations

    // disconnect GoogleApiClient
 super.onStop();
 } NearbyActivity.java
  92. iOS

  93. source 'https://github.com/CocoaPods/Specs.git' platform :ios, '9.0' pod 'NearbyMessages', '0.10.0' Podfile (0.39)

  94. #import <GNSMessages.h> Nearby-Bridging-Header.h

  95. private lazy var messageManager: GNSMessageManager = { GNSMessageManager(APIKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") }()

    NearbyViewController.swift
  96. private var message: GNSMessage? { guard let userData = user?.toNSData()

    else { return nil } return GNSMessage(content: userData) } NearbyViewController.swift
  97. private var message: GNSMessage? { guard let userData = user?.toNSData()

    else { return nil } return GNSMessage(content: userData) } NearbyViewController.swift
  98. private var permissionProxy: GNSPermission? ... override func viewWillAppear(animated: Bool) {

    super.viewWillAppear(animated) permissionProxy = GNSPermission { [weak self] granted in if granted { // show active UI } else { // show inactive UI } } } NearbyViewController.swift
  99. private var permissionProxy: GNSPermission? ... override func viewWillAppear(animated: Bool) {

    super.viewWillAppear(animated) permissionProxy = GNSPermission { [weak self] granted in if granted { // show active UI } else { // show inactive UI } } } NearbyViewController.swift
  100. private var currentPub: GNSPublication? ... if let message = message

    { // shows permissions request dialog // can also pass params to set role and range currentPub = messageManager.publicationWithMessage(message) } NearbyViewController.swift
  101. private var currentPub: GNSPublication? ... private func stopPublishing() { currentPub

    = nil // show inactive UI } NearbyViewController.swift
  102. private var currentSub: GNSSubscription? ... // can also pass params

    to set role and range currentSub = messageManager.subscriptionWithMessageFoundHandler( { [weak self] foundMessage in // received once; deserialize data and cache it }, messageLostHandler: { [weak self] lostMessage in // received once; deserialize data and remove from cache } ) NearbyViewController.swift
  103. private var currentSub: GNSSubscription? ... private func stopSubscribing() { currentSub

    = nil // show inactive UI } NearbyViewController.swift
  104. override func viewWillDisappear(animated: Bool) { // cancel all Nearby operations

    super.viewWillDisappear(animated) } NearbyViewController.swift
  105. responsibilities

  106. Battery Be a good citizen

  107. Privacy Anonymity vs Authenticity

  108. Privacy Anonymity vs Authenticity "Yik Yak is a location-based social

    network that helps people discover their local community, letting them share news, crack jokes, offer support, ask questions, and interact freely."
  109. Privacy Anonymity vs Authenticity

  110. Privacy Anonymity vs Authenticity

  111. opportunities

  112. • Augmentation Trajectories

  113. • Augmentation • Foundation Trajectories

  114. • Augmentation • Foundation • Competition Trajectories

  115. • Augmentation • Foundation • Competition • Evolution Trajectories

  116. Augmentation Pocket Casts

  117. Foundation Radon Card Case

  118. Competition

  119. Evolution Nearby Notifications

  120. Questions? Stuart Kent • stuart@detroitlabs.com • @skentphd thanks!