Google Play-Dienste Verwenden der API für nahegelegene Verbindungen

Einführung

Eine der vielen in den Google Play Services verfügbaren APIs ist die API für Verbindungen in der Nähe. Dieses Framework wurde Anfang 2015 eingeführt und ermöglicht Ihnen, ein Gerät, auf dem Ihre Anwendung ausgeführt wird, als Host festzulegen und mehrere andere Geräte damit zu verbinden, um über ein Gerät kommunizieren zu können Lokales Netzwerk (LAN).

Anwendungsfälle für diese Funktion umfassen das Anschließen eines Telefons an ein Android-Fernsehgerät, um eine App zu steuern und Benutzern die Teilnahme an einem Multiplayer-Spiel zu ermöglichen. In diesem Lernprogramm erfahren Sie, wie Sie Anwendungen zum Verbinden mehrerer Geräte über ein Netzwerk einrichten und Daten über diese Verbindung senden. Ein funktionierendes Beispiel für dieses Lernprogramm finden Sie auf GitHub.

1. Projekteinrichtung

Nachdem Sie Ihr ursprüngliches Programm in Android Studio erstellt haben, müssen Sie die Play Services-Bibliothek in Ihre App importieren. Platzieren Sie dazu die folgende Codezeile unter dem Abhängigkeitsknoten von build.gradle Datei. Zum jetzigen Zeitpunkt ist Play Services 7.5.0 die neueste Version für die Entwicklung.

"com.google.android.gms: play-services: 7.5.0" kompilieren

Sobald Play Services in Ihrer App enthalten ist, können Sie sie schließen build.gradle und offen AndroidManifest.xml. Da diese Funktion ein LAN für die Kommunikation verwendet, müssen Sie das ACCESS_NETWORK_STATE Erlaubnis in Ihrem Manifest.

Als Nächstes müssen Sie ein Stück hinzufügen Metadaten in dem Anwendung Knoten, der eine Dienstkennung definiert, die von Ihrer App verwendet wird, um Hosts mit derselben Kennung zu erkennen. In diesem Beispiel ist unsere Service-ID in definiert strings.xml wie tutsplus_service_id.

Wenn Sie mit dem Manifest fertig sind, können Sie zu wechseln MainActivity.java. In dieser Klasse werden wir sowohl Werbung als auch Discovery implementieren. Im Hauptaktivität, Sie können auch das Senden von Nachrichten zwischen verschiedenen Geräten steuern.

Damit Sie die API für nahegelegene Verbindungen verwenden können, müssen Sie den Google API-Client einrichten und eine Verbindung herstellen. Beginnen Sie mit der Implementierung ConnectionCallbacks und OnConnectionFailedListener an der Spitze Ihrer Klasse. Während wir unsere Schnittstellen hinzufügen, fügen wir auch die drei hinzu, die von der API und einer benötigt werden OnClickListener.

Öffentliche Klasse MainActivity erweitert AppCompatActivity implementiert GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, Connections.ConnectionRequestListener, Connections.MessageListener, Connections.EndpointDiscoveryListener, View.OnClickListener. 

Lassen Sie uns nun die Member-Variablen erstellen, die wir für dieses Tutorial oben in der Hauptaktivität Klasse. Der Kürze halber möchte ich nur erwähnen, dass das Layout für diese Klasse aus a besteht Listenansicht zur Anzeige von Nachrichten, eine Text bearbeiten Feld mit einem Taste zum Senden von Nachrichten nach verbundener Verbindung, a Taste je nach Rolle des Geräts für Werbung, Verbinden oder Trennen der Verbindung, und a Textvorschau zur Anzeige grundlegender Zustandsinformationen.

Sie werden feststellen, dass es zwei boolesche Flags gibt, die angeben, ob das Gerät angeschlossen ist oder nicht und ob es sich bei dem Verbindungshost um das Gerät handelt GoogleApiClient Dies ist für die Verwendung der API für nahegelegene Verbindungen und ein Array von Ganzzahlen zum Verfolgen der Netzwerkverbindungstypen erforderlich, die für diese API unterstützt werden.

privater GoogleApiClient mGoogleApiClient; privater Spinner mTypeSpinner; private TextView mStatusText; private Schaltfläche mConnectionButton; privater Button mSendButton; private ListView mListView; private ViewGroup mSendTextContainer; private EditText mSendEditText; privater ArrayAdapter mMessageAdapter; private boolean mIsHost; private boolean mIsConnected; private String mRemoteHostEndpoint; private Liste mRemotePeerEndpoints = neue ArrayList(); private statische letzte Länge CONNECTION_TIME_OUT = 10000L; private static int [] NETWORK_TYPES = ConnectivityManager.TYPE_WIFI, ConnectivityManager.TYPE_ETHERNET;

