[JAVA] Android 8.0 - Wi-Fi Aware Memo

Unten ↓ maschinelle Übersetzung https://developer.android.com/guide/topics/connectivity/wifi-aware.html#create_a_connection

Überblick

On some devices running Android 8.0 (API level 26) and higher, Wi-Fi Aware provides the ability to discover and connect directly to each other without any other type of connectivity between them, such as Wi-Fi Access Point or Cellular. Wi-Fi Aware is also known as Neighbor Awareness Networking or NAN.

Auf einigen Geräten mit Android 8.0 (API-Stufe 26) oder höher kann Wi-Fi Aware, wie z. B. Wi-Fi Access Points und Cellular, ohne andere Verbindungstypen eine direkte Verbindung erkennen und eine Verbindung herstellen. .. Wi-Fi Aware wird auch als Neighbor Awareness Networking oder NAN bezeichnet.

Wi-Fi Aware networking works by forming clusters with neighboring devices, or by creating a new cluster if the device is the first one in an area. This clustering behavior is device-wide—apps have no control over clustering behavior—and the behavior is managed by the Wi-Fi Aware system service. Apps use the Wi-Fi Aware APIs to talk to the Wi-Fi Aware system service which, in turn, manages the Wi-Fi Aware hardware on the device.

Wi-Fi-fähige Netzwerke bilden einen Cluster mit benachbarten Geräten oder erstellen einen neuen Cluster, wenn das Gerät das erste in der Region ist. Das Verhalten dieses Clusters ist geräteweit, die Anwendung hat keine Kontrolle über das Clusterverhalten und dieses Verhalten wird von den Wi-Fi Aware System Services verwaltet. Die App verwendet die Wi-Fi Aware-API, um mit dem Wi-Fi Aware-Systemdienst zu kommunizieren, der die Wi-Fi Aware-Hardware auf dem Gerät verwaltet.

The Wi-Fi Aware APIs are available to apps that target Android 8.0 (API level 26), and let apps perform the following operations:

Die Wi-Fi Aware-API kann in Anwendungen für Android 8.0 (API-Stufe 26) verwendet werden und ermöglicht der App Folgendes:

Andere Geräte entdecken - Die API verfügt über einen Mechanismus zum Auffinden anderer Geräte in der Nähe. Der Prozess beginnt, wenn ein Gerät einen erkennbaren Dienst verfügbar macht. Wenn das Gerät dann einen oder mehrere Dienste abonniert und den Wi-Fi-Bereich des Herausgebers betritt, wird der Teilnehmer benachrichtigt, dass ein passender Herausgeber gefunden wurde. Nachdem der Teilnehmer den Herausgeber erkannt hat, kann der Teilnehmer eine Kurznachricht senden oder eine Netzwerkverbindung mit dem erkannten Gerät herstellen.

Erstellen einer Netzwerkverbindung - Sie können eine bidirektionale Wi-Fi Aware-Netzwerkverbindung ohne Zugriffspunkt erstellen, nachdem sich die beiden Geräte über Wi-Fi Aware Discovery oder andere Mechanismen wie Bluetooth oder BLE erkannt haben.

Wi-Fi Aware network connections are more reliable than Wi-Fi P2P connections and support higher throughput rates across longer distances than Bluetooth connections. These types of connections are useful for apps that share data between users, such as photo-sharing apps.

Wi-Fi-fähige Netzwerkverbindungen sind zuverlässiger als Wi-Fi P2P-Verbindungen und unterstützen einen höheren Durchsatz über größere Entfernungen als Bluetooth-Verbindungen. Diese Arten von Verbindungen sind nützlich für Apps, die Daten zwischen Benutzern austauschen, z. B. Foto-Sharing-Apps.

Wi-Fi Aware Setup

Berechtigungen festlegen

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Überprüfen Sie die Wi-Fi Aware-Unterstützung für Ihr Gerät

context.getPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE);

Registrierung des Rundfunkempfängers zum Empfang einer Benachrichtigung über Änderungen der Verfügbarkeit von Wi-Fi Aware

