短消息

用户可以通过 Android NearbyConnections API 发布和订阅消息。“附近消息”用户可以通过以下示例调整其当前设计,以适应“附近连接”。如需详细了解 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();
}