blob: ec8e71eeb997c2d9088abd12a8ba54d8fcfc78e5 [file] [log] [blame]
Robert Ly12a1de02011-11-02 11:56:50 -07001page.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 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
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);
Scott Main8edad6f2012-03-09 10:55:50 -0800336 mReceiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
Robert Ly12a1de02011-11-02 11:56:50 -0700337 ...
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();
Scott Main8edad6f2012-03-09 10:55:50 -0800367 registerReceiver(mReceiver, mIntentFilter);
Robert Ly12a1de02011-11-02 11:56:50 -0700368}
369/* unregister the broadcast receiver */
370&#064;Override
371protected void onPause() {
372 super.onPause();
Scott Main8edad6f2012-03-09 10:55:50 -0800373 unregisterReceiver(mReceiver);
Robert Ly12a1de02011-11-02 11:56:50 -0700374}
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>
400manager.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 (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
453WifiP2pDevice device;
454WifiP2pConfig config = new WifiP2pConfig();
455config.deviceAddress = device.deviceAddress;
456manager.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>
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>