IntentFilter filter =
    new IntentFilter(WifiAwareManager.WIFI_AWARE_STATE_CHANGED_ACTION);
BroadcastReceiver myReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(final Context context, final Intent intent) {
        if (WifiAwareManager.isAvailable()) {
            //Wi-Was tun, wenn Fi Aware verfügbar ist?
        } else {
            //Wi-Was tun, wenn Fi Aware nicht mehr verfügbar ist?
        }
    }
};
context.registerReceiver(myReceiver, filter);

Sitzung abrufen

To start using Wi-Fi Aware, your app must obtain a WifiAwareSession by calling attach(). This method does the following:

Um mit Wi-Fi Aware zu beginnen, muss Ihre Anwendung attach () aufrufen, um eine WifiAwareSession zu erhalten. Diese Methode führt Folgendes aus:

Service veröffentlichen

Rufen Sie die WiFiAwareSession # Publish () -Methode auf, um den Dienst erkennbar zu machen.

PublishConfig config = new PublishConfig.Builder()
    .setServiceName(AWARE_FILE_SHARE_SERVICE_NAME)
    .build();

mAwareSession.publish(config, new DiscoverySessionCallback() {
    @Override
    public void onPublishStarted(PublishDiscoverySession session) {
        //Wird aufgerufen, wenn die Veröffentlichung erfolgreich ist.
        //Das Gerät, auf dem die passende Teilnehmer-App ausgeführt wird, ist das Wi des öffentlichen Geräts-Wenn Sie in den Fi-Bereich wechseln, erkennt der Teilnehmer den Dienst. Wenn ein Abonnent einen Herausgeber entdeckt, wird der Herausgeber erst benachrichtigt, wenn der Abonnent eine Nachricht an den Herausgeber sendet.
    }
    @Override
    public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
        //Der Herausgeber erhält eine Benachrichtigung, wenn der Abonnent eine Nachricht an den Herausgeber sendet. In diesem Fall wird die Rückrufmethode onMessageReceived () ausgeführt. Mit dem PeerHandle-Argument dieser Methode können Sie eine Nachricht an den Abonnenten zurücksenden oder eine Verbindung zum Abonnenten herstellen.
    }, null);

To stop publishing the service, call DiscoverySession.close(). Discovery sessions are associated with their parent WifiAwareSession. If the parent session is closed, its associated discovery sessions are also closed. However, the system doesn't guarantee when out-of-scope sessions are closed, so we recommend that you manually call DiscoverySession.close().

Um die Veröffentlichung des Dienstes zu beenden, rufen Sie DiscoverySession.close () auf. Die Erkennungssitzung ist der übergeordneten WifiAwareSession zugeordnet. Wenn die übergeordnete Sitzung geschlossen ist, wird auch die zugehörige Erkennungssitzung geschlossen. Es ist jedoch nicht garantiert, wenn eine Sitzung außerhalb des Gültigkeitsbereichs geschlossen wird. Daher wird empfohlen, DiscoverySession.close () manuell aufzurufen.

Serviceabonnement

Rufen Sie die WiFiAwareSession # subscribe () -Methode auf, um den Dienst zu abonnieren.

SubscribeConfig config = new SubscribeConfig.Builder()
    .setServiceName(AWARE_FILE_SHARE_SERVICE_NAME)
    .build();

mAwareSession.subscribe(config, new DiscoverySessionCallback() {
    @Override
    public void onSubscribeStarted(SubscribeDiscoverySession session) {
        //Wenn der Abonnementvorgang erfolgreich ist, führt das System in der Anwendung einen onSubscribeStarted () - Rückruf durch. Sie müssen diese Referenz speichern, da Sie das SubscribeDiscoverySession-Argument im Rückruf verwenden können, um mit dem Herausgeber zu kommunizieren, nachdem die App ihn erkannt hat. Sie können die Beschreibung jederzeit aktualisieren, indem Sie updateSubscribe () in der Erkennungssitzung aufrufen.
    }

    @Override
    public void onServiceDiscovered(PeerHandle peerHandle,
            byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
        //Passender Verlag ist Wi-In Fi führt das System die Rückrufmethode onServiceDiscovered () aus. Sie können das PeerHandle-Argument in diesem Rückruf verwenden, um eine Nachricht zu senden oder eine Verbindung zu diesem Herausgeber herzustellen.
    }
}, null);

