Iniciar uma conexão
Quando dispositivos por perto forem encontrados, o descobridor poderá iniciar conexões. O exemplo abaixo solicita uma conexão com um dispositivo assim que ele é descoberto.
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. } };
Dependendo do seu caso de uso, você pode mostrar uma lista de dispositivos descobertos para o usuário, permitindo que ele escolha a quais dispositivos se conectar.
Aceitar ou recusar uma conexão
Ambas as partes recebem uma notificação do processo de iniciação da conexão com o método onConnectionInitiated()
do callback ConnectionLifecycleCallback
quando o solicitante solicita uma conexão com ele. Esse callback é transmitido para startAdvertising()
no
anunciante e requestConnection()
no descobridor, mas a partir desse ponto
a API é simétrica.
Agora, os dois lados precisam aceitar ou rejeitar a conexão usando acceptConnection()
ou rejectConnection()
, respectivamente. A conexão só será
integrada quando os dois lados forem aceitos. Se uma ou ambas forem rejeitadas, a conexão será descartada. De qualquer forma, o resultado é entregue a
onConnectionResult()
.
O snippet de código abaixo mostra como implementar esse callback:
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. } };
Novamente, esse exemplo mostra a conexão sendo aceita automaticamente pelos dois lados, mas dependendo do seu caso de uso, você pode apresentar essa opção ao usuário de alguma forma.
Autenticar uma conexão
Quando uma conexão é solicitada, seu app pode autenticar a conexão
usando o token de autenticação fornecido para onConnectionInitiated()
. Isso
oferece uma maneira de permitir que os usuários confirmem que estão se conectando ao dispositivo
desejado. Os dois dispositivos recebem o mesmo token, que é uma string aleatória curta. Cabe a você decidir como verificá-lo. Normalmente, isso envolve mostrar o
token em ambos os dispositivos e solicitar que os usuários comparem e confirmem manualmente,
semelhante a uma caixa de diálogo de pareamento do Bluetooth.
Este exemplo de código demonstra uma maneira de autenticação exibindo o
token de autenticação para o usuário em um 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(); }