用户可以通过 Android NearbyConnections API 发布和订阅消息。“附近消息”用户可以通过以下示例调整他们当前的设计,以适应 Nearby Connections。如需详细了解 Nearby Connections 的用法,请参阅 Nearby Connections API 概览。
Nearby Connections 允许其客户端在 131 字节内发送数据,而无需与远程设备建立连接。请参阅下面的流程,了解如何传输 131 字节以内的消息。
发布商
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();
}
订阅者
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();
}
长消息
对于超过 131 个字节的消息,需要在设备之间建立连接才能传输消息。请参阅下面的流程,了解如何使用 Nearby Connections 传输大型数据。
发布商
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();
}
订阅者
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();
}