Nachricht senden

To send a message to another device, you need the following objects: A DiscoverySession. This object allows you to call sendMessage(). Your app gets a DiscoverySession by either publishing a service or subscribing to a service. The other device's PeerHandle, so you know where to send the message. Your app gets another device's PeerHandle in one of two ways: Your app publishes a service. Then, when it receives a message from a subscriber, your app gets the subscriber's PeerHandle from the onMessageReceived() callback. Your app subscribes to a service. Then, when it discovers a matching publisher, your app gets the publisher's PeerHandle from the onServiceDiscovered() callback. To send a message, call sendMessage(). The following callbacks might then occur:

Um eine Nachricht an ein anderes Gerät zu senden, benötigen Sie die folgenden Objekte: Ermittlungssitzung. Mit diesem Objekt können Sie sendMessage () aufrufen. Ihre App erhält eine Discovery-Sitzung, indem Sie den Dienst veröffentlichen oder abonnieren. PeerHandle auf anderen Geräten weiß, wohin die Nachricht gesendet werden soll. Ihre App erhält PeerHandle auf zwei Arten auf einem anderen Gerät: Ihre App veröffentlicht den Dienst. Wenn die Anwendung dann eine Nachricht vom Abonnenten empfängt, erhält sie das PeerHandle des Abonnenten vom Rückruf onMessageReceived (). Ihre App hat den Dienst abonniert. Wenn dann ein passender Herausgeber gefunden wird, erhält er das PeerHandle des Herausgebers aus dem Rückruf onServiceDiscovered (). Rufen Sie sendMessage () auf, um eine Nachricht zu senden. Folgende Rückrufe können auftreten:

When the message is successfully received by the peer, the system executes the onMessageSendSucceeded() callback in the sending app. When the peer receives a message, the system executes the onMessageReceived() callback in the receiving app. Note: Messages are generally used for lightweight messaging, as they might not be delivered and are limited to about 255 bytes in length. To determine the exact length limit, call getMaxServiceSpecificInfoLength(). For high speed, bi-directional communication, your app should create a connection instead.

Wenn die Nachricht erfolgreich vom Peer empfangen wurde, führt das System in der sendenden App einen Rückruf onMessageSendSucceeded () durch. Wenn der Peer die Nachricht empfängt, führt die empfangende Anwendung einen onMessageReceived () - Rückruf durch. Hinweis: Nachrichten werden häufig für einfache Nachrichten verwendet. Dies liegt daran, dass die Nachricht möglicherweise nicht zugestellt wird und auf eine Länge von ungefähr 255 Byte begrenzt ist. Rufen Sie getMaxServiceSpecificInfoLength () auf, um die genaue Längenbeschränkung zu ermitteln. Für die bidirektionale Hochgeschwindigkeitskommunikation sollte die App stattdessen eine Verbindung herstellen.

Verbindung

There are two ways to create a Wi-Fi Aware connection. The first way assumes that you have used Wi-Fi Aware to discover the other device and you have the other device's PeerHandle. The second way assumes that you have discovered the other device's MAC address through some other mechanism, such as Bluetooth or BLE. This is known as out-of-band discovery, or OOB.

Es gibt zwei Möglichkeiten, eine Wi-Fi Aware-Verbindung herzustellen. Bei der ersten Methode wird davon ausgegangen, dass Sie Wi-Fi Aware verwenden, um andere Geräte zu erkennen, und den PeerHandle des anderen Geräts verwenden. Bei der zweiten Methode wird davon ausgegangen, dass Sie die MAC-Adresse eines anderen Geräts mithilfe anderer Mechanismen wie Bluetooth oder BLE erkannt haben. Dies wird als Out-of-Band-Erkennung oder OOB bezeichnet.

