Een van de vele API's die beschikbaar zijn in Google Play Services is de Dichtbij Connections API. Dit framework is begin 2015 geïntroduceerd en stelt u in staat één apparaat in te stellen waarop uw toepassing als host wordt uitgevoerd en waarmee meerdere andere apparaten verbinding kunnen maken om te communiceren via een Local Area Network (LAN).
Use cases voor deze functie zijn onder meer het verbinden van een telefoon met een Android TV voor het besturen van een app en het toestaan dat gebruikers deelnemen aan een multiplayer-game. In deze zelfstudie leert u hoe u toepassingen kunt instellen voor het verbinden van meerdere apparaten via een netwerk en hoe u gegevens over die verbinding kunt verzenden. Een werkvoorbeeld voor deze tutorial is te vinden op GitHub.
Nadat u uw oorspronkelijke programma hebt gemaakt in Android Studio, moet u de Play Services-bibliotheek importeren in uw app. Hiertoe plaatst u de volgende regel code onder het afhankelijkheidknooppunt van de build.gradle het dossier. Op het moment van schrijven is Play Services 7.5.0 de meest recente release voor ontwikkeling.
compileren 'com.google.android.gms: afspeelservices: 7.5.0'
Zodra Play Services is opgenomen in uw app, kunt u sluiten build.gradle en open AndroidManifest.xml. Aangezien deze functie een LAN gebruikt om te communiceren, moet u de ACCESS_NETWORK_STATE
toestemming in je manifest.
Vervolgens moet u een stukje toevoegen meta-data
in de toepassing
knooppunt dat een service-ID definieert dat door uw app wordt gebruikt, zodat het hosts kan ontdekken die adverteren met datzelfde ID. In dit voorbeeld is onze service-ID gedefinieerd in strings.xml zoals tutsplus_service_id
.
Wanneer je klaar bent met het manifest, kun je naar verplaatsen MainActivity.java. Dit is de klas waar we reclame en ontdekking zullen implementeren. In Hoofdactiviteit
, u beheert ook het verzenden van berichten tussen verschillende apparaten.
Om de API Nabijgelegen verbindingen te kunnen gebruiken, moet u een Google API-client instellen en hier verbinding mee maken. Begin met de implementatie ConnectionCallbacks
en OnConnectionFailedListener
aan de top van je klas. Terwijl we onze interfaces toevoegen, voegen we ook de drie toe die nodig zijn voor de API en een OnClickListener
.
openbare klasse MainActivity breidt AppCompatActivity implementeert GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, Connections.ConnectionRequestListener, Connections.MessageListener, Connections.EndpointDiscoveryListener, View.OnClickListener ...
Laten we nu de lidvariabelen maken die we nodig hebben voor deze zelfstudie boven aan de Hoofdactiviteit
klasse. Kortheidshalve vermeld ik eenvoudig dat de lay-out voor deze klasse bestaat uit een Lijstweergave
voor het weergeven van berichten, een Tekst bewerken
veld met een Knop
voor het verzenden van berichten na verbonden, a Knop
voor adverteren, verbinden of loskoppelen, afhankelijk van de rol van het apparaat, en a Tekstweergave
voor het weergeven van basisstatusinformatie.
U zult merken dat er twee booleaanse vlaggen zijn om aan te geven of het apparaat al dan niet is verbonden en of dit de verbindingshost is, GoogleApiClient
dat is nodig voor het gebruik van de Near Connections API en een array van gehele getallen voor het bijhouden van de netwerkverbindingstypes die we voor deze API zullen ondersteunen.
privé GoogleApiClient m GoogleApiClient; privé Spinner mTypeSpinner; privé TextView mStatusText; private Button mConnectionButton; privé-knop mSendButton; private ListView mListView; private ViewGroup mSendTextContainer; private EditText mSendEditText; privé ArrayAdaptermMessageAdapter; private boolean mIsHost; private boolean mIsConnected; private String mRemoteHostEndpoint; privélijst mRemotePeerEndpoints = nieuwe ArrayList (); privé statische finale lang CONNECTION_TIME_OUT = 10000L; private static int [] NETWORK_TYPES = ConnectivityManager.TYPE_WIFI, ConnectivityManager.TYPE_ETHERNET;
Als u eerder met Android-API-klassen voor Google heeft gewerkt, ziet het laatste instelscherm er redelijk bekend uit. U moet de initialiseren GoogleApiClient
en maak er verbinding mee onCreate
.
mGoogleApiClient = new GoogleApiClient.Builder (this) .addConnectionCallbacks (this) .addOnConnectionFailedListener (this) .addApi (Nearby.CONNECTIONS_API) .build ();
In onStart
en onStop
, wij behandelen het verbinden en loskoppelen.
@Override beschermde leegte onStart () super.onStart (); mGoogleApiClient.connect (); @Override beschermde ongeldig onStop () super.onStop (); if (mGoogleApiClient! = null &&GoogleApiClient.isConnected ()) mGoogleApiClient.disconnect ();
Nadat u verbinding hebt gemaakt met de Google API Client, kunt u gaan werken met verbindingen in de buurt. Het eerste onderdeel dat we zullen bespreken is reclame, waarmee een apparaat de rol van host kan aannemen en verbindingen tussen verschillende peers kan beheren voor communicatie.
Reclame zelf is redelijk eenvoudig. U hoeft alleen maar te controleren of het apparaat een acceptabel type verbinding heeft en vervolgens te bellen Nearby.Connections.StartAdvertising
met de juiste parameters. Dit zorgt ervoor dat het apparaat via uw LAN adverteert dat het beschikbaar is voor het accepteren van verbindingen van andere toepassingen.
In dit voorbeeld geven we een time-out van tien seconden door voor reclame. U kunt echter een waarde van geven 0
om voor onbepaalde tijd te adverteren. In de volgende code, isConnectedToNetwork
is een helpermethode die bedoeld is om te controleren of er reclame moet worden gemaakt.
private void advertise () if (! isConnectedToNetwork ()) terug; String naam = "Advertenties in de buurt"; Nearby.Connections.startAdvertising (mGoogleApiClient, name, null, CONNECTION_TIME_OUT, this) .setResultCallback (new ResultCallback() @Oeverride public unfid onResult (Connections.StartAdvertisingResult result) 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;
Zodra uw hosttoepassing reclame maakt, kan deze verbindingsverzoeken van peers ontvangen. Wanneer een apparaat verbinding probeert te maken, wordt de volgende methode aangeroepen:
public void onConnectionRequest (final String remoteEndpointId, final String remoteDeviceId, final String remoteEndpointName, byte [] payload)
Met deze methode kunt u de verbinding accepteren of weigeren. Om het verzoek te accepteren, belt u Nearby.Connections.acceptConnectionRequest
met een ResultsCallback
. U kunt dan acties uitvoeren, afhankelijk van of de verbinding met succes is geaccepteerd of niet.
Voor dit voorbeeld voegen we eenvoudig het externe eindpunt toe aan een lijst om het bij te houden en uit te zenden naar alle verbonden peers die dit nieuwe apparaat heeft verbonden. Als u om de een of andere reden vaststelt dat het apparaat geen verbinding mag maken met uw toepassing, kunt u dit weigeren door te bellen 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 public void onResult (Statusstatus) 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);
Net als adverteren, hangt het ontdekken ervan af van verbonden zijn met de GoogleApiClient
en met een acceptabele netwerkverbinding. U kunt de detectie starten door de service-id van de toepassing door te geven aan de Nearby.Connections.startDiscovery
methode, waarmee het apparaat van uw gebruiker in de detectiemodus wordt geplaatst.
Wanneer het apparaat een host detecteert die momenteel adverteert met behulp van de vooraf gedefinieerde service-id, wordt de onEndpointFound
terugbellen zal worden geactiveerd. Er moet worden opgemerkt dat deze methode meerdere keren kan worden aangeroepen als er meerdere hosts worden uitgezonden. In deze situatie kunt u een dialoogvenster voor uw gebruikers maken waarin alle beschikbare hosts worden weergegeven, zodat ze kunnen selecteren waarmee ze verbonden willen zijn.
Voor dit voorbeeld gaan we ervan uit dat er maar één hostadvertentie tegelijkertijd is, dus we zullen onmiddellijk verzoeken om verbinding te maken door te bellen Nearby.Connections.sendConnectionRequest
. Als de verbinding wordt geaccepteerd of afgewezen door de host, wordt de sendConnectionRequest
resultaat callback wordt gebeld. Als de verbinding wordt geaccepteerd, wordt de status ingesteld op succesvol en kunnen we de host-eindpunt-ID opslaan en voorbereiden op het verzenden van berichten via het verbindingskanaal.
private void discover () if (! isConnectedToNetwork ()) terug; String-serviceId = getString (R.string.service_id); Nearby.Connections.startDiscovery (mGoogleApiClient, serviceId, 10000L, this) .setResultCallback (new ResultCallback() @Oever openbare ongeldigheid onResult (statusstatus) if (status.isSuccess ()) mStatusText.setText ("Discovering"); else Log.e ("TutsPlus", "Ontdekken mislukt:" + 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, Statusstatus, byte [] bytes) if (status.isSuccess ()) mStatusText. setText ("Verbonden met:" + eindpuntId); Nearby.Connections.stopDiscovery (mGoogleApiClient, serviceId); mRemoteHostEndpoint = endpointId; mSendTextContainer.setVisibility (View.VISIBLE); if (! mIsHost) mIsConnected = true; else mStatusText .setText ("Connection to" + endpointId + "failed"); if (! mIsHost) mIsConnected = false;, this);
In een situatie waarin u naar meerdere eindpunten luistert om een keuze voor uw gebruikers te presenteren, de onEndpointLost
methode laat u weten of een host is gestopt met adverteren voordat uw gebruiker heeft geprobeerd verbinding te maken. De onDisconnected
callback is ook beschikbaar voor clientapparaten en kan worden gebruikt voor het opnieuw verbinden met advertentiehosts in het geval van een onverwachtse verbreking van de verbinding.
Zodra uw apparaten met elkaar zijn verbonden, is het tijd om te beginnen met communiceren. Er zijn twee soorten berichten die kunnen worden verzonden, betrouwbaar en onbetrouwbaar. Als u bekend bent met netwerktechnologie, kunt u hieraan denken in termen van TCP (Transmission Control Protocol) en UDP (User Datagram Protocol). Een vereenvoudigde uitleg is dat betrouwbare berichten opnieuw proberen om een bericht te verzenden als ze falen, terwijl onbetrouwbare berichten de gegevens eenvoudigweg laten vallen als deze niet met succes worden verzonden en ontvangen.
Voor deze zelfstudie gebruikt u betrouwbare berichten. Wanneer een bericht wordt ontvangen via de API, onMessageReceived
zal gebeld worden. Deze methode accepteert de eindpunt-ID, een payload en een booleaanse waarde die aangeeft of de verbinding betrouwbaar of onbetrouwbaar is. De payload bevat het bericht en de endpoint-ID is de identifier van het apparaat dat het bericht heeft verzonden.
In de voorbeeldtoepassing gebruikt u deze om de payload weer te geven als een tekenreeks in a Lijstweergave
en, als het apparaat de host is, opnieuw uitzenden naar elk aangesloten apparaat.
@Override public void onMessageReceived (String endpointId, byte [] payload, boolean isReliable) mMessageAdapter.add (new String (payload)); mMessageAdapter.notifyDataSetChanged (); if (mIsHost) sendMessage (new String (payload));
De bericht versturen
methode is een hulpmethode die twee versies van laat zien Nearby.Connections.sendReliableMessage
. Voor hosttoepassingen, sendReliableMessage
accepteert een lijst met eindpunten om het bericht naartoe te sturen. Hiermee kunt u communiceren met meerdere apparaten met één regel code. Voor clients hoeven berichten alleen naar de host te gaan, dus alleen de hostnaam is nodig als parameter bij de host GoogleApiClient
en message byte array.
private void sendMessage (String-bericht) if (mIsHost) Nearby.Connections.sendReliableMessage (mGoogleApiClient, mRemotePeerEndpoints, message.getBytes ()); mMessageAdapter.add (bericht); mMessageAdapter.notifyDataSetChanged (); else Nearby.Connections.sendReliableMessage (mGoogleApiClient, mRemoteHostEndpoint, (Nearby.Connections.getLocalDeviceId (mGoogleApiClient) + "zegt:" + bericht) .getBytes ());
Wanneer u klaar bent om de verbinding met de host- of clientzijde van de toepassing te verbreken, moet er een klein beetje opschoning plaatsvinden. Voor hosts moet u stoppen met adverteren en al uw eindpunten ontkoppelen.
In de voorbeeldcode ziet u dat er ook een bericht wordt verzonden dat peers probeert te laten weten dat de host de verbinding heeft verbroken. In een completere app wilt u dat uw klanten naar dit soort berichten luisteren, zodat zij de situatie op de juiste manier kunnen afhandelen.
Als u probeert verbinding te maken met een client die nog geen verbinding met een host heeft, hoeft u de detectie alleen te stoppen. Als je al verbinding hebt gemaakt met een host, bel je disconnectFromEndpoint
en de API zal de verbinding verbreken.
private void disconnect () if (! isConnectedToNetwork ()) terug; if (mIsHost) sendMessage ("Host afsluiten"); Nearby.Connections.stopAdvertising (mGoogleApiClient); Nearby.Connections.stopAllEndpoints (mGoogleApiClient); mIsHost = false; mStatusText.setText ("Niet verbonden"); mRemotePeerEndpoints.clear (); else if (! mIsConnected || TextUtils.isEmpty (mRemoteHostEndpoint)) Nearby.Connections.stopDiscovery (mGoogleApiClient, getString (R.string.service_id)); terug te keren; sendMessage ("Ontkoppelen"); Nearby.Connections.disconnectFromEndpoint (mGoogleApiClient, mRemoteHostEndpoint); mRemoteHostEndpoint = null; mStatusText.setText ("Disconnected"); mIsConnected = false;
In deze zelfstudie hebt u geleerd hoe u communicatie tussen verschillende Android-apparaten via een Local Area Network kunt implementeren met behulp van de Near Connections API. U zou nu in staat moeten zijn om uw eigen apps te verbeteren door apparaten aan elkaar te koppelen en ze door verschillende updates met elkaar te synchroniseren.
Hoewel deze tutorial je door een vrij eenvoudige chat-clienttoepassing heeft geleid, kun je wat je hier hebt geleerd, gebruiken om gepolijste multiplayer-ervaringen te creëren, secundaire schermen voor gebruikers te bieden of je apps contextair bewuster te maken door een extra communicatiekanaal voor de omgeving te bieden om hen heen.
Omdat de API van Near Connections blijft groeien met de toevoeging van Eddystone bakens en Bluetooth, zal dit een onschatbare vaardigheid blijken te zijn bij het ontwikkelen van Android-applicaties.