• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.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 */
238public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
239
240    private WifiP2pManager mManager;
241    private Channel mChannel;
242    private MyWiFiActivity mActivity;
243
244    public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel,
245            MyWifiActivity activity) {
246        super();
247        this.mManager = manager;
248        this.mChannel = channel;
249        this.mActivity = 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
300public 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>
327WifiP2pManager mManager;
328Channel mChannel;
329BroadcastReceiver mReceiver;
330...
331&#064;Override
332protected void onCreate(Bundle savedInstanceState){
333    ...
334    mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
335    mChannel = mManager.initialize(this, getMainLooper(), null);
336    mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, 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>
345IntentFilter mIntentFilter;
346...
347&#064;Override
348protected 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
365protected void onResume() {
366    super.onResume();
367    registerReceiver(mReceiver, mIntentFilter);
368}
369/* unregister the broadcast receiver */
370&#064;Override
371protected 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>
400mManager.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>
421PeerListListener myPeerListListener;
422...
423if (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 (mManager != null) {
429        mManager.requestPeers(mChannel, 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
453WifiP2pDevice device;
454WifiP2pConfig config = new WifiP2pConfig();
455config.deviceAddress = device.deviceAddress;
456mManager.connect(mChannel, 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>
499public 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>
562Context context = this.getApplicationContext();
563String host;
564int port;
565int len;
566Socket socket = new Socket();
567byte buf[]  = new byte[1024];
568...
569try {
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 */
600finally {
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