Regardless of which method you choose, there are always two devices in a Wi-Fi Aware connection: an initiator and a responder. If you're using Wi-Fi Aware discovery, then the roles are fixed and don't need to be explicitly specified: the subscriber is the initiator and the publisher is the responder. If you are using out-of-band discovery, then the devices need to negotiate these roles on their own.

Unabhängig davon, für welche Methode Sie sich entscheiden, befinden sich in Ihrer Wi-Fi Aware-Verbindung immer zwei Geräte: der Initiator und der Responder. Wenn Sie die Wi-Fi Aware-Erkennung verwenden, ist die Rolle festgelegt und muss nicht explizit angegeben werden. Der Abonnent ist der Initiator und der Herausgeber ist der Antwortende. Wenn Sie die Out-of-Band-Erkennung verwenden, muss Ihr Gerät diese Rollen selbst aushandeln.

To create a connection, complete the following sequence of steps:

  1. Create a network specifier: For Wi-Fi Aware discovery, call either DiscoverySession.createNetworkSpecifierOpen() or DiscoverySession.createNetworkSpecifierPassphrase() from the publisher and subscriber. For OOB discovery, call either WifiAwareSession.createNetworkSpecifierOpen() or WifiAwareSession.createNetworkSpecifierPassphrase() from both devices. The responder isn't required to provide a MAC address or a PeerHandle. If no MAC address or PeerHandle is specified, the device accepts all connection requests.

Gehen Sie wie folgt vor, um eine Verbindung herzustellen:

  1. Erstellen Sie einen Netzwerkspezifizierer: Rufen Sie für die Wi-Fi Aware-Erkennung DiscoverySession.createNetworkSpecifierOpen () oder DiscoverySession.createNetworkSpecifierPassphrase () von Herausgebern und Abonnenten auf. Rufen Sie für die OOB-Erkennung von beiden Geräten aus WifiAwareSession.createNetworkSpecifierOpen () oder WifiAwareSession.createNetworkSpecifierPassphrase () auf. Der Responder muss keine MAC-Adresse oder PeerHandle angeben. Wenn keine MAC-Adresse oder kein PeerHandle angegeben ist, akzeptiert das Gerät alle Verbindungsanforderungen.
  1. Build a network request, setting the transport mechanism to TRANSPORT_WIFI_AWARE:

Setzen Sie den Transportmechanismus auf TRANSPORT_WIFI_AWARE, um eine Netzwerkanforderung zu erstellen.

NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
     .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
     .setNetworkSpecifier(networkSpecifier)
     .build();
  1. Call requestNetwork() and provide the following callback methods:

Rufen Sie requestNetwork () auf und geben Sie die folgende Rückrufmethode an:

mCallback = new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        ...
    }
    @Override
    public void onLinkPropertiesChanged(Network network,
            LinkProperties linkProperties) {
        ...
    }
    @Override
    public void onLost(Network network) {
        ...
    }
};
mConnMgr.requestNetwork(networkRequest, mCallback);

The appropriate callback methods are executed when the network connection is available, changed, or lost.

Geeignete Rückrufmethoden werden ausgeführt, wenn eine Netzwerkverbindung verfügbar ist, geändert wird oder verloren geht.

4 When you're finished with the network connection, call unregisterNetworkCallback(). Note: Building a network request and specifying the required network capabilities aren't specific to the Wi-Fi Aware API. For more information on working with network requests, see ConnectivityManager.

Rufen Sie unregisterNetworkCallback () auf, wenn die Netzwerkverbindung geschlossen ist. Hinweis: Das Erstellen von Netzwerkanforderungen und das Festlegen der erforderlichen Netzwerkfunktionen ist nicht spezifisch für die Wi-Fi Aware-API. Weitere Informationen zum Behandeln von Netzwerkanforderungen finden Sie unter Connectivity Manager.


Erstellen einer Test-App basierend auf den oben genannten

Herausgeberseite, die mit der Veröffentlichung beginnt und Nachrichten von Abonnenten empfängt, die auf die oben genannten Punkte verweisen Probieren Sie die App und die abonnementseitige App-Implementierung aus, die abonniert und Nachrichten an den Herausgeber sendet.

