Google Play Services: Using the Nearby Connections API

Introduction

One of the many APIs available in Google Play Services is the Nearby Connections API. Introduced in early 2015, this framework lets you set one device running your application as a host and have multiple other devices connect to it in order to communicate over a Local Area Network (LAN).

Use cases for this feature include connecting a phone to an Android TV for controlling an app and allowing users to participate in a multiplayer game. In this tutorial, you will learn how to set up applications for connecting multiple devices together over a network and how to send data over that connection. A working sample for this tutorial can be found on GitHub.

1. Project Setup

Once you have your initial program created in Android Studio, you will need to import the Play Services library into your app. To do this, place the following line of code under the dependency node of the build.gradle file. At the time of writing, Play Services 7.5.0 is the most recent release for development.

Once Play Services is included in your app, you can close build.gradle and open AndroidManifest.xml. Since this feature uses a LAN to communicate, you will need to include the ACCESS_NETWORK_STATE permission in your manifest.

Next, you will need to add a piece of meta-data in the application node that defines a service identifier that will be used by your app so that it can discover hosts advertising with that same identifier. In this example, our service identifier is defined in strings.xml as tutsplus_service_id.

When you're done with the manifest, you can move to MainActivity.java. This is the class where we will implement both advertising and discovery. In MainActivity, you will also control sending messages between different devices.

In order to start using the Nearby Connections API, you must set up and connect to the Google API Client. Start by implementing ConnectionCallbacks and OnConnectionFailedListener at the top of your class. While we're adding our interfaces, let's also include the three that are needed by the API and an OnClickListener.

Let's now create the member variables that we'll need for this tutorial at the top of the MainActivity class. For the sake of brevity, I'll simply mention that the layout for this class consists of a ListView for displaying messages, an EditText field with a Button for sending messages after connected, a Button for advertising, connecting, or disconnecting, depending on the device's role, and a TextView for displaying basic state information.

You'll notice that there are two boolean flags for designating wether or not the device is connected and if it is the connection host, the GoogleApiClient that is necessary for using the Nearby Connections API, and an array of integers for keeping track of the network connection types we will support for this API.

If you've worked with any Android Google API classes before, the last bit of setup should look fairly familiar. You need to initialize the GoogleApiClient and connect to it in onCreate.

In onStart and onStop, we handle connecting and disconnecting.

2. Advertising and Accepting Connections

Once you have connected to the Google API Client, you can start working with nearby connections. The first component we'll go over is advertising, which allows a device to assume the role of host and manage connections between various peers for communication.

Advertising itself is fairly straightforward. You simply need to check that the device has an acceptable type of connection and then call Nearby.Connections.StartAdvertising with the proper parameters. This will cause the device to advertise across your LAN that it is available for accepting connections from other applications.

In this example, we pass in a timeout of ten seconds for advertising. However, you can pass in a value of 0 to advertise indefinitely. In the following code, isConnectedToNetwork is a helper method meant to check if advertising should occur.

Sample application in advertising mode

Once your host application is advertising, it will be able to receive connection requests from peers. When a device attempts to connect, the following method will be called:

Using this method, you can either accept or reject the connection. To accept the request, you call Nearby.Connections.acceptConnectionRequest with a ResultsCallback. You can then perform actions, depending on whether the connection is successfully accepted or not.

For this example, we'll simply add the remote endpoint to a list to keep track of it and broadcast to any connected peers that this new device has connected. If, for some reason, you determine that the device should not connect to your application, you can reject it by calling Nearby.Connections.rejectConnectionRequest.

Sample host accepting connections from peers

3. Discovery

Just like advertising, discovery relies on being connected to the GoogleApiClient and having an acceptable network connection. You can start discovery by passing the application's service identifier into the Nearby.Connections.startDiscovery method, which sets your user's device into discovery mode.

When the device detects a host that is currently advertising using the predefined service identifier, the onEndpointFound callback will be triggered. It should be noted that this method can be called multiple times if there are multiple hosts broadcasting. In this situation, you can create a dialog for your users that displays all available hosts so that they can select which they would like to be connected to.

For this example, we'll assume that there's only one host advertising at a time, so we'll immediately request to connect by calling Nearby.Connections.sendConnectionRequest. If the connection is accepted or rejected by the host, the sendConnectionRequest result callback will be called. If the connection is accepted, the status will be set to successful and we can save the host endpoint identifier and prepare for sending messages across the connection channel.

Discovering a host

In a situation where you listen for multiple endpoints to present a choice for your users, the onEndpointLost method will let you know if a host has stopped advertising before your user has attempted to connect to it. The onDisconnected callback is also available for client devices and can be used for reconnecting to advertising hosts in the event of an unexpected disconnect.

4. Sending Messages

Once your devices have connected together, it's time to start communicating. There are two kinds of messages that can be sent, reliable and unreliable. If you're familiar with networking technology, you can think of these in terms of TCP (Transmission Control Protocol) and UDP (User Datagram Protocol). A simplified explanation is that reliable messages will retry attempts to send a message if they fail, whereas unreliable messages will simply drop the data if it is not successfully sent and received.

For this tutorial, you will use reliable messages. When a message is received over the API, onMessageReceived will be called. This method accepts the endpoint identifier, a payload, and a boolean indicating whether the connection is reliable or unreliable. The payload contains the message and the endpoint identifier is the identifier of whichever device sent the message.

In the sample application, you will use this to display the payload as a string in a ListView and, if the device is the host, rebroadcast it out to every connected device.

The sendMessage method is a helper method that demonstrates two versions of Nearby.Connections.sendReliableMessage. For host applications, sendReliableMessage will accept a list of endpoints to send the message to. This allows you to communicate to multiple devices with one line of code. For clients, messages only need to go to the host, so only the host name is needed as a parameter with the GoogleApiClient and message byte array.

Sending messages

5. Disconnecting

When you're ready to disconnect on either the host or client side of the application, there is a little bit of clean up that must take place. For hosts, you have to stop advertising and disconnect all of your endpoints.

In the sample code, you'll notice that a message is also sent that attempts to let peers know that the host has disconnected. In a more complete app, you would want your clients to listen for this kind of message so that they can handle the situation appropriately.

If you attempt to disconnect on a client that hasn't connected to a host yet, you simply need to stop discovery. If you've already connected to a host, you call disconnectFromEndpoint and the API will handle severing the connection.

Clean up the connection

Conclusion

In this tutorial, you have learned how to implement communication between various Android devices over a Local Area Network using the Nearby Connections API. You should now be able to enhance your own apps by connecting devices together and keeping them in sync through various updates to each other.

While this tutorial walked you through a fairly simple chat client application, you can take what you've learned here to create polished multiplayer experiences, provide secondary screens for users, or make your apps more contextually aware by providing an additional communication channel for the environment around them.

As the Nearby Connections API continues to grow with the addition of Eddystone beacons and Bluetooth, this will prove to be an invaluable skill to have when developing Android applications.

Tags:

Comments

Related Articles