Wenn Sie bereits mit Android-Google-API-Klassen gearbeitet haben, sollte das letzte Setup etwas vertraut sein. Sie müssen das initialisieren GoogleApiClient und verbinden Sie sich damit onCreate.

mGoogleApiClient = new GoogleApiClient.Builder (this) .addConnectionCallbacks (this) .addOnConnectionFailedListener (this) .addApi (Nearby.CONNECTIONS_API) .build ();

Im am Start und onStop, Wir erledigen das Verbinden und Trennen.

@Override protected void onStart () super.onStart (); mGoogleApiClient.connect ();  @Override protected void onStop () super.onStop (); if (mGoogleApiClient! = null && mGoogleApiClient.isConnected ()) mGoogleApiClient.disconnect (); 

2. Werbung und Akzeptieren von Verbindungen

Sobald Sie eine Verbindung zum Google API-Client hergestellt haben, können Sie mit Verbindungen in der Nähe beginnen. Die erste Komponente, die wir besprechen, ist Werbung, Dadurch kann ein Gerät die Rolle des Hosts übernehmen und Verbindungen zwischen verschiedenen Peers für die Kommunikation verwalten.

Die Werbung selbst ist ziemlich unkompliziert. Sie müssen lediglich prüfen, ob das Gerät über eine akzeptable Verbindungsart verfügt, und dann den Anruf tätigen In der Nähe.Verbindungen.StartWerbung mit den richtigen Parametern. Dadurch wird das Gerät in Ihrem LAN darauf aufmerksam gemacht, dass es für die Annahme von Verbindungen aus anderen Anwendungen verfügbar ist.

In diesem Beispiel haben wir für die Werbung einen Timeout von zehn Sekunden. Sie können jedoch einen Wert von übergeben 0 unbefristet werben. Im folgenden Code, isConnectedToNetwork ist eine Hilfsmethode, mit der geprüft werden soll, ob Werbung erscheint.

private void advertise () if (! isConnectedToNetwork ()) return; String name = "Werbung in der Nähe"; Nearby.Connections.startAdvertising (mGoogleApiClient, name, null, CONNECTION_TIME_OUT, this) .setResultCallback (neuer ResultCallback)() @Override public void onResult (Ergebnis von Connections.StartAdvertisingResult) if (result.getStatus (). IsSuccess ()) mStatusText.setText ("Advertising"); );  private boolean isConnectedToNetwork () ConnectivityManager connManager = (ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE); für (int networkType: NETWORK_TYPES) ​​NetworkInfo info = connManager.getNetworkInfo (networkType); if (info! = null && info.isConnectedOrConnecting ()) return true;   falsch zurückgeben; 

Sobald Ihre Hostanwendung Werbung macht, kann sie Verbindungsanfragen von Kollegen erhalten. Wenn ein Gerät versucht, eine Verbindung herzustellen, wird die folgende Methode aufgerufen:

public void onConnectionRequest (abschließender String remoteEndpointId, abschließender String remoteDeviceId, abschließender String remoteEndpointName, Byte [] Nutzlast)

Mit dieser Methode können Sie die Verbindung entweder annehmen oder ablehnen. Um die Anfrage anzunehmen, rufen Sie an Nearby.Connections.acceptConnectionRequest mit einer Ergebnisse Rückruf. Sie können dann Aktionen ausführen, je nachdem, ob die Verbindung erfolgreich angenommen wurde oder nicht.

In diesem Beispiel fügen wir den entfernten Endpunkt einfach einer Liste hinzu, um den Überblick zu behalten und an alle verbundenen Peers zu senden, die mit diesem neuen Gerät verbunden sind. Wenn Sie aus irgendeinem Grund feststellen, dass das Gerät keine Verbindung zu Ihrer Anwendung herstellen soll, können Sie es durch Aufruf abweisen Nearby.Connections.rejectConnectionRequest.

@Override public void onConnectionRequest (finaler String remoteEndpointId, finaler String remoteDeviceId, finaler String remoteEndpointName, Byte [] Nutzlast) if (mIsHost) Nearby.Connections.acceptConnectionRequest (mGoogleApiClient, remoteEndpointI, payload)() @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); 

3. Entdeckung