Publisher-Aktivität

package com.example.user.wifiawaretest;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.net.wifi.aware.AttachCallback;
import android.net.wifi.aware.DiscoverySessionCallback;
import android.net.wifi.aware.PeerHandle;
import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.PublishDiscoverySession;
import android.net.wifi.aware.WifiAwareManager;
import android.net.wifi.aware.WifiAwareSession;
import android.os.Handler;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends Activity {

    private WifiAwareSession mAwareSession;
    private Handler mHandler = new Handler();
    public static final String AWARE_SERVICE_NAME = "Aware Service";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)) {
            Toast.makeText(this, "Wi-Fi Aware not supoortted", Toast.LENGTH_SHORT).show();
            return;
        }

        WifiAwareManager was = (WifiAwareManager)getSystemService(WifiAwareManager.class);

        was.attach(new MyAttachCallback(), mHandler);
    }

    class MyAttachCallback extends AttachCallback {
        @Override
        public void onAttachFailed() {
            Toast.makeText(MainActivity.this, "onAttachFailed", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onAttached(WifiAwareSession session) {
            Toast.makeText(MainActivity.this, "onAttach", Toast.LENGTH_SHORT).show();

            MainActivity.this.mAwareSession = session;
            PublishConfig config = new PublishConfig.Builder()
                    .setServiceName(AWARE_SERVICE_NAME)
                    .build();
            MainActivity.this.mAwareSession.publish(config, new DiscoverySessionCallback() {
                @Override
                public void onPublishStarted(PublishDiscoverySession session) {
                    Toast.makeText(MainActivity.this, "onPublishStarted", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
                    Toast.makeText(MainActivity.this, "onMessageReceived : " + message.toString(), Toast.LENGTH_SHORT).show();
                }
            }, null);
        }
    }
}

Abonnentenseite

package com.example.user.wifiawaresubscribertest;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.net.wifi.aware.AttachCallback;
import android.net.wifi.aware.DiscoverySessionCallback;
import android.net.wifi.aware.PeerHandle;
import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.PublishDiscoverySession;
import android.net.wifi.aware.SubscribeConfig;
import android.net.wifi.aware.SubscribeDiscoverySession;
import android.net.wifi.aware.WifiAwareManager;
import android.net.wifi.aware.WifiAwareSession;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import java.util.List;

public class MainActivity extends Activity {

    private WifiAwareSession mAwareSession;
    private Handler mHandler = new Handler();
    public static final String AWARE_SERVICE_NAME = "Aware Service";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)) {
            Toast.makeText(this, "Wi-Fi Aware not supoortted", Toast.LENGTH_SHORT).show();
            return;
        }

        WifiAwareManager was = (WifiAwareManager)getSystemService(WifiAwareManager.class);

        was.attach(new MyAttachCallback(), mHandler);
    }

    class MyAttachCallback extends AttachCallback {
        @Override
        public void onAttachFailed() {
            Toast.makeText(MainActivity.this, "onAttachFailed", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onAttached(WifiAwareSession session) {
            Toast.makeText(MainActivity.this, "onAttach", Toast.LENGTH_SHORT).show();

            MainActivity.this.mAwareSession = session;

            SubscribeConfig config = new SubscribeConfig.Builder()
                    .setServiceName(AWARE_SERVICE_NAME)
                    .build();

            mAwareSession.subscribe(config, new DiscoverySessionCallback() {

                private PeerHandle mPeerHandle = null;
                @Override
                public void onSubscribeStarted(SubscribeDiscoverySession session) {
                    if (mPeerHandle != null) {
                        int messageId = 1;
                        session.sendMessage(mPeerHandle, messageId, "Test Message".getBytes());
                    }
                }

                @Override
                public void onServiceDiscovered(PeerHandle peerHandle,
                                                byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
                    mPeerHandle = peerHandle;
                }
            }, null);

        }
    }
}

Allgemein (Berechtigungseinstellung)

AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.user.wifiawaretest">
    
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Recommended Posts

Android 8.0 - Wi-Fi Aware Memo
Memo