Rozpoczynanie połączenia
Po znalezieniu urządzeń w pobliżu urządzenie może rozpoczynać połączenia. Ten przykład żąda połączenia z urządzeniem natychmiast po jego wykryciu.
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. } };
W zależności od przypadku możesz wyświetlić listę wykrytych urządzeń, aby użytkownik mógł wybrać, z którymi urządzeniami chce się połączyć.
Akceptowanie i odrzucanie połączenia
Po wykryciu powiązania z reklamodawcą obie strony są powiadamiane o procesie inicjowania połączenia za pomocą metody onConnectionInitiated()
wywołania zwrotnego ConnectionLifecycleCallback
. Zwróć uwagę, że to wywołanie zwrotne jest przekazywane do reklamodawcy (startAdvertising()
) i requestConnection()
w wyszukiwarce. Od tego momentu interfejs API jest symetryczny.
Teraz obie strony będą mogły zdecydować, czy zaakceptować, czy odrzucić połączenie, używając odpowiednio wywołania acceptConnection()
lub rejectConnection()
. Połączenie zostanie nawiązane tylko wtedy, gdy obie strony zaakceptują zaproszenie. Jeśli któreś z nich zostanie odrzucone, połączenie zostanie odrzucone. W obu przypadkach wynik jest dostarczany do onConnectionResult()
.
Ten fragment kodu pokazuje, jak wdrożyć to wywołanie zwrotne:
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. } };
Ten przykład pokazuje, że połączenie jest automatycznie akceptowane przez obie strony, ale w zależności od konkretnego przypadku możesz chcieć zaprezentować tę opcję użytkownikowi.
Uwierzytelnianie połączenia
Gdy nastąpi żądanie połączenia, aplikacja może uwierzytelnić przy użyciu tokena uwierzytelniania podanego przez onConnectionInitiated()
. Dzięki temu użytkownicy będą mogli się upewnić, że łączą się z odpowiednim urządzeniem. Oba urządzenia otrzymują ten sam token – krótki losowy ciąg znaków – to Ty decydujesz, jak go zweryfikować. Zwykle wiąże się to z wyświetleniem tokena na obu urządzeniach i poproszenie użytkownika o ręczne porównanie i potwierdzenie, podobnie jak w przypadku okna parowania Bluetooth.
Ten przykładowy kod pokazuje jeden ze sposobów uwierzytelniania, wyświetlając token uwierzytelniania użytkownikowi w 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(); }