Una delle tante API disponibili in Google Play Services è la API Connections nelle vicinanze. Introdotto all'inizio del 2015, questo framework consente di impostare un dispositivo che esegue l'applicazione come host e di collegarsi ad altri dispositivi multipli per comunicare su un dispositivo Rete locale (LAN).
I casi d'uso per questa funzione includono il collegamento di un telefono a una TV Android per controllare un'app e consentire agli utenti di partecipare a una partita multiplayer. In questo tutorial, imparerai come configurare le applicazioni per connettere più dispositivi insieme su una rete e come inviare dati tramite quella connessione. Un esempio funzionante per questo tutorial è disponibile su GitHub.
Una volta creato il tuo programma iniziale in Android Studio, dovrai importare la libreria Play Services nella tua app. Per fare questo, posizionare la seguente riga di codice sotto il nodo di dipendenza del build.gradle file. Al momento della stesura, Play Services 7.5.0 è la versione più recente per lo sviluppo.
compila "com.google.android.gms: play-services: 7.5.0"
Una volta che Play Services è incluso nella tua app, puoi chiudere build.gradle e aperto AndroidManifest.xml. Poiché questa funzione utilizza una LAN per comunicare, è necessario includere il ACCESS_NETWORK_STATE
permesso nel tuo manifest.
Successivamente, dovrai aggiungere un pezzo di meta-dati
nel applicazione
nodo che definisce un identificatore di servizio che verrà utilizzato dalla tua app in modo che possa scoprire gli host pubblicitari con lo stesso identificatore. In questo esempio, il nostro identificatore di servizio è definito in strings.xml come tutsplus_service_id
.
Quando hai finito con manifest, puoi spostarti MainActivity.java. Questa è la classe in cui implementeremo sia la pubblicità che la scoperta. Nel Attività principale
, controllerai anche l'invio di messaggi tra diversi dispositivi.
Per iniziare a utilizzare l'API delle connessioni vicine, è necessario configurare e connettersi al client dell'API di Google. Inizia con l'implementazione ConnectionCallbacks
e OnConnectionFailedListener
in cima alla tua classe. Mentre aggiungiamo le nostre interfacce, includiamo anche le tre necessarie all'API e a OnClickListener
.
public class MainActivity estende AppCompatActivity implementa GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, Connections.ConnectionRequestListener, Connections.MessageListener, Connections.EndpointDiscoveryListener, View.OnClickListener ...
Creiamo ora le variabili membro di cui avremo bisogno per questo tutorial all'inizio del Attività principale
classe. Per brevità, menzionerò semplicemente che il layout di questa classe è costituito da a Visualizzazione elenco
per visualizzare messaggi, a Modifica il testo
campo con a Pulsante
per l'invio di messaggi dopo la connessione, a Pulsante
per pubblicità, connessione o disconnessione, a seconda del ruolo del dispositivo e a TextView
per la visualizzazione delle informazioni di base dello stato.
Noterai che ci sono due flag booleani per designare se il dispositivo è connesso o meno e se è l'host di connessione, GoogleApiClient
è necessario per utilizzare l'API delle connessioni vicine e un array di numeri interi per tenere traccia dei tipi di connessione di rete che supporteranno per questa API.
GoogleApiClient privato mGoogleApiClient; Spinner privato mTypeSpinner; TextView privato mStatusText; Pulsante privato mConnectionButton; Pulsante privato mSendButton; ListView privato mListView; ViewGroup privato mSendTextContainer; privato EditText mSendEditText; ArrayAdapter privatomMessageAdapter; mIsHost booleano privato; private boolean mIsConnected; stringa privata mRemoteHostEndpoint; Elenco privato mRemotePeerEndpoints = new ArrayList (); finale statico privato lungo CONNECTION_TIME_OUT = 10000L; private static int [] NETWORK_TYPES = ConnectivityManager.TYPE_WIFI, ConnectivityManager.TYPE_ETHERNET;
Se hai già lavorato con alcune classi dell'API di Google Android, l'ultimo bit di configurazione dovrebbe apparire abbastanza familiare. È necessario inizializzare il GoogleApiClient
e connettersi ad esso onCreate
.
mGoogleApiClient = new GoogleApiClient.Builder (this) .addConnectionCallbacks (this) .addOnConnectionFailedListener (this) .addApi (Nearby.CONNECTIONS_API) .build ();
Nel onStart
e onStop
, gestiamo la connessione e la disconnessione.
@Override protected void onStart () super.onStart (); mGoogleApiClient.connect (); @Override protected void onStop () super.onStop (); if (mGoogleApiClient! = null && mGoogleApiClient.isConnected ()) mGoogleApiClient.disconnect ();
Dopo esserti collegato al client dell'API di Google, puoi iniziare a lavorare con le connessioni vicine. Il primo componente che esamineremo è pubblicità, che consente a un dispositivo di assumere il ruolo di host e di gestire le connessioni tra diversi peer per la comunicazione.
La pubblicità stessa è abbastanza semplice. È sufficiente verificare che il dispositivo abbia un tipo accettabile di connessione e quindi chiamare Nearby.Connections.StartAdvertising
con i parametri appropriati. Ciò farà sì che il dispositivo pubblicizzi sulla tua LAN che è disponibile per accettare connessioni da altre applicazioni.
In questo esempio, passiamo un timeout di dieci secondi per la pubblicità. Tuttavia, puoi passare un valore di 0
fare pubblicità a tempo indeterminato. Nel seguente codice, isConnectedToNetwork
è un metodo di supporto pensato per verificare se la pubblicità dovrebbe verificarsi.
private void advertise () if (! isConnectedToNetwork ()) return; String name = "Pubblicità nelle vicinanze"; Nearby.Connections.startAdvertising (mGoogleApiClient, name, null, CONNECTION_TIME_OUT, this) .setResultCallback (new ResultCallback() @Override public void onResult (risultato Connections.StartAdvertisingResult) if (result.getStatus (). IsSuccess ()) mStatusText.setText ("Advertising"); ); private boolean isConnectedToNetwork () ConnectivityManager connManager = (ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE); for (int networkType: NETWORK_TYPES) NetworkInfo info = connManager.getNetworkInfo (networkType); if (info! = null && info.isConnectedOrConnecting ()) return true; return false;
Una volta che la tua applicazione host fa pubblicità, sarà in grado di ricevere richieste di connessione da colleghi. Quando un dispositivo tenta di connettersi, verrà chiamato il seguente metodo:
public void onConnectionRequest (final String remoteEndpointId, final String remoteDeviceId, final String remoteEndpointName, byte [] payload)
Utilizzando questo metodo, puoi accettare o rifiutare la connessione. Per accettare la richiesta, chiami Nearby.Connections.acceptConnectionRequest
con un ResultsCallback
. È quindi possibile eseguire azioni, a seconda che la connessione sia accettata o meno con successo.
Per questo esempio, aggiungeremo semplicemente l'endpoint remoto a un elenco per tenerne traccia e trasmetterlo a tutti i peer connessi connessi a questo nuovo dispositivo. Se, per qualche motivo, si stabilisce che il dispositivo non deve connettersi all'applicazione, è possibile rifiutarlo chiamando Nearby.Connections.rejectConnectionRequest
.
@Override public void onConnectionRequest (final String remoteEndpointId, final String remoteDeviceId, final String remoteEndpointName, byte [] payload) if (mIsHost) Nearby.Connections.acceptConnectionRequest (mGoogleApiClient, remoteEndpointId, payload, this) .setResultCallback (new ResultCallback() @ Override pubblico onResult (stato stato) if (status.isSuccess ()) if (! MRemotePeerEndpoints.contains (remoteEndpointId)) mRemotePeerEndpoints.add (remoteEndpointId); mMessageAdapter.add (remoteDeviceId + "connected!"); mMessageAdapter.notifyDataSetChanged (); sendMessage (remoteDeviceId + "connected!"); mSendTextContainer.setVisibility (View.VISIBLE); ); else Nearby.Connections.rejectConnectionRequest (mGoogleApiClient, remoteEndpointId);
Proprio come la pubblicità, la scoperta si basa sulla connessione con GoogleApiClient
e con una connessione di rete accettabile. È possibile avviare la scoperta passando l'identificatore del servizio dell'applicazione nel file Nearby.Connections.startDiscovery
metodo, che imposta il dispositivo dell'utente in modalità di rilevamento.
Quando il dispositivo rileva un host che attualmente sta pubblicizzando utilizzando l'identificatore di servizio predefinito, il onEndpointFound
la richiamata verrà attivata. Va notato che questo metodo può essere chiamato più volte se ci sono più trasmissioni di host. In questa situazione, puoi creare una finestra di dialogo per gli utenti che visualizza tutti gli host disponibili in modo che possano selezionare a chi vorrebbero essere connessi.
Per questo esempio, supponiamo che ci sia un solo annuncio pubblicitario per volta, quindi richiederemo immediatamente la connessione chiamando Nearby.Connections.sendConnectionRequest
. Se la connessione è accettata o rifiutata dall'host, il sendConnectionRequest
verrà richiamata la callback del risultato. Se la connessione viene accettata, lo stato verrà impostato su corretto e potremo salvare l'identificatore dell'endpoint host e prepararci per l'invio di messaggi attraverso il canale di connessione.
private void discover () if (! isConnectedToNetwork ()) return; String serviceId = getString (R.string.service_id); Nearby.Connections.startDiscovery (mGoogleApiClient, serviceId, 10000L, this) .setResultCallback (nuovo ResultCallback() @Override public void onResult (stato di stato) if (status.isSuccess ()) mStatusText.setText ("Discovering"); else Log.e ("TutsPlus", "Rilevamento fallito:" + status.getStatusMessage ()); ); @Override public void onEndpointFound (String endpointId, String deviceId, final String serviceId, String endpointName) byte [] payload = null; Nearby.Connections.sendConnectionRequest (mGoogleApiClient, deviceId, endpointId, payload, new Connections.ConnectionResponseCallback () @Override public void onConnectionResponse (String endpointId, Status status, byte [] bytes) if (status.isSuccess ()) mStatusText. setText ("Connected to:" + endpointId); Nearby.Connections.stopDiscovery (mGoogleApiClient, serviceId); mRemoteHostEndpoint = endpointId; mSendTextContainer.setVisibility (View.VISIBLE); if (! mIsHost) mIsConnected = true; else mStatusText .setText ("Connessione a" + endpointId + "non riuscito"); if (! mIsHost) mIsConnected = false;, this);
In una situazione in cui si ascoltano più endpoint per presentare una scelta per i propri utenti, il onEndpointLost
il metodo ti consente di sapere se un host ha interrotto la pubblicità prima che l'utente abbia tentato di connettersi ad esso. Il onDisconnected
la funzione callback è disponibile anche per i dispositivi client e può essere utilizzata per riconnettersi agli host pubblicitari in caso di disconnessione imprevista.
Una volta connessi i dispositivi, è ora di iniziare a comunicare. Ci sono due tipi di messaggi che possono essere inviati, affidabile e inaffidabile. Se hai familiarità con la tecnologia di rete, puoi pensare a questi in termini di TCP (Transmission Control Protocol) e UDP (User Datagram Protocol). Una spiegazione semplificata è che i messaggi affidabili tenteranno nuovamente di inviare un messaggio se falliscono, mentre i messaggi inaffidabili semplicemente lasceranno cadere i dati se non vengono inviati e ricevuti correttamente.
Per questo tutorial, utilizzerai messaggi affidabili. Quando un messaggio viene ricevuto tramite l'API, onMessageReceived
sarà chiamato. Questo metodo accetta l'identificatore dell'endpoint, un payload e un booleano che indica se la connessione è affidabile o inaffidabile. Il carico utile contiene il messaggio e l'identificatore dell'endpoint è l'identificatore di qualsiasi dispositivo ha inviato il messaggio.
Nell'applicazione di esempio, la userai per visualizzare il carico utile come una stringa in a Visualizzazione elenco
e, se il dispositivo è l'host, ritrasmetterlo a tutti i dispositivi collegati.
@Override public void onMessageReceived (String endpointId, byte [] payload, boolean isReliable) mMessageAdapter.add (new String (payload)); mMessageAdapter.notifyDataSetChanged (); if (mIsHost) sendMessage (new String (payload));
Il invia messaggio
metodo è un metodo di supporto che dimostra due versioni di Nearby.Connections.sendReliableMessage
. Per le applicazioni host, sendReliableMessage
accetterà un elenco di endpoint a cui inviare il messaggio. Ciò consente di comunicare a più dispositivi con una sola riga di codice. Per i client, i messaggi devono solo andare all'host, quindi è necessario solo il nome host come parametro con il GoogleApiClient
e matrice di byte di messaggi.
private void sendMessage (String message) if (mIsHost) Nearby.Connections.sendReliableMessage (mGoogleApiClient, mRemotePeerEndpoints, message.getBytes ()); mMessageAdapter.add (messaggio); mMessageAdapter.notifyDataSetChanged (); else Nearby.Connections.sendReliableMessage (mGoogleApiClient, mRemoteHostEndpoint, (Nearby.Connections.getLocalDeviceId (mGoogleApiClient) + "dice:" + message) .getBytes ());
Quando sei pronto per disconnetterti sul lato host o client dell'applicazione, c'è un po 'di pulizia che deve avvenire. Per gli host, devi interrompere la pubblicità e disconnettere tutti i tuoi endpoint.
Nel codice di esempio, noterai che viene inviato anche un messaggio che tenta di comunicare ai peer che l'host si è disconnesso. In un'app più completa, vorresti che i tuoi clienti ascoltassero questo tipo di messaggio in modo che possano gestire la situazione in modo appropriato.
Se si tenta di disconnettersi su un client che non è ancora connesso a un host, è sufficiente interrompere la scoperta. Se sei già connesso a un host, chiami disconnectFromEndpoint
e l'API gestirà l'interruzione della connessione.
private void disconnect () if (! isConnectedToNetwork ()) return; if (mIsHost) sendMessage ("Chiusura dell'host"); Nearby.Connections.stopAdvertising (mGoogleApiClient); Nearby.Connections.stopAllEndpoints (mGoogleApiClient); mIsHost = falso; mStatusText.setText ("Non connesso"); mRemotePeerEndpoints.clear (); else if (! mIsConnected || TextUtils.isEmpty (mRemoteHostEndpoint)) Nearby.Connections.stopDiscovery (mGoogleApiClient, getString (R.string.service_id)); ritorno; sendMessage ("Disconnecting"); Nearby.Connections.disconnectFromEndpoint (mGoogleApiClient, mRemoteHostEndpoint); mRemoteHostEndpoint = null; mStatusText.setText ("Disconnected"); mIsConnected = false;
In questo tutorial, hai imparato come implementare la comunicazione tra vari dispositivi Android su una rete locale utilizzando l'API delle connessioni vicine. Ora dovresti essere in grado di migliorare le tue app collegando i dispositivi e mantenendoli sincronizzati tra loro con vari aggiornamenti.
Mentre questo tutorial ti ha illustrato un'applicazione client di chat abbastanza semplice, puoi prendere ciò che hai imparato qui per creare esperienze multiplayer lucidate, fornire schermate secondarie per gli utenti o rendere le tue app più contestualizzate fornendo un ulteriore canale di comunicazione per l'ambiente intorno a loro.
Poiché l'API delle connessioni vicine continua a crescere con l'aggiunta di beacon Eddystone e Bluetooth, questa sarà un'abilità preziosa da avere nello sviluppo di applicazioni Android.