管理连接

启动连接

发现附近的设备时,发现器可以发起连接。通过 以下示例会在发现设备后立即请求与其建立连接。

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.
      }
    };

根据您的用例,您可能希望显示已发现的 设备,让用户可以选择连接哪些设备。

接受或拒绝连接

在探索者请求与广告主建立关联后,双方会 通过 onConnectionInitiated() 收到连接启动流程通知 方法的 ConnectionLifecycleCallback 回调。请注意,此回调将传入 startAdvertising() 探索器上的广告客户和requestConnection(),但从现在开始 那么 API 是对称的。

现在,双方必须选择是接受还是拒绝通话连接 分别更改为 acceptConnection()rejectConnection()。连接 双方都接受后才能完全达成共识。如果其中有一个或两个都拒绝, 连接将被舍弃。无论采用哪种方式,结果都会传递到 onConnectionResult()

以下代码段展示了如何实现此回调:

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.
      }
    };

同样,此示例展示了双方自动接受连接,但根据您的用例,您可能希望以某种方式向用户提供此选择。

对连接进行身份验证

请求连接时,您的应用可以通过以下方式对连接进行身份验证: 使用提供给 onConnectionInitiated() 的身份验证令牌。这个 可让用户确认他们是否连接到 设备。两部设备会获得同一个令牌,该令牌是一个简短的随机字符串; 具体如何验证将由您决定。这通常涉及 令牌,并让用户手动比较和确认, 类似于蓝牙配对对话框

此示例代码演示了一种身份验证方法,即通过显示 在 AlertDialog 中为该用户指定身份验证令牌:

@Override
public void onConnectionInitiated(String endpointId, ConnectionInfo info) {
  new AlertDialog.Builder(context)
      .setTitle("Accept connection to " + info.getEndpointName())
      .setMessage("Confirm the code matches on both devices: " + info.getAuthenticationDigits())
      .setPositiveButton(
          "Accept",
          (DialogInterface dialog, int which) ->
              // The user confirmed, so we can accept the connection.
              Nearby.getConnectionsClient(context)
                  .acceptConnection(endpointId, payloadCallback))
      .setNegativeButton(
          android.R.string.cancel,
          (DialogInterface dialog, int which) ->
              // The user canceled, so we should reject the connection.
              Nearby.getConnectionsClient(context).rejectConnection(endpointId))
      .setIcon(android.R.drawable.ic_dialog_alert)
      .show();
}