Genauso wie Werbung hängt Entdeckung davon ab, mit dem Internet verbunden zu sein GoogleApiClient und eine akzeptable Netzwerkverbindung haben. Sie können die Ermittlung starten, indem Sie die Dienstkennung der Anwendung an den Server übergeben Nearby.Connections.startDiscovery Methode, die das Gerät Ihres Benutzers in den Erkennungsmodus versetzt.

Wenn das Gerät mithilfe der vordefinierten Service-ID einen Host erkennt, der gerade Werbung macht, können Sie die onEndpointFound Rückruf wird ausgelöst. Es ist zu beachten, dass diese Methode mehrmals aufgerufen werden kann, wenn mehrere Hosts Broadcasting ausführen. In dieser Situation können Sie für Ihre Benutzer ein Dialogfeld erstellen, in dem alle verfügbaren Hosts angezeigt werden, sodass sie auswählen können, mit welchen Benutzern sie verbunden werden möchten.

In diesem Beispiel wird davon ausgegangen, dass jeweils nur ein Host-Inserat vorhanden ist. Daher werden wir sofort eine Verbindung per Anruf anfordern Nearby.Connections.sendConnectionRequest. Wenn die Verbindung vom Host akzeptiert oder abgelehnt wird, wird die sendConnectionRequest Ergebnis Callback wird aufgerufen. Wenn die Verbindung akzeptiert wird, wird der Status als erfolgreich festgelegt, und wir können die Host-Endpunktkennung speichern und das Senden von Nachrichten über den Verbindungskanal vorbereiten.

private void discover () if (! isConnectedToNetwork ()) return; String serviceId = getString (R.string.service_id); Nearby.Connections.startDiscovery (mGoogleApiClient, serviceId, 10000L, this) .setResultCallback (neuer ResultCallback)() @Override public void onResult (Statusstatus) if (status.isSuccess ()) mStatusText.setText ("Discovering");  else Log.e ("TutsPlus", "Erkennung fehlgeschlagen:" + status.getStatusMessage ()); );  @Override public void onEndpointFound (String endpointId, String deviceId, abschließender String serviceId, String endpointName) byte [] payload = null; Nearby.Connections.sendConnectionRequest (mGoogleApiClient, deviceId, endpointId, payload, neue Connections.ConnectionResponseCallback () @Override public void onConnectionResponse (Zeichenfolge endpointId, Status status, Byte [] bytes) if (status.isSuccess). setText ("Verbunden mit:" + endpointId); Nearby.Connections.stopDiscovery (mGoogleApiClient, serviceId); mRemoteHostEndpoint = endpointId; mSendTextContainer.setVisibility (View.VISIBLE); wenn (! mIsHost) mIsHost); .setText ("Verbindung mit" + endpointId + "fehlgeschlagen"); if (! mIsHost) mIsConnected = false;, this); 

In einer Situation, in der Sie auf mehrere Endpunkte warten, um Ihren Benutzern eine Auswahl zu präsentieren, die onEndpointLost Diese Methode teilt Ihnen mit, wenn ein Host keine Werbung mehr gemacht hat, bevor Ihr Benutzer versucht hat, sich mit dem Host zu verbinden. Das onDisconnected Callback ist auch für Clientgeräte verfügbar und kann im Falle einer unerwarteten Verbindungsunterbrechung zum erneuten Herstellen einer Verbindung mit Werbehosts verwendet werden.

4. Nachrichten senden

Sobald Ihre Geräte miteinander verbunden sind, können Sie mit der Kommunikation beginnen. Es gibt zwei Arten von Nachrichten, die gesendet werden können, zuverlässig und unzuverlässig. Wenn Sie mit der Netzwerktechnologie vertraut sind, können Sie sich diese in Bezug auf TCP (Transmission Control Protocol) und UDP (User Datagram Protocol). Eine vereinfachte Erklärung ist, dass zuverlässige Nachrichten erneut versuchen, eine Nachricht zu senden, wenn sie fehlschlagen, während unzuverlässige Nachrichten die Daten einfach löschen, wenn sie nicht erfolgreich gesendet und empfangen werden.

Für dieses Tutorial verwenden Sie zuverlässige Nachrichten. Wenn eine Nachricht über die API empfangen wird, onMessageReceived wird angerufen werden. Diese Methode akzeptiert die Endpunktkennung, eine Nutzlast und einen Booleschen Wert, der angibt, ob die Verbindung zuverlässig oder unzuverlässig ist. Die Payload enthält die Nachricht und die Endpunktkennung ist die Kennung des Geräts, das die Nachricht gesendet hat.

