Nearby Connections is a peer-to-peer networking API that allows apps to easily discover, connect to, and exchange data with nearby devices in real-time, regardless of network connectivity. The API is located in the com.google.android.gms.nearby.connection package.

Some example use cases:

  • Collaborative whiteboard: Jot ideas down with nearby participants on a shared virtual whiteboard.
  • Local multiplayer gaming: Set up a multiplayer game and invite other users nearby to join.
  • Multi-screen gaming: Use a phone or tablet as a game controller to play games displayed on a nearby large-screen Android device, such as Android TV.
  • Offline file transfers: Share photos, videos, or any other type of data quickly and without requiring a network connection.


Nearby Connections enables advertising, discovery, and connections between nearby devices in a fully-offline peer-to-peer manner. Connections between devices are high-bandwidth, low-latency, and fully encrypted to enable fast, secure data transfers.

A primary goal of this API is to provide a platform that is simple, reliable, and performant. Under the hood, the API uses a combination of Bluetooth, BLE, and Wifi hotspots, leveraging the strengths of each while circumventing their respective weaknesses. This effectively abstracts the vagaries of Bluetooth and Wifi across a range of Android OS versions and hardware, allowing developers to focus on the features that matter to their users.

As a convenience, users are not prompted to turn on Bluetooth or Wifi — Nearby Connections enables these features as they are required, and restores the device to its prior state once the app is done using the API, ensuring a smooth user experience.

API Overview

Usage of the API falls into two phases: pre-connection, and post-connection.

In the pre-connection phase, Advertisers advertise themselves, while Discoverers discover nearby Advertisers and send connection requests. A connection request from a Discoverer to an Advertiser initiates a symmetric authentication flow that results in both sides independently accepting (or rejecting) the connection request.

After a connection request is accepted by both sides, the connection is considered to be established and the devices enter the post-connection phase, during which both sides can exchange data.

Advertising and Discovery

Advertisers begin by invoking startAdvertising(), passing in a ConnectionLifecycleCallback which will be notified whenever a Discoverer wants to connect via the onConnectionInitiated() callback.

Discoverers begin by invoking startDiscovery(), passing in an EndpointDiscoveryCallback which will be notified whenever a nearby Advertiser is found via the onEndpointFound() callback.

Establishing Connections

When a Discoverer wishes to connect to a nearby Advertiser, the Discoverer invokes requestConnection(), passing in a ConnectionLifecycleCallback of its own.

Both sides are then notified of the connection initiation process via the ConnectionLifecycleCallback.onConnectionInitiated() callback, and both must now choose whether to accept or reject the connection via a call to acceptConnection() or rejectConnection(), respectively.

At this point, apps can optionally prompt the user to accept the connection. See Authenticate a connection to learn more.

Once both sides have responded, each will be notified of the result via the ConnectionLifecycleCallback.onConnectionResult() callback. If both sides accepted the connection, then the ConnectionResolution provided in the callback will be successful, the connection is considered established, and the transfer of Payloads can then begin.

Exchanging Data

After a connection is established, further API usage is symmetrical, so there’s no longer a distinction between Advertiser and Discoverer.

Both sides can now exchange data as Payload objects. There are 3 types of supported Payloads:

  • BYTES Byte arrays limited to 32k; these are good for sending things such as metadata or control messages.
  • FILE Files of any size; these are transferred from the app to the network interface with minimal copying across process boundaries.
  • STREAM A stream of data that is generated on the fly, as in the case of recorded audio/video, with no final size known beforehand.

Senders use the sendPayload() method to send a Payload. This method can be invoked multiple times, but since we guarantee in-order delivery, the second Payload onwards will be queued for sending until the first Payload is done.

Receivers can expect the PayloadCallback.onPayloadReceived() callback to be invoked when a new incoming Payload is received.

Senders and Receivers both can expect the PayloadCallback.onPayloadTransferUpdate() callback to be invoked to update them about the progress of outgoing and incoming Payloads, respectively.

The connections established are full-duplex, which means that Advertisers and Discoverers can simultaneously send and receive Payloads.


Finally, disconnectFromEndpoint() disconnects from a particular remote endpoint, and stopAllEndpoints() disconnects from all connected endpoints. Remote endpoints are notified of disconnection via the ConnectionLifecycleCallback.onDisconnected().