1page.title=Wi-Fi Peer-to-Peer
2page.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
38hardware to connect directly to each other via Wi-Fi without an intermediate access point (Android's
39Wi-Fi P2P framework complies with the Wi-Fi Alliance's Wi-Fi Direct&trade; certification program).
40Using these APIs, you can discover and connect to other devices when each device supports Wi-Fi P2P,
41then communicate over a speedy connection across distances much longer than a Bluetooth connection.
42This is useful for applications that share data among users, such as a multiplayer game or
43a 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 */
242public 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
304public 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>
331WifiP2pManager mManager;
332Channel mChannel;
333BroadcastReceiver mReceiver;
334...
335&#064;Override
336protected 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>
349IntentFilter mIntentFilter;
350...
351&#064;Override
352protected 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
369protected void onResume() {
370    super.onResume();
371    registerReceiver(mReceiver, mIntentFilter);
372}
373/* unregister the broadcast receiver */
374&#064;Override
375protected 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>
404mManager.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>
425PeerListListener myPeerListListener;
426...
427if (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
457WifiP2pDevice device;
458WifiP2pConfig config = new WifiP2pConfig();
459config.deviceAddress = device.deviceAddress;
460mManager.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>
503public 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>
566Context context = this.getApplicationContext();
567String host;
568int port;
569int len;
570Socket socket = new Socket();
571byte buf[]  = new byte[1024];
572...
573try {
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 */
604finally {
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