Установить соединение
При обнаружении близлежащих устройств исследователь может инициировать подключение. В следующем примере запрашивается подключение к устройству, как только оно будет обнаружено.
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()
. Это позволяет пользователям подтвердить, что они подключаются к предполагаемому устройству. Оба устройства получают один и тот же токен, представляющий собой короткую случайную строку; Вам решать, как это проверить. Обычно это включает отображение токена на обоих устройствах и просьбу пользователей вручную сравнить и подтвердить, аналогично диалоговому окну сопряжения Bluetooth.
Этот пример кода демонстрирует один из способов аутентификации путем отображения токена аутентификации пользователю в 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(); }