In der Beispielanwendung verwenden Sie dies, um die Nutzdaten als Zeichenfolge in a anzuzeigen Listenansicht und wenn das Gerät der Host ist, senden Sie es an jedes angeschlossene Gerät.

@Override public void onMessageReceived (String endpointId, byte [] payload, boolean isReliable) mMessageAdapter.add (neuer String (payload)); mMessageAdapter.notifyDataSetChanged (); if (mIsHost) sendMessage (neuer String (Nutzlast)); 

Das Nachricht senden method ist eine Hilfsmethode, die zwei Versionen von demonstriert Nearby.Connections.sendReliableMessage. Für Hostanwendungen, sendReliableMessage akzeptiert eine Liste von Endpunkten, an die die Nachricht gesendet werden soll. Dies ermöglicht Ihnen die Kommunikation mit mehreren Geräten mit einer Codezeile. Bei Clients müssen Nachrichten nur an den Host gesendet werden, sodass nur der Hostname als Parameter mit der Option benötigt wird GoogleApiClient und Nachrichtenbyte-Array.

private void sendMessage (String message) if (mIsHost) Nearby.Connections.sendReliableMessage (mGoogleApiClient, mRemotePeerEndpoints, message.getBytes ()); mMessageAdapter.add (Nachricht); mMessageAdapter.notifyDataSetChanged ();  else Nearby.Connections.sendReliableMessage (mGoogleApiClient, mRemoteHostEndpoint, (Nearby.Connections.getLocalDeviceId (mGoogleApiClient) + "sagt:" + message) .getBytes ()); 

5. Verbindung trennen

Wenn Sie bereit sind, die Verbindung entweder auf der Host- oder auf der Clientseite der Anwendung zu trennen, müssen Sie ein wenig aufräumen. Für Hosts müssen Sie die Werbung stoppen und alle Ihre Endpunkte trennen.

Im Beispielcode werden Sie feststellen, dass auch eine Nachricht gesendet wird, mit der versucht wird, Peers darüber zu informieren, dass der Host die Verbindung getrennt hat. In einer vollständigeren App möchten Sie, dass Ihre Kunden auf diese Art von Nachrichten warten, damit sie die Situation angemessen behandeln können.

Wenn Sie versuchen, die Verbindung zu einem Client zu trennen, der noch keine Verbindung zu einem Host hergestellt hat, müssen Sie die Erkennung einfach beenden. Wenn Sie bereits mit einem Host verbunden sind, rufen Sie an disconnectFromEndpoint und die API übernimmt das Trennen der Verbindung.

private void disconnect () if (! isConnectedToNetwork ()) return; if (mIsHost) sendMessage ("Host herunterfahren"); Nearby.Connections.stopAdvertising (mGoogleApiClient); Nearby.Connections.stopAllEndpoints (mGoogleApiClient); mIsHost = false; mStatusText.setText ("Nicht verbunden"); mRemotePeerEndpoints.clear ();  else if (! mIsConnected || TextUtils.isEmpty (mRemoteHostEndpoint)) Nearby.Connections.stopDiscovery (mGoogleApiClient, getString (R.string.service_id)); Rückkehr;  sendMessage ("Verbindung trennen"); Nearby.Connections.disconnectFromEndpoint (mGoogleApiClient, mRemoteHostEndpoint); mRemoteHostEndpoint = null; mStatusText.setText ("Disconnected");  mIsConnected = false; 

Fazit

In diesem Lernprogramm haben Sie gelernt, wie Sie die Kommunikation zwischen verschiedenen Android-Geräten über ein lokales Netzwerk mithilfe der API für nahegelegene Verbindungen implementieren. Sie sollten jetzt in der Lage sein, Ihre eigenen Apps zu verbessern, indem Sie Geräte miteinander verbinden und sie durch verschiedene Updates miteinander synchronisieren.

Während dieses Lernprogramm Sie durch eine recht einfache Chat-Client-Anwendung geführt hat, können Sie das Erlernte nutzen, um erstklassige Multiplayer-Erlebnisse zu erstellen, sekundäre Bildschirme für Benutzer bereitzustellen oder Ihre Apps kontextabhängiger zu machen, indem Sie einen zusätzlichen Kommunikationskanal für die Umgebung bereitstellen um sie herum.

Da die API für nahegelegene Verbindungen mit Eddystone-Beacons und Bluetooth immer weiter wächst, wird sich dies als unschätzbare Fähigkeit bei der Entwicklung von Android-Anwendungen erweisen.