Home | History | Annotate | Download | only in connectivity
      1 page.title=Wi-Fi Peer-to-Peer
      2 page.tags="wireless","WifiP2pManager","Wi-Fi Direct","WiFi Direct","P2P","Wi-Fi P2P","WiFi P2P"
      3 
      4 @jd:body
      5 
      6   <div id="qv-wrapper">
      7     <div id="qv">
      8       <h2>In this document</h2>
      9 
     10       <ol>
     11         <li><a href="#api">API Overview</a></li>
     12         <li><a href="#creating-br">Creating a Broadcast Receiver for Wi-Fi P2P Intents</a></li>
     13 
     14         <li>
     15           <a href="#creating-app">Creating a Wi-Fi P2P Application</a>
     16 
     17           <ol>
     18             <li><a href="#setup">Initial setup</a></li>
     19 
     20             <li><a href="#discovering">Discovering peers</a></li>
     21 
     22             <li><a href="#connecting">Connecting to peers</a></li>
     23 
     24             <li><a href="#transferring">Transferring data</a></li>
     25           </ol>
     26         </li>
     27       </ol>
     28     <h2>See also</h2>
     29     <ul>
     30       <li><a href="{@docRoot}training/connect-devices-wirelessly/wifi-direct.html">Creating
     31         P2P Connections with Wi-Fi</a></li>
     32     </ul>
     33     </div>
     34   </div>
     35 
     36 
     37 <p>Wi-Fi peer-to-peer (P2P) allows Android 4.0 (API level 14) or later devices with the appropriate
     38 hardware to connect directly to each other via Wi-Fi without an intermediate access point (Android's
     39 Wi-Fi P2P framework complies with the Wi-Fi Alliance's Wi-Fi Direct&trade; certification program).
     40 Using these APIs, you can discover and connect to other devices when each device supports Wi-Fi P2P,
     41 then communicate over a speedy connection across distances much longer than a Bluetooth connection.
     42 This is useful for applications that share data among users, such as a multiplayer game or
     43 a photo sharing application.</p>
     44 
     45   <p>The Wi-Fi P2P APIs consist of the following main parts:</p>
     46 
     47   <ul>
     48     <li>Methods that allow you to discover, request, and connect to peers are defined
     49     in the {@link android.net.wifi.p2p.WifiP2pManager} class.</li>
     50 
     51     <li>Listeners that allow you to be notified of the success or failure of {@link
     52     android.net.wifi.p2p.WifiP2pManager} method calls. When calling {@link
     53     android.net.wifi.p2p.WifiP2pManager} methods, each method can receive a specific listener
     54     passed in as a parameter.</li>
     55 
     56     <li>Intents that notify you of specific events detected by the Wi-Fi P2P framework,
     57     such as a dropped connection or a newly discovered peer.</li>
     58   </ul>
     59 
     60   <p>You often use these three main components of the APIs together. For example, you can
     61   provide a {@link android.net.wifi.p2p.WifiP2pManager.ActionListener} to a call to {@link
     62   android.net.wifi.p2p.WifiP2pManager#discoverPeers discoverPeers()}, so that you can be
     63   notified with the {@link android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess
     64   ActionListener.onSuccess()} and {@link android.net.wifi.p2p.WifiP2pManager.ActionListener#onFailure
     65   ActionListener.onFailure()}
     66   methods. A {@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent is
     67   also broadcast if the {@link android.net.wifi.p2p.WifiP2pManager#discoverPeers discoverPeers()}
     68   method discovers that the peers list has changed.</p>
     69   
     70   <h2 id="api">API Overview</h2>
     71 
     72 <p>The {@link android.net.wifi.p2p.WifiP2pManager} class provides methods to allow you to interact with
     73   the Wi-Fi hardware on your device to do things like discover and connect to peers. The following actions
     74   are available:</p>
     75 
     76 <p class="table-caption"><strong>Table 1.</strong>Wi-Fi P2P Methods</p>
     77 
     78    <table>
     79         <tr>
     80           <th>Method</th>
     81           <th>Description</th>
     82         </tr>
     83 
     84 	<tr>
     85 	  <td>{@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</td>
     86 	  <td>Registers the application with the Wi-Fi framework. This must be called before calling any other Wi-Fi P2P method.</td>
     87 	</tr>
     88 
     89 	<tr>
     90 	  <td>{@link android.net.wifi.p2p.WifiP2pManager#connect connect()}</td>
     91 	  <td>Starts a peer-to-peer connection with a device with the specified configuration.</td>
     92 	</tr>
     93 
     94 	<tr>
     95 	  <td>{@link android.net.wifi.p2p.WifiP2pManager#cancelConnect cancelConnect()}</td>
     96 	  <td>Cancels any ongoing peer-to-peer group negotiation.</td>
     97 	</tr>
     98 
     99 	<tr>
    100 	  <td>{@link android.net.wifi.p2p.WifiP2pManager#requestConnectionInfo requestConnectInfo()}</td>
    101 	  <td>Requests a device's connection information.</td>
    102 	</tr>
    103 
    104 	<tr>
    105 	  <td>{@link android.net.wifi.p2p.WifiP2pManager#createGroup createGroup()}</td>
    106 	  <td>Creates a peer-to-peer group with the current device as the group owner.</td>
    107 	</tr>
    108 
    109 	<tr>
    110 	  <td>{@link android.net.wifi.p2p.WifiP2pManager#removeGroup removeGroup()}</td>
    111 	  <td>Removes the current peer-to-peer group.</td>
    112 	</tr>
    113 
    114 	<tr>
    115 	  <td>{@link android.net.wifi.p2p.WifiP2pManager#requestGroupInfo requestGroupInfo()}</td>
    116 	  <td>Requests peer-to-peer group information.</td>
    117 	</tr>
    118 
    119 	<tr>
    120 	  <td>{@link android.net.wifi.p2p.WifiP2pManager.PeerListListener#discoverPeers discoverPeers()}</td>
    121 	  <td>Initiates peer discovery </td>
    122 	</tr>
    123 
    124 	<tr>
    125 	  <td>{@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()}</td>
    126 	  <td>Requests the current list of discovered peers.</td>
    127 	</tr>
    128   </table>
    129 
    130 
    131  <p>{@link android.net.wifi.p2p.WifiP2pManager} methods let you pass in a listener,
    132   so that the Wi-Fi P2P framework can notify your
    133   activity of the status of a call. The available listener interfaces and the
    134   corresponding {@link android.net.wifi.p2p.WifiP2pManager} method calls that use the listeners
    135   are described in the following table:</p>
    136 
    137  <p class="table-caption"><strong>Table 2.</strong> Wi-Fi P2P Listeners</p>
    138  
    139  <table>
    140     <tr>
    141       <th>Listener interface</th>
    142       <th>Associated actions</th>
    143     </tr>
    144     <tr>
    145     <td>{@link android.net.wifi.p2p.WifiP2pManager.ActionListener}</td>
    146     <td>{@link android.net.wifi.p2p.WifiP2pManager#connect connect()}, {@link
    147     android.net.wifi.p2p.WifiP2pManager#cancelConnect cancelConnect()}, {@link
    148     android.net.wifi.p2p.WifiP2pManager#createGroup createGroup()}, {@link
    149     android.net.wifi.p2p.WifiP2pManager#removeGroup removeGroup()}, and {@link
    150     android.net.wifi.p2p.WifiP2pManager.PeerListListener#discoverPeers discoverPeers()}</td>
    151     </tr>
    152 
    153     <tr>
    154       <td>{@link android.net.wifi.p2p.WifiP2pManager.ChannelListener}</td>
    155       <td>{@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</td>
    156     </tr>
    157 
    158     <tr>
    159       <td>{@link android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener}</td>
    160       <td>{@link android.net.wifi.p2p.WifiP2pManager#requestConnectionInfo requestConnectInfo()}</td>
    161     </tr>
    162 
    163     <tr>
    164       <td>{@link android.net.wifi.p2p.WifiP2pManager.GroupInfoListener}</td>
    165       <td>{@link android.net.wifi.p2p.WifiP2pManager#requestGroupInfo requestGroupInfo()}</td>
    166     </tr>
    167 
    168     <tr>
    169       <td>{@link android.net.wifi.p2p.WifiP2pManager.PeerListListener}</td>
    170       <td>{@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()}</td>
    171     </tr>
    172   </table>
    173 
    174 <p>The Wi-Fi P2P APIs define intents that are broadcast when certain Wi-Fi P2P events happen,
    175   such as when a new peer is discovered or when a device's Wi-Fi state changes. You can register
    176   to receive these intents in your application by <a href="#creating-br">creating a broadcast
    177   receiver</a> that handles these intents:</p>
    178 
    179 <p class="table-caption"><strong>Table 3.</strong> Wi-Fi P2P Intents</p>
    180 
    181     <table>
    182     <tr>
    183       <th>Intent</th>
    184       <th>Description</th>
    185     </tr>
    186       <tr>
    187         <td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION}</td>
    188         <td>Broadcast when the state of the device's Wi-Fi connection changes.</td>
    189       </tr>
    190       <tr>
    191         <td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION}</td>
    192         <td>Broadcast when you call {@link
    193     android.net.wifi.p2p.WifiP2pManager.PeerListListener#discoverPeers discoverPeers()}. You
    194     usually want to call {@link android.net.wifi.p2p.WifiP2pManager.PeerListListener#requestPeers
    195     requestPeers()} to get an updated list of peers if you handle this intent in your
    196     application.</td>
    197       </tr>
    198       <tr>
    199         <td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION}</td>
    200         <td>Broadcast when Wi-Fi P2P is enabled or disabled on the device.</td>
    201       </tr>
    202       <tr>
    203         <td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_THIS_DEVICE_CHANGED_ACTION}</td>
    204         <td>Broadcast when a device's details have changed, such as the device's name.</td>
    205       </tr>
    206     </table>
    207 
    208 
    209 
    210   <h2 id="creating-br">Creating a Broadcast Receiver for Wi-Fi P2P Intents</h2>
    211 
    212   <p>A broadcast receiver allows you to receive intents broadcast by the Android system,
    213   so that your application can respond to events that you are interested in. The basic steps
    214   for creating a broadcast receiver to handle Wi-Fi P2P intents are as follows:</p>
    215 
    216   <ol>
    217     <li>Create a class that extends the {@link android.content.BroadcastReceiver} class. For the
    218     class' constructor, you most likely want to have parameters for the {@link
    219     android.net.wifi.p2p.WifiP2pManager}, {@link android.net.wifi.p2p.WifiP2pManager.Channel}, and
    220     the activity that this broadcast receiver will be registered in. This allows the broadcast
    221     receiver to send updates to the activity as well as have access to the Wi-Fi hardware and a
    222     communication channel if needed.</li>
    223 
    224     <li>In the broadcast receiver, check for the intents that you are interested in
    225     <code>{@link android.content.BroadcastReceiver#onReceive onReceive()}</code>.
    226     Carry out any necessary actions depending on the intent that is
    227     received. For example, if the broadcast receiver receives a {@link
    228     android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent, you can call the
    229     {@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()} method to get a list of
    230     the currently discovered peers.</li>
    231   </ol>
    232 
    233   <p>The following code shows you how to create a typical broadcast receiver. The broadcast
    234   receiver takes a {@link android.net.wifi.p2p.WifiP2pManager} object and an activity as
    235   arguments and uses these two classes to appropriately carry out the needed actions when the
    236   broadcast receiver receives an intent:</p>
    237 
    238 <pre>
    239 /**
    240  * A BroadcastReceiver that notifies of important Wi-Fi p2p events.
    241  */
    242 public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
    243 
    244     private WifiP2pManager mManager;
    245     private Channel mChannel;
    246     private MyWiFiActivity mActivity;
    247 
    248     public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel,
    249             MyWifiActivity activity) {
    250         super();
    251         this.mManager = manager;
    252         this.mChannel = channel;
    253         this.mActivity = activity;
    254     }
    255 
    256     &#064;Override
    257     public void onReceive(Context context, Intent intent) {
    258         String action = intent.getAction();
    259 
    260         if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
    261             // Check to see if Wi-Fi is enabled and notify appropriate activity
    262         } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
    263             // Call WifiP2pManager.requestPeers() to get a list of current peers
    264         } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
    265             // Respond to new connection or disconnections
    266         } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
    267             // Respond to this device's wifi state changing
    268         }
    269     }
    270 }
    271 </pre>
    272 
    273   <h2 id="creating-app">Creating a Wi-Fi P2P Application</h2>
    274 
    275   <p>Creating a Wi-Fi P2P application involves creating and registering a
    276   broadcast receiver for your application, discovering peers, connecting to a peer, and
    277   transferring data to a peer. The following sections describe how to do this.</p>
    278 
    279   <h3 id="setup">Initial setup</h3>
    280   <p>Before using the Wi-Fi P2P APIs, you must ensure that your application can access
    281   the hardware and that the device supports the Wi-Fi P2P protocol. If Wi-Fi P2P is supported,
    282   you can obtain an instance of {@link android.net.wifi.p2p.WifiP2pManager}, create and register
    283   your broadcast receiver, and begin using the Wi-Fi P2P APIs.</p>
    284   <ol>
    285     <li>
    286       <p>Request permission to use the Wi-Fi hardware on the device and also declare
    287       your application to have the correct minimum SDK version in the Android manifest:</p>
    288       <pre>
    289 &lt;uses-sdk android:minSdkVersion="14" /&gt;
    290 &lt;uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /&gt;
    291 &lt;uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /&gt;
    292 &lt;uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /&gt;
    293 &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
    294 &lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /&gt;
    295 </pre>
    296     </li>
    297 
    298     <li>Check to see if Wi-Fi P2P is on and supported. A good place to check this is in your
    299     broadcast receiver when it receives the {@link
    300     android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION} intent. Notify your
    301     activity of the Wi-Fi P2P state and react accordingly:
    302 <pre>
    303 &#064;Override
    304 public void onReceive(Context context, Intent intent) {
    305     ...
    306     String action = intent.getAction();
    307     if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
    308         int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
    309         if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
    310             // Wifi P2P is enabled
    311         } else {
    312             // Wi-Fi P2P is not enabled
    313         }
    314     }
    315     ...
    316 }
    317 </pre>
    318     </li>
    319 
    320     <li>In your activity's {@link android.app.Activity#onCreate onCreate()} method, obtain an instance of {@link
    321     android.net.wifi.p2p.WifiP2pManager} and register your application with the Wi-Fi P2P
    322     framework by calling {@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()}. This
    323     method returns a {@link android.net.wifi.p2p.WifiP2pManager.Channel}, which is used to connect
    324     your application to the Wi-Fi P2P framework. You should also create an instance of your
    325     broadcast receiver with the {@link
    326     android.net.wifi.p2p.WifiP2pManager} and {@link android.net.wifi.p2p.WifiP2pManager.Channel}
    327     objects along with a reference to your activity. This allows your broadcast receiver to notify
    328     your activity of interesting events and update it accordingly. It also lets you manipulate the device's
    329     Wi-Fi state if necessary:
    330 <pre>
    331 WifiP2pManager mManager;
    332 Channel mChannel;
    333 BroadcastReceiver mReceiver;
    334 ...
    335 &#064;Override
    336 protected void onCreate(Bundle savedInstanceState){
    337     ...
    338     mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
    339     mChannel = mManager.initialize(this, getMainLooper(), null);
    340     mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
    341     ...
    342 }
    343 </pre>
    344     </li>
    345 
    346     <li>Create an intent filter and add the same intents that your
    347     broadcast receiver checks for:
    348       <pre>
    349 IntentFilter mIntentFilter;
    350 ...
    351 &#064;Override
    352 protected void onCreate(Bundle savedInstanceState){
    353     ...
    354     mIntentFilter = new IntentFilter();
    355     mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
    356     mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
    357     mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
    358     mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
    359     ...
    360 }
    361 </pre>
    362     </li>
    363 
    364     <li>Register the broadcast receiver in the {@link android.app.Activity#onResume()} method
    365     of your activity and unregister it in the {@link android.app.Activity#onPause()} method of your activity:
    366       <pre>
    367 /* register the broadcast receiver with the intent values to be matched */
    368 &#064;Override
    369 protected void onResume() {
    370     super.onResume();
    371     registerReceiver(mReceiver, mIntentFilter);
    372 }
    373 /* unregister the broadcast receiver */
    374 &#064;Override
    375 protected void onPause() {
    376     super.onPause();
    377     unregisterReceiver(mReceiver);
    378 }
    379 </pre>
    380 
    381       <p>When you have obtained a {@link android.net.wifi.p2p.WifiP2pManager.Channel} and
    382       set up a broadcast receiver, your application can make Wi-Fi P2P method calls and receive
    383       Wi-Fi P2P intents.</p>
    384     </li>
    385 
    386     <p>You can now implement your application and use the Wi-Fi P2P features by calling the
    387     methods in {@link android.net.wifi.p2p.WifiP2pManager}. The next sections describe how to do common actions
    388     such as discovering and connecting to peers.</p>
    389   </ol>
    390 
    391   <h3 id="discovering">Discovering peers</h3>
    392 
    393   <p>To discover peers that are available to connect to, call {@link
    394   android.net.wifi.p2p.WifiP2pManager#discoverPeers discoverPeers()} to detect
    395   available peers that are in range. The call to this function is asynchronous and a success or
    396   failure is communicated to your application with {@link
    397   android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess onSuccess()} and {@link
    398   android.net.wifi.p2p.WifiP2pManager.ActionListener#onFailure onFailure()} if you created a 
    399   {@link android.net.wifi.p2p.WifiP2pManager.ActionListener}. The
    400   {@link android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess onSuccess()} method only notifies you
    401   that the discovery process succeeded and does not provide any information about the actual peers
    402   that it discovered, if any:</p>
    403   <pre>
    404 mManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
    405     &#064;Override
    406     public void onSuccess() {
    407         ...
    408     }
    409 
    410     &#064;Override
    411     public void onFailure(int reasonCode) {
    412         ...
    413     }
    414 });
    415 
    416 </pre>
    417 
    418 <p>If the discovery process succeeds and detects peers, the system broadcasts the {@link
    419   android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent, which you can listen
    420   for in a broadcast receiver to obtain a list of peers. When your application receives the {@link
    421   android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent, you can request a
    422   list of the discovered peers with {@link
    423   android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()}. The following code shows how to set this up:</p>
    424   <pre>
    425 PeerListListener myPeerListListener;
    426 ...
    427 if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
    428 
    429     // request available peers from the wifi p2p manager. This is an
    430     // asynchronous call and the calling activity is notified with a
    431     // callback on PeerListListener.onPeersAvailable()
    432     if (mManager != null) {
    433         mManager.requestPeers(mChannel, myPeerListListener);
    434     }
    435 }
    436 </pre>
    437 
    438   <p>The {@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()} method is also
    439   asynchronous and can notify your activity when a list of peers is available with {@link
    440   android.net.wifi.p2p.WifiP2pManager.PeerListListener#onPeersAvailable onPeersAvailable()}, which is defined in
    441   the {@link android.net.wifi.p2p.WifiP2pManager.PeerListListener} interface. The {@link
    442   android.net.wifi.p2p.WifiP2pManager.PeerListListener#onPeersAvailable onPeersAvailable()} method
    443   provides you with an {@link android.net.wifi.p2p.WifiP2pDeviceList}, which you can iterate
    444   through to find the peer that you want to connect to.</p>
    445 
    446   <h3 id="connecting">Connecting to peers</h3>
    447 
    448   <p>When you have figured out the device that you want to connect to after obtaining a list of
    449   possible peers, call the {@link android.net.wifi.p2p.WifiP2pManager#connect connect()} method to
    450   connect to the device. This method call requires a {@link android.net.wifi.p2p.WifiP2pConfig}
    451   object that contains the information of the device to connect to.
    452   You can be notified of a connection success or failure through the {@link
    453   android.net.wifi.p2p.WifiP2pManager.ActionListener}. The following code
    454   shows you how to create a connection to a desired device:</p>
    455   <pre>
    456 //obtain a peer from the WifiP2pDeviceList
    457 WifiP2pDevice device;
    458 WifiP2pConfig config = new WifiP2pConfig();
    459 config.deviceAddress = device.deviceAddress;
    460 mManager.connect(mChannel, config, new ActionListener() {
    461 
    462     &#064;Override
    463     public void onSuccess() {
    464         //success logic
    465     }
    466 
    467     &#064;Override
    468     public void onFailure(int reason) {
    469         //failure logic
    470     }
    471 });
    472 
    473 </pre>
    474 
    475 
    476   <h3 id="transferring">Transferring data</h3>
    477   <p>Once a connection is established, you can transfer data between the devices with
    478   sockets. The basic steps of transferring data are as follows:</p>
    479 
    480   <ol>
    481     <li>Create a {@link java.net.ServerSocket}. This socket waits for a connection from a client on a specified
    482     port and blocks until it happens, so do this in a background thread.</li>
    483 
    484     <li>Create a client {@link java.net.Socket}. The client uses the IP address and port of
    485     the server socket to connect to the server device.</li>
    486 
    487     <li>Send data from the client to the server. When the client
    488     socket successfully connects to the server socket, you can send data from the client to the server
    489     with byte streams. </li>
    490 
    491     <li>The server socket waits for a client connection (with the {@link java.net.ServerSocket#accept()} method). This
    492     call blocks until a client connects, so call this is another thread. When a connection happens, the server device can receive
    493     the data from the client. Carry out any actions with this data, such as saving it to a file
    494     or presenting it to the user.</li>
    495   </ol>
    496 
    497   <p>The following example, modified from the <a href=
    498   "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi P2P Demo</a> sample, shows you how
    499   to create this client-server socket communication and transfer JPEG images from a client
    500   to a server with a service. For a complete working example, compile and run the <a href=
    501   "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi P2P Demo</a> sample.</p>
    502 <pre>
    503 public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
    504 
    505     private Context context;
    506     private TextView statusText;
    507 
    508     public FileServerAsyncTask(Context context, View statusText) {
    509         this.context = context;
    510         this.statusText = (TextView) statusText;
    511     }
    512 
    513     &#064;Override
    514     protected String doInBackground(Void... params) {
    515         try {
    516 
    517             /**
    518              * Create a server socket and wait for client connections. This
    519              * call blocks until a connection is accepted from a client
    520              */
    521             ServerSocket serverSocket = new ServerSocket(8888);
    522             Socket client = serverSocket.accept();
    523 
    524             /**
    525              * If this code is reached, a client has connected and transferred data
    526              * Save the input stream from the client as a JPEG file
    527              */
    528             final File f = new File(Environment.getExternalStorageDirectory() + "/"
    529                     + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
    530                     + ".jpg");
    531 
    532             File dirs = new File(f.getParent());
    533             if (!dirs.exists())
    534                 dirs.mkdirs();
    535             f.createNewFile();
    536             InputStream inputstream = client.getInputStream();
    537             copyFile(inputstream, new FileOutputStream(f));
    538             serverSocket.close();
    539             return f.getAbsolutePath();
    540         } catch (IOException e) {
    541             Log.e(WiFiDirectActivity.TAG, e.getMessage());
    542             return null;
    543         }
    544     }
    545 
    546     /**
    547      * Start activity that can handle the JPEG image
    548      */
    549     &#064;Override
    550     protected void onPostExecute(String result) {
    551         if (result != null) {
    552             statusText.setText("File copied - " + result);
    553             Intent intent = new Intent();
    554             intent.setAction(android.content.Intent.ACTION_VIEW);
    555             intent.setDataAndType(Uri.parse("file://" + result), "image/*");
    556             context.startActivity(intent);
    557         }
    558     }
    559 }
    560 </pre>
    561 
    562   <p>On the client, connect to the server socket with a client socket and transfer data. This example
    563   transfers a JPEG file on the client device's file system.</p>
    564 
    565 <pre>
    566 Context context = this.getApplicationContext();
    567 String host;
    568 int port;
    569 int len;
    570 Socket socket = new Socket();
    571 byte buf[]  = new byte[1024];
    572 ...
    573 try {
    574     /**
    575      * Create a client socket with the host,
    576      * port, and timeout information.
    577      */
    578     socket.bind(null);
    579     socket.connect((new InetSocketAddress(host, port)), 500);
    580 
    581     /**
    582      * Create a byte stream from a JPEG file and pipe it to the output stream
    583      * of the socket. This data will be retrieved by the server device.
    584      */
    585     OutputStream outputStream = socket.getOutputStream();
    586     ContentResolver cr = context.getContentResolver();
    587     InputStream inputStream = null;
    588     inputStream = cr.openInputStream(Uri.parse("path/to/picture.jpg"));
    589     while ((len = inputStream.read(buf)) != -1) {
    590         outputStream.write(buf, 0, len);
    591     }
    592     outputStream.close();
    593     inputStream.close();
    594 } catch (FileNotFoundException e) {
    595     //catch logic
    596 } catch (IOException e) {
    597     //catch logic
    598 }
    599 
    600 /**
    601  * Clean up any open sockets when done
    602  * transferring or if an exception occurred.
    603  */
    604 finally {
    605     if (socket != null) {
    606         if (socket.isConnected()) {
    607             try {
    608                 socket.close();
    609             } catch (IOException e) {
    610                 //catch logic
    611             }
    612         }
    613     }
    614 }
    615 </pre>
    616