Users can publish and subscribe messages via the Android NearbyConnections API. Nearby Message users could adapt their current design to Nearby Connections via below samples. For more detailed usage about Nearby Connections, please refer to Nearby Connections API Overview .
Nearby Connections allows its clients to send data within 131 bytes without establishing a connection to the remote device. Please refer to the flow below as how to transfer messages within 131 bytes.
Publisher
private void startPublishing() {
// Using the default advertising option is enough since connecting is not required.
AdvertisingOptions advertisingOptions = new AdvertisingOptions.Builder().build();
Nearby.getConnectionsClient(context)
.startAdvertising(getMessagesInBytes(), SERVICE_ID, connectionLifecycleCallback, advertisingOptions)
.addOnSuccessListener(
(Void unused) -> {
// We're advertising!
})
.addOnFailureListener(
(Exception e) -> {
// We were unable to start advertising.
});
}
// To manage incoming connections from the subscriber.
// In this flow since we are not establishing connections between the two devices, we could
// ignore the implementation.
private
final
ConnectionLifecycleCallback
connectionLifecycleCallback
=
new
ConnectionLifecycleCallback
()
{
@
Override
public
void
onConnectionInitiated
(
String
endpointId
,
ConnectionInfo
connectionInfo
)
{}
@
Override
public
void
onConnectionResult
(
String
endpointId
,
ConnectionResolution
result
)
{}
@
Override
public
void
onDisconnected
(
String
endpointId
)
{}
};
private void stopPublishing() {
// Stop advertising when done.
Nearby.getConnectionsClient(context).stopAdvertising();
Nearby.getConnectionsClient(context).stopAllEndpoints();
}
Subscriber
private
void
startSubscription
()
{
// Using the default discovery option is enough since connection is not required.
DiscoveryOptions
discoveryOptions
=
new
DiscoveryOptions
.
Builder
().
build
();
Nearby
.
getConnectionsClient
(
context
)
// The SERVICE_ID value must uniquely identify your app.
// As a best practice, use the package name of your app
// (for example, com.google.example.myapp).
.
startDiscovery
(
SERVICE_ID
,
endpointDiscoveryCallback
,
discoveryOptions
)
.
addOnSuccessListener
(
(
Void
unused
)
-
>
{
// We're discovering!
})
.
addOnFailureListener
(
(
Exception
e
)
-
>
{
// We're unable to start discovering.
});
}
private
final
EndpointDiscoveryCallback
endpointDiscoveryCallback
=
new
EndpointDiscoveryCallback
()
{
@Override
public
void
onEndpointFound
(
String
endpointId
,
DiscoveredEndpointInfo
info
)
{
//
A
remote
advertising
endpoint
is
found
.
//
To
retrieve
the
published
message
data
.
byte
[]
message
=
info
.
getEndpointInfo
();
}
@Override
public
void
onEndpointLost
(
String
endpointId
)
{
//
A
previously
discovered
endpoint
has
gone
away
.
}
}
;
private void stopSubscription() {
// Stop discovery when the subscription is done.
Nearby.getConnectionsClient(context).stopDiscovery();
Nearby.getConnectionsClient(context).stopAllEndpoints();
}
Long Messages
For messages which are larger than 131 bytes, a connection between the devices needs to be established to transfer the message. Please refer to the flow below as how to transfer large data using Nearby Connections.
Publisher
private
void
startPublishing
()
{
//
Using
P2P
strategy
for
1:1
connection.
AdvertisingOptions
advertisingOptions
=
new
AdvertisingOptions.Builder().setStrategy(Strategy.P2P_POINT_TO_POINT).build()
;
Nearby.getConnectionsClient(context)
.startAdvertising(
getLocalUserName(),
SERVICE_ID,
connectionLifecycleCallback,
advertisingOptions)
.addOnSuccessListener(
(Void
unused)
-
>
{
//
We're
advertising!
}
)
.
addOnFailureListener
(
(
Exception
e
)
-
>
{
//
We
were
unable
to
start
advertising.
}
);
}
private
final
ConnectionLifecycleCallback
connectionLifecycleCallback
=
new
ConnectionLifecycleCallback
()
{
@
Override
public
void
onConnectionInitiated
(
String
endpointId
,
ConnectionInfo
connectionInfo
)
{
//
Automatically
accept
the
connection
on
both
sides
.
Nearby
.
getConnectionsClient
(
context
)
.
acceptConnection
(
endpointId
,
payloadCallback
);
}
@
Override
public
void
onConnectionResult
(
String
endpointId
,
ConnectionResolution
result
)
{
switch
(
result
.
getStatus
()
.
getStatusCode
())
{
case
ConnectionsStatusCodes
.
STATUS_OK
:
//
We
're connected! Can now start sending and receiving data.
Payload
bytesPayload
=
Payload
.
fromBytes
(
DATA_TO_BE_SENT
);
Nearby
.
getConnectionsClient
(
context
)
.
sendPayload
(
endpointId
,
bytesPayload
);
break
;
case
ConnectionsStatusCodes
.
STATUS_CONNECTION_REJECTED
:
//
The
connection
was
rejected
by
one
or
both
sides
.
break
;
case
ConnectionsStatusCodes
.
STATUS_ERROR
:
//
The
connection
broke
before
it
was
able
to
be
accepted
.
break
;
default
:
//
Unknown
status
code
}
}
@
Override
public
void
onDisconnected
(
String
endpointId
)
{
//
We
've been disconnected from this endpoint. No more data can be
//
sent
or
received
.
}
};
private void stopPublishing() {
// Stop advertising when done.
Nearby.getConnectionsClient(context).stopAdvertising();
Nearby.getConnectionsClient(context).stopAllEndpoints();
}
Subscriber
private void startSubscription() {
DiscoveryOptions discoveryOptions =
new DiscoveryOptions.Builder().setStrategy(Strategy.P2P_POINT_TO_POINT).build();
Nearby.getConnectionsClient(context)
.startDiscovery(SERVICE_ID, endpointDiscoveryCallback, discoveryOptions)
.addOnSuccessListener(
(Void unused) -> {
// We're discovering!
})
.addOnFailureListener(
(Exception e) -> {
// We're unable to start discovering.
});
}
private
final
EndpointDiscoveryCallback
endpointDiscoveryCallback
=
new
EndpointDiscoveryCallback
()
{
@Override
public
void
onEndpointFound
(
String
endpointId
,
DiscoveredEndpointInfo
info
)
{
//
An
endpoint
was
found
.
We
request
a
connection
to
it
.
Nearby
.
getConnectionsClient
(
context
)
.
requestConnection
(
getLocalUserName
(),
endpointId
,
connectionLifecycleCallback
)
.
addOnSuccessListener
(
(
Void
unused
)
-
>
{
//
We
successfully
requested
a
connection
.
Now
both
sides
//
must
accept
before
the
connection
is
established
.
}
)
.
addOnFailureListener
(
(
Exception
e
)
-
>
{
//
Nearby
Connections
failed
to
request
the
connection
.
}
);
}
@Override
public
void
onEndpointLost
(
String
endpointId
)
{
//
A
previously
discovered
endpoint
has
gone
away
.
}
}
;
private
final
ConnectionLifecycleCallback
connectionLifecycleCallback
=
new
ConnectionLifecycleCallback
()
{
@
Override
public
void
onConnectionInitiated
(
String
endpointId
,
ConnectionInfo
connectionInfo
)
{
//
Automatically
accept
the
connection
on
both
sides
.
Nearby
.
getConnectionsClient
(
context
)
.
acceptConnection
(
endpointId
,
payloadCallback
);
}
@
Override
public
void
onConnectionResult
(
String
endpointId
,
ConnectionResolution
result
)
{
switch
(
result
.
getStatus
()
.
getStatusCode
())
{
case
ConnectionsStatusCodes
.
STATUS_OK
:
//
We
're connected! Can now start sending and receiving data.
break
;
case
ConnectionsStatusCodes
.
STATUS_CONNECTION_REJECTED
:
//
The
connection
was
rejected
by
one
or
both
sides
.
break
;
case
ConnectionsStatusCodes
.
STATUS_ERROR
:
//
The
connection
broke
before
it
was
able
to
be
accepted
.
break
;
default
:
//
Unknown
status
code
}
}
@
Override
public
void
onDisconnected
(
String
endpointId
)
{
//
We
've been disconnected from this endpoint. No more data can be
//
sent
or
received
.
}
};
static
class
ReceiveBytesPayloadListener
extends
PayloadCallback
{
@
Override
public
void
onPayloadReceived
(
String
endpointId
,
Payload
payload
)
{
//
This
always
gets
the
full
data
of
the
payload
.
Is
null
if
it
's not a BYTES payload.
if
(
payload
.
getType
()
==
Payload
.
Type
.
BYTES
)
{
byte
[]
receivedBytes
=
payload
.
asBytes
();
}
}
@
Override
public
void
onPayloadTransferUpdate
(
String
endpointId
,
PayloadTransferUpdate
update
)
{
//
Bytes
payloads
are
sent
as
a
single
chunk
,
so
you
'll receive a SUCCESS update immediately
//
after
the
call
to
onPayloadReceived
()
.
}
}
private void stopSubscription() {
// Stop discovery when the subscription is done.
Nearby.getConnectionsClient(context).stopDiscovery();
Nearby.getConnectionsClient(context).stopAllEndpoints();
}