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