Wi-Fi peer-to-peer overview

Wi-Fi peer-to-peer (P2P) allows Android 4.0 (API level 14) or later devices with the appropriate
hardware to connect directly to each other via Wi-Fi without an intermediate access point (Android's
Wi-Fi P2P framework complies with the Wi-Fi Alliance's Wi-Fi Direct™ certification program).
Using these APIs, you can discover and connect to other devices when each device supports Wi-Fi P2P,
then communicate over a speedy connection across distances much longer than a Bluetooth connection.
This is useful for applications that share data among users, such as a multiplayer game or
a photo sharing application.

The Wi-Fi P2P APIs consist of the following main parts:

Methods that allow you to discover, request, and connect to peers are defined
in the WifiP2pManager class.

Listeners that allow you to be notified of the success or failure of WifiP2pManager method calls. When calling WifiP2pManager methods, each method can receive a specific listener
passed in as a parameter.

Intents that notify you of specific events detected by the Wi-Fi P2P framework,
such as a dropped connection or a newly discovered peer.

WifiP2pManager methods let you pass in a listener,
so that the Wi-Fi P2P framework can notify your
activity of the status of a call. The available listener interfaces and the
corresponding WifiP2pManager method calls that use the listeners
are described in the following table:

The Wi-Fi P2P APIs define intents that are broadcast when certain Wi-Fi P2P events happen,
such as when a new peer is discovered or when a device's Wi-Fi state changes. You can register
to receive these intents in your application by creating a broadcast
receiver that handles these intents:

Broadcast when a device's details have changed, such as the device's name.

Create a broadcast receiver for Wi-Fi P2P intents

A broadcast receiver allows you to receive intents broadcast by the Android system,
so that your application can respond to events that you are interested in. The basic steps
for creating a broadcast receiver to handle Wi-Fi P2P intents are as follows:

Create a class that extends the BroadcastReceiver class. For the
class' constructor, you most likely want to have parameters for the WifiP2pManager, WifiP2pManager.Channel, and
the activity that this broadcast receiver will be registered in. This allows the broadcast
receiver to send updates to the activity as well as have access to the Wi-Fi hardware and a
communication channel if needed.

In the broadcast receiver, check for the intents that you are interested in
onReceive().
Carry out any necessary actions depending on the intent that is
received. For example, if the broadcast receiver receives a WIFI_P2P_PEERS_CHANGED_ACTION intent, you can call the
requestPeers() method to get a list of
the currently discovered peers.

The following code shows you how to create a typical broadcast receiver. The broadcast
receiver takes a WifiP2pManager object and an activity as
arguments and uses these two classes to appropriately carry out the needed actions when the
broadcast receiver receives an intent:

Create a Wi-Fi P2P application

Creating a Wi-Fi P2P application involves creating and registering a
broadcast receiver for your application, discovering peers, connecting to a peer, and
transferring data to a peer. The following sections describe how to do this.

Initial setup

Before using the Wi-Fi P2P APIs, you must ensure that your application can access
the hardware and that the device supports the Wi-Fi P2P protocol. If Wi-Fi P2P is supported,
you can obtain an instance of WifiP2pManager, create and register
your broadcast receiver, and begin using the Wi-Fi P2P APIs.

Request permission to use the Wi-Fi hardware on the device and also declare
your application to have the correct minimum SDK version in the Android manifest:

Check to see if Wi-Fi P2P is on and supported. A good place to check this is in your
broadcast receiver when it receives the WIFI_P2P_STATE_CHANGED_ACTION intent. Notify your
activity of the Wi-Fi P2P state and react accordingly:

In your activity's onCreate() method, obtain an instance of WifiP2pManager and register your application with the Wi-Fi P2P
framework by calling initialize(). This
method returns a WifiP2pManager.Channel, which is used to connect
your application to the Wi-Fi P2P framework. You should also create an instance of your
broadcast receiver with the WifiP2pManager and WifiP2pManager.Channel
objects along with a reference to your activity. This allows your broadcast receiver to notify
your activity of interesting events and update it accordingly. It also lets you manipulate the device's
Wi-Fi state if necessary:

When you have obtained a WifiP2pManager.Channel and
set up a broadcast receiver, your application can make Wi-Fi P2P method calls and receive
Wi-Fi P2P intents.

You can now implement your application and use the Wi-Fi P2P features by calling the
methods in WifiP2pManager. The next sections describe how to do common actions
such as discovering and connecting to peers.

Discover peers

To discover peers that are available to connect to, call discoverPeers() to detect
available peers that are in range. The call to this function is asynchronous and a success or
failure is communicated to your application with onSuccess() and onFailure() if you created a
WifiP2pManager.ActionListener. The
onSuccess() method only notifies you
that the discovery process succeeded and does not provide any information about the actual peers
that it discovered, if any:

Java

If the discovery process succeeds and detects peers, the system broadcasts the WIFI_P2P_PEERS_CHANGED_ACTION intent, which you can listen
for in a broadcast receiver to obtain a list of peers. When your application receives the WIFI_P2P_PEERS_CHANGED_ACTION intent, you can request a
list of the discovered peers with requestPeers(). The following code shows how to set this up:

Java

PeerListListener myPeerListListener;
...
if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// request available peers from the wifi p2p manager. This is an
// asynchronous call and the calling activity is notified with a
// callback on PeerListListener.onPeersAvailable()
if (manager != null) {
manager.requestPeers(channel, myPeerListListener);
}
}

Connect to peers

When you have figured out the device that you want to connect to after obtaining a list of
possible peers, call the connect() method to
connect to the device. This method call requires a WifiP2pConfig
object that contains the information of the device to connect to.
You can be notified of a connection success or failure through the WifiP2pManager.ActionListener. The following code
shows you how to create a connection to a desired device:

Transfer data

Once a connection is established, you can transfer data between the devices with
sockets. The basic steps of transferring data are as follows:

Create a ServerSocket. This socket waits for a connection from a client on a specified
port and blocks until it happens, so do this in a background thread.

Create a client Socket. The client uses the IP address and port of
the server socket to connect to the server device.

Send data from the client to the server. When the client
socket successfully connects to the server socket, you can send data from the client to the server
with byte streams.

The server socket waits for a client connection (with the accept() method). This
call blocks until a client connects, so call this is another thread. When a connection happens, the server device can receive
the data from the client. Carry out any actions with this data, such as saving it to a file
or presenting it to the user.

The following example, modified from the
Wi-Fi P2P Demo
sample, shows you how to create this client-server socket communication and transfer JPEG images
from a client to a server with a service. For a complete working example, compile and run the
Wi-Fi P2P Demo
sample.