Service Discovery Introduction
In Android Wifidirect Learning (a), a simple description of how to use Wifidirect for search-connect-transfer.
The problem with this is that you will be searching all the nearby network devices that are in the Wifidirect search state, and these devices are not necessarily the one you want to connect to.
The Android Wifidirect API provides a search method that searches only specific network devices, called Service Discovery, which is the Wi-Fi Direct API on Android 4.1 was enhanced to support the discovery of pre-associated services in Wifip2pmanager. This allows you to use Wi-Fi direct to discover and filter the surrounding devices through the service before connecting.
Common service:
Android has provided two service, one is the Bonjour service, one is the UPnP service, the developer can also design a set of service, in general, these two kinds of service is enough.
Service Basic Usage method
In order to broadcast your app as a service on a Wi-Fi, so that other devices can discover and connect to your app, you need to call the Addlocalservice () method and transfer a Wifip2pserviceinfo object. This object describes your app service.
In order to start discovering nearby devices over Wi-Fi, you should first decide whether to use Bonjour service or UPnP service for communication. If you use Bonjour, you first need to set up some callback listeners with Setdnssdresponselisteners (). This method requires Wifip2pmanager.dnssdserviceresponselistener and dnssdtxtrecordlistener two parameters. If you are using UPnP, call Setupnpserviceresponselistener (). This method requires Upnpserviceresponselistener as a parameter.
You also need to call the Addservicerequest () method before you start discovering services on your local device. When you pass the interface to this method ActionListener receive a successful callback, you can then start exploring the service on the local device by calling Discoverservices ().
When the local service is found, you will receive a callback, From Wifip2pmanager.dnssdserviceresponselistener or Wifip2pmanager.upnpserviceresponselistener, depending on whether you are registering with Bonjour or UPnP. The callback received will contain a Wifip2pdevice object that represents the corresponding device.
Service use case (take Bonjour service as an example)
SetManifest
To use Wi-Fi peer, add change_wifi_state, Access_wifi_state, and Internet permissions to your androidmanifest. Even though WI-FIP2P does not require an Internet connection, it wants to use a standard Java socket, and Android requires these permissions when using these sockets, so request Internet permissions in the manifest.
1 <manifestxmlns:android= "Http://schemas.android.com/apk/res/android" 2 Package= "Com.example.android.nsdchat" 3 ... 4 <uses-permission5 android:required= "true" 6 Android:name= "Android.permission.ACCESS_WIFI_STATE"/> 7 <uses-permission8 android:required= "true" 9 Android:name= "Android.permission.CHANGE_WIFI_STATE"/> Ten <uses-permission One android:required= "true" A Android:name= "Android.permission.INTERNET"/> -...
Add local Service
If you want to provide a local service, you need to register the service as discoverable. Once the local service is registered, the framework automatically responds to the service discovery request from the peer.
Here are the steps to create a local service:
1. Create a Wifip2pserviceinfo object;
2. Fill in the information related to your service;
3. Call the Addlocalservice () method to register the local service so that it can be discovered.
1 private void Startregistration () {2 //Create A string map containing information about your service.3Map record =NewHashMap ();4Record.put ("Listenport", String.valueof (Server_port)); 5Record.put ("Buddyname", "John Doe" + (int) (Math.random () * 1000)); 6Record.put ("Available", "visible"); 7 //serviceinformation. Pass it an instance name, service type8 //_protocol._transportlayer, and the map containing9 //information Other devices would want once they connect to this one.TenWifip2pdnssdserviceinfo serviceinfo = OneWifip2pdnssdserviceinfo.newinstance ("_test", "_presence._tcp", record); A //ADD thelocal Service, sending the service info, network channel, - //Andlistener that'll be used to indicate success or failure of - //therequest. theMmanager.addlocalservice (channel, ServiceInfo,NewActionListener () { - @Override - Public voidonsuccess () { - //Command successful! Code isn ' t necessarily needed here, + //unless want to update the UI or add logging statements. - } + @Override A Public voidOnFailure (intarg0) { at //Command failed. Check for p2p_unsupported, ERROR, or BUSY - } - }); -}
Discover the nearby services
Android uses a callback method to inform your application of the available services, so the first thing to do is to set up a callback method. Create a Wifip2pmanager.dnssdtxtrecordlistener object to listen for incoming records. This record can be any broadcast by any other device. When a record enters, you can copy the device address and other relevant information you want to the data structure outside the current method so that it can be accessed later. The following example assumes that the record contains a "buddyname" field with the user's identity.
1Finalhashmap<string,string> Buddies =newhashmap<string,string>(); 2 ... 3 Private voidDiscoverservice () {4Dnssdtxtrecordlistener Txtlistener =NewDnssdtxtrecordlistener () {5 @Override6 /*Callbackincludes:7 * fulldomain:full domainname:e.g "printer._ipp._tcp.local."8 * Record:txt record DTA as AMAP of key/value pairs.9 * device:the device runningthe advertised service.Ten */ One Publicvoidondnssdtxtrecordavailable ( A String Fulldomain, Map record, wifip2pdevice device) { -LOG.D (TAG, "Dnssdtxtrecord available-" +record.tostring ()); -Buddies.put (device.deviceaddress, Record.get ("Buddyname")); the } - }; - ... -}
Implement a Wifip2pmanager.dnssdserviceresponselistener interface to obtain service information. This interface receives the actual description and connection information. The above code uses a map object to make a pair of device addresses and user identities. The service response listener uses this interface to connect DNS records with the corresponding service information. After implementing both listeners, use the Setdnssdresponselistener () method to add them to the Wifip2pmanager object.
1 Private voidDiscoverservice () {2 ... 3Dnssdserviceresponselistener Servlistener =NewDnssdserviceresponselistener () {4 @Override5 Publicvoidondnssdserviceavailable (string instancename, String registrationtype,6 Wifip2pdevice ResourceType) { 7 //Update The device name with the human-friendly version from8 //the Dnstxtrecord, assuming one arrived.9Resourcetype.devicename =BuddiesTen. ContainsKey (resourcetype.deviceaddress)?Buddies One . Get (resourcetype.deviceaddress): Resourcetype.devicename; A //ADD to the custom adapter defined specifically for showing - //WiFi devices. -Wifidirectserviceslist fragment =(wifidirectserviceslist) Getfragmentmanager () the . Findfragmentbyid (r.id.frag_peerlist); -Wifidevicesadapter adapter =((wifidevicesadapter) Fragment - . Getlistadapter ()); - Adapter.add (resourcetype); + adapter.notifydatasetchanged (); -LOG.D (TAG, "onbonjourserviceavailable" +instancename); + } A }; at mmanager.setdnssdresponselisteners (channel, Servlistener, Txtlistener); - ... -}
Now to create a service request and invoke the Addservicerequest () method, this method also requires a listener to include success or failure.
1Servicerequest =wifip2pdnssdservicerequest.newinstance ();2 mmanager.addservicerequest (channel,3 Servicerequest,4 NewActionListener () {5 @Override6 Public voidonsuccess () {7 //success!8 } 9 @OverrideTen Public voidOnFailure (intcode) { One //Command failed. Check forp2p_unsupported, ERROR, or BUSY A } -});
Finally, call the discoverservices () method.
1 mmanager.discoverservices (Channel,newactionlistener () {2 @Override3 Public voidonsuccess () {4 //success!5 } 6 @Override7 Public voidOnFailure (intcode) { 8 //Command failed. Check for p2p_unsupported, ERROR, or BUSY9 if(Code = =wifip2pmanager.p2p_unsupported) { TenLOG.D (TAG, "peer isn ' tsupported on this device.")); One Else if(...) A ... - } -});
If all goes well, congratulations on your success. If a problem is encountered, the parameter of the preceding asynchronous invocation wifip2pmanager.actionlistener the parameter, which provides a callback method that indicates success or failure. Set the Debug breakpoint in the OnFailure () method to diagnose the problem. This method provides the error code, and the following are the possible errors:
p2p_unsupported
Wi-Fi peer is not supported on the device running the app
BUSY
The system is busy processing requests
ERROR
Operation failed due to an internal error
Android Wifidirect Learning (ii)--service Discovery