Inicia una conexión
Cuando se encuentran dispositivos cercanos, el descubridor puede iniciar conexiones. En el siguiente ejemplo, se solicita una conexión con un dispositivo en cuanto se descubre.
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. } };
Según tu caso práctico, puedes mostrar al usuario una lista de los dispositivos detectados para que pueda elegir a qué dispositivos conectarse.
Aceptar o rechazar una conexión
Después de que el descubrimiento solicita una conexión a un anunciante, ambas partes reciben una notificación del proceso de inicio de la conexión a través del método onConnectionInitiated()
de la devolución de llamada ConnectionLifecycleCallback
. Ten en cuenta que esta devolución de llamada se pasa a startAdvertising()
en el anunciante y a requestConnection()
en el detector, pero a partir de ese momento, la API es simétrica.
Ahora ambas partes deben elegir si desean aceptar o rechazar la conexión a través de una llamada a acceptConnection()
o rejectConnection()
, respectivamente. La conexión se establece por completo solo cuando ambas partes aceptan. Si uno o ambos se rechazan, se descarta la conexión. De cualquier manera, el resultado se entrega a onConnectionResult()
.
En el siguiente fragmento de código, se muestra cómo implementar esta devolución de llamada:
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. } };
Una vez más, en este ejemplo se muestra que la conexión es aceptada automáticamente por ambos lados, pero, según tu caso de uso, tal vez quieras presentarle esta opción al usuario de alguna manera.
Autentica una conexión
Cuando se solicita una conexión, tu app puede autenticar la conexión mediante el token de autenticación proporcionado para onConnectionInitiated()
. Esto permite que los usuarios confirmen que se están conectando al dispositivo deseado. Ambos dispositivos reciben el mismo token, que es una string corta aleatoria. Tú decides cómo verificarlo. Por lo general, esto implica mostrar el token en ambos dispositivos y pedirles a los usuarios que comparen y confirmen manualmente, de forma similar al diálogo de vinculación por Bluetooth.
En este código de muestra, se muestra una forma de autenticación cuando se muestra el token de autenticación al usuario en un 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(); }