Nearby Messages is a publish-subscribe API which lets nearby devices exchange
small payloads of data. Once a device publishes a message, nearby devices can
receive the message. This guide walks you through all of the functionality
your app must implement in order to publish messages, and subscribe to messages
using the Nearby Messages API.

The set of nearby devices is determined by the exchange of small tokens over
Bluetooth. When a device detects a token from a nearby device, it sends the
token to the Nearby Messages server to validate it and check if there are any
messages to deliver for the application's current set of subscriptions.

An application can control the set of mediums used for device discovery, and
whether the mediums are used to broadcast tokens and/or scan for tokens.
By default, broadcasting and scanning is done on all the mediums. To do
discovery on a subset or mediums, and to control whether to broadcast or scan,
you must pass additional parameters when you create publications and
subscriptions.

When actively publishing and subscribing, a "Nearby is in use" notification
is presented, informing users that Nearby is active. This notification is
only displayed when one or more apps are actively using Nearby, giving users
a chance to conserve battery life if Nearby is not needed. It provides
users with the following options:

- Navigate to an app to disable Nearby.
- Force an app to stop using Nearby.
- Navigate to the **Nearby Settings** screen.

You can use [`PublishCallback()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/PublishCallback.md.txt)
and [`SubscribeCallback()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/SubscribeCallback.md.txt)
to listen for cases when a user forces the app to stop using Nearby. When this
happens, the
[`onExpired()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/SubscribeCallback.md.txt#onExpired())
method is triggered.

Because the Nearby Messages APIs have the potential to impact battery life,
they should only be used from a foreground activity (with the exception of
[BLE background subscribe](https://developers.google.com/nearby/messages/android/get-beacon-messages.md.txt#subscribe_in_the_background)).

Call [`publish()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessagesClient.md.txt#publish(com.google.android.gms.nearby.messages.Message))
and/or [`subscribe()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessagesClient.md.txt#subscribe(com.google.android.gms.nearby.messages.MessageListener))
to use the Nearby Messages API. Your app should always
symetrically [`unpublish()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessagesClient.md.txt#unpublish(com.google.android.gms.nearby.messages.Message))
and [`unsubscribe()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessagesClient.md.txt#unsubscribe(com.google.android.gms.nearby.messages.MessageListener))
in [`onStop()`](https://developer.android.com/reference/android/app/Activity.html#onStop()).

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        mMessageListener = new MessageListener() {
            @Override
            public void onFound(Message message) {
                Log.d(TAG, "Found message: " + new String(message.getContent()));
            }

            @Override
            public void onLost(Message message) {
                Log.d(TAG, "Lost sight of message: " + new String(message.getContent()));
            }
        }

        mMessage = new Message("Hello World".getBytes());
    }

    @Override
    public void onStart() {
        super.onStart();
        ...
        Nearby.getMessagesClient(this).publish(mMessage);
        Nearby.getMessagesClient(this).subscribe(mMessageListener);
    }

    @Override
    public void onStop() {
        Nearby.getMessagesClient(this).unpublish(mMessage);
        Nearby.getMessagesClient(this).unsubscribe(mMessageListener);
        ...
        super.onStop();
    }

## Publish a message

To publish a message, call [`Nearby.getMessagesClient(Activity).publish()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessagesClient.md.txt#publish(com.google.android.gms.nearby.messages.Message))
passing your message byte array. We recommend keeping the messages to less then
3KB--these messages we can deliver faster--but we can support up to 100KB for
apps that need it. This service is not meant for exchanging larger objects such
as photos and videos.

You can optionally call [`PublishOptions.setStrategy()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/PublishOptions.Builder.md.txt#setStrategy(com.google.android.gms.nearby.messages.Strategy))
to set the [strategy](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/Strategy.md.txt)
to use.

The following example demonstrates calling `publish()` to send a small text
message:

    private void publish(String message) {
        Log.i(TAG, "Publishing message: " + message);
        mActiveMessage = new Message(message.getBytes());
        Nearby.getMessagesClient(this).publish(mActiveMessage);
    }

> [!NOTE]
> **Note:** This example has not set callbacks for the publish's status. To set a callback, pass [`PublishOptions`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/PublishOptions.md.txt) with a valid [`PublishCallback`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/PublishOptions.Builder.md.txt#setCallback(com.google.android.gms.nearby.messages.PublishCallback)) when publishing. You should also append a [`OnFailureListener`](https://developers.google.com/android/reference/com/google/android/gms/tasks/OnFailureListener.md.txt) to the end of the publish call, which will notify you if the publish has failed. For instance, if the device doesn't have an active internet connection.

## Unpublish a message

To unpublish a message, call [`unpublish()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessagesClient.md.txt#unpublish(com.google.android.gms.nearby.messages.Message)). At minimum your
app should call unpublish in its [`onStop()`](https://developer.android.com/reference/android/app/Activity.html#onStop())
method. Pass the same [`Message`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/Message.md.txt)
object that was used to publish (`mActiveMessage` in this example).

The following code example shows calling `unpublish()`:

    private void unpublish() {
        Log.i(TAG, "Unpublishing.");
        if (mActiveMessage != null) {
            Nearby.getMessagesClient(this).unpublish(mActiveMessage);
            mActiveMessage = null;
        }
    }

## Subscribe to messages

To subscribe to messages from other devices, call [`Nearby.getMessagesClient(Activity).subscribe()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessagesClient.md.txt#subscribe(com.google.android.gms.nearby.messages.MessageListener)). You'll need to pass
a [`MessageListener`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessageListener.md.txt)
to handle receiving subscribed messages.

You can optionally call [`SubscribeOptions.setStrategy()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/SubscribeOptions.Builder.md.txt#setStrategy(com.google.android.gms.nearby.messages.Strategy))
to set the [strategy](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/Strategy.md.txt)
to use.

The following example demonstrates subscribing to messages:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        mMessageListener = new MessageListener() {
            @Override
            public void onFound(Message message) {
                Log.d(TAG, "Found message: " + new String(message.getContent()));
            }

            @Override
            public void onLost(Message message) {
                Log.d(TAG, "Lost sight of message: " + new String(message.getContent()));
            }
        }
    }

    // Subscribe to receive messages.
    private void subscribe() {
        Log.i(TAG, "Subscribing.");
        Nearby.getMessagesClient(this).subscribe(mMessageListener, options);
    }

> [!NOTE]
> **Note:** Just like publishing, you're able to set a callback for the status of the subscription. Pass [`SubscribeOptions`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/SubscribeOptions.md.txt) with a valid [`SubscribeCallback`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/SubscribeOptions.Builder.md.txt#setCallback(com.google.android.gms.nearby.messages.SubscribeCallback)) when subscribing. You should also append a [`OnFailureListener`](https://developers.google.com/android/reference/com/google/android/gms/tasks/OnFailureListener.md.txt) to the end of the subscribe call, which will notify you if the subscribe has failed. For instance, if the device doesn't have an active internet connection.

## Unsubscribe

To unsubscribe and stop receiving device messages, call
[`Nearby.getMessagesClient(Activity).unsubscribe()`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessagesClient.md.txt#unsubscribe(com.google.android.gms.nearby.messages.MessageListener)). Pass the same
[`MessageListener`](https://developers.google.com/android/reference/com/google/android/gms/nearby/messages/MessageListener.md.txt)
object that was used to subscribe (`mMessageListener` in this example).

The following code example demonstrates unsubscribing:

    private void unsubscribe() {
        Log.i(TAG, "Unsubscribing.");
        Nearby.getMessagesClient(this).unsubscribe(mMessageListener);
    }