blob: 7cadde1cf06aa7ad9122b901ce2628fa4c019929 [file] [log] [blame]
Scott Mainf5e09702013-08-22 17:19:17 -07001page.title=Wi-Fi Peer-to-Peer
2page.tags="wireless","WifiP2pManager","Wi-Fi Direct","WiFi Direct","P2P","Wi-Fi P2P","WiFi P2P"
Robert Ly12a1de02011-11-02 11:56:50 -07003
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>
Scott Mainf5e09702013-08-22 17:19:17 -070012 <li><a href="#creating-br">Creating a Broadcast Receiver for Wi-Fi P2P Intents</a></li>
Robert Ly12a1de02011-11-02 11:56:50 -070013
14 <li>
Scott Mainf5e09702013-08-22 17:19:17 -070015 <a href="#creating-app">Creating a Wi-Fi P2P Application</a>
Robert Ly12a1de02011-11-02 11:56:50 -070016
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>
Scott Mainf5e09702013-08-22 17:19:17 -070028 <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>
Robert Ly12a1de02011-11-02 11:56:50 -070033 </div>
34 </div>
35
Robert Ly12a1de02011-11-02 11:56:50 -070036
Scott Mainf5e09702013-08-22 17:19:17 -070037<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>
Robert Ly12a1de02011-11-02 11:56:50 -070046
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
Scott Mainf5e09702013-08-22 17:19:17 -070056 <li>Intents that notify you of specific events detected by the Wi-Fi P2P framework,
Robert Ly12a1de02011-11-02 11:56:50 -070057 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
Scott Mainf5e09702013-08-22 17:19:17 -070076<p class="table-caption"><strong>Table 1.</strong>Wi-Fi P2P Methods</p>
Robert Ly12a1de02011-11-02 11:56:50 -070077
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>
Scott Mainf5e09702013-08-22 17:19:17 -070086 <td>Registers the application with the Wi-Fi framework. This must be called before calling any other Wi-Fi P2P method.</td>
Robert Ly12a1de02011-11-02 11:56:50 -070087 </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,
Scott Mainf5e09702013-08-22 17:19:17 -0700132 so that the Wi-Fi P2P framework can notify your
Robert Ly12a1de02011-11-02 11:56:50 -0700133 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
Scott Mainf5e09702013-08-22 17:19:17 -0700137 <p class="table-caption"><strong>Table 2.</strong> Wi-Fi P2P Listeners</p>
Robert Ly12a1de02011-11-02 11:56:50 -0700138
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
Scott Mainf5e09702013-08-22 17:19:17 -0700174<p>The Wi-Fi P2P APIs define intents that are broadcast when certain Wi-Fi P2P events happen,
Robert Ly12a1de02011-11-02 11:56:50 -0700175 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
Scott Mainf5e09702013-08-22 17:19:17 -0700179<p class="table-caption"><strong>Table 3.</strong> Wi-Fi P2P Intents</p>
Robert Ly12a1de02011-11-02 11:56:50 -0700180
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>
Scott Mainf5e09702013-08-22 17:19:17 -0700200 <td>Broadcast when Wi-Fi P2P is enabled or disabled on the device.</td>
Robert Ly12a1de02011-11-02 11:56:50 -0700201 </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
Scott Mainf5e09702013-08-22 17:19:17 -0700210 <h2 id="creating-br">Creating a Broadcast Receiver for Wi-Fi P2P Intents</h2>
Robert Ly12a1de02011-11-02 11:56:50 -0700211
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
Scott Mainf5e09702013-08-22 17:19:17 -0700214 for creating a broadcast receiver to handle Wi-Fi P2P intents are as follows:</p>
Robert Ly12a1de02011-11-02 11:56:50 -0700215
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
Scott Main6aad9952013-01-07 18:51:49 -0800244 private WifiP2pManager mManager;
245 private Channel mChannel;
246 private MyWiFiActivity mActivity;
Robert Ly12a1de02011-11-02 11:56:50 -0700247
248 public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel,
249 MyWifiActivity activity) {
250 super();
Scott Main6aad9952013-01-07 18:51:49 -0800251 this.mManager = manager;
252 this.mChannel = channel;
253 this.mActivity = activity;
Robert Ly12a1de02011-11-02 11:56:50 -0700254 }
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
Scott Mainf5e09702013-08-22 17:19:17 -0700273 <h2 id="creating-app">Creating a Wi-Fi P2P Application</h2>
Robert Ly12a1de02011-11-02 11:56:50 -0700274
Scott Mainf5e09702013-08-22 17:19:17 -0700275 <p>Creating a Wi-Fi P2P application involves creating and registering a
Robert Ly12a1de02011-11-02 11:56:50 -0700276 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>
Scott Mainf5e09702013-08-22 17:19:17 -0700280 <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,
Robert Ly12a1de02011-11-02 11:56:50 -0700282 you can obtain an instance of {@link android.net.wifi.p2p.WifiP2pManager}, create and register
Scott Mainf5e09702013-08-22 17:19:17 -0700283 your broadcast receiver, and begin using the Wi-Fi P2P APIs.</p>
Robert Ly12a1de02011-11-02 11:56:50 -0700284 <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
Scott Mainf5e09702013-08-22 17:19:17 -0700298 <li>Check to see if Wi-Fi P2P is on and supported. A good place to check this is in your
Robert Ly12a1de02011-11-02 11:56:50 -0700299 broadcast receiver when it receives the {@link
300 android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION} intent. Notify your
Scott Mainf5e09702013-08-22 17:19:17 -0700301 activity of the Wi-Fi P2P state and react accordingly:
Robert Ly12a1de02011-11-02 11:56:50 -0700302<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) {
Scott Mainf5e09702013-08-22 17:19:17 -0700310 // Wifi P2P is enabled
Robert Ly12a1de02011-11-02 11:56:50 -0700311 } else {
Scott Mainf5e09702013-08-22 17:19:17 -0700312 // Wi-Fi P2P is not enabled
Robert Ly12a1de02011-11-02 11:56:50 -0700313 }
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
Scott Mainf5e09702013-08-22 17:19:17 -0700321 android.net.wifi.p2p.WifiP2pManager} and register your application with the Wi-Fi P2P
Robert Ly12a1de02011-11-02 11:56:50 -0700322 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
Scott Mainf5e09702013-08-22 17:19:17 -0700324 your application to the Wi-Fi P2P framework. You should also create an instance of your
Robert Ly12a1de02011-11-02 11:56:50 -0700325 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);
Scott Main6aad9952013-01-07 18:51:49 -0800340 mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
Robert Ly12a1de02011-11-02 11:56:50 -0700341 ...
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();
Scott Main8edad6f2012-03-09 10:55:50 -0800371 registerReceiver(mReceiver, mIntentFilter);
Robert Ly12a1de02011-11-02 11:56:50 -0700372}
373/* unregister the broadcast receiver */
374&#064;Override
375protected void onPause() {
376 super.onPause();
Scott Main8edad6f2012-03-09 10:55:50 -0800377 unregisterReceiver(mReceiver);
Robert Ly12a1de02011-11-02 11:56:50 -0700378}
379</pre>
380
381 <p>When you have obtained a {@link android.net.wifi.p2p.WifiP2pManager.Channel} and
Scott Mainf5e09702013-08-22 17:19:17 -0700382 set up a broadcast receiver, your application can make Wi-Fi P2P method calls and receive
383 Wi-Fi P2P intents.</p>
Robert Ly12a1de02011-11-02 11:56:50 -0700384 </li>
385
Scott Mainf5e09702013-08-22 17:19:17 -0700386 <p>You can now implement your application and use the Wi-Fi P2P features by calling the
Robert Ly12a1de02011-11-02 11:56:50 -0700387 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>
Scott Main6aad9952013-01-07 18:51:49 -0800404mManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
Robert Ly12a1de02011-11-02 11:56:50 -0700405 &#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()
Scott Main6aad9952013-01-07 18:51:49 -0800432 if (mManager != null) {
433 mManager.requestPeers(mChannel, myPeerListListener);
Robert Ly12a1de02011-11-02 11:56:50 -0700434 }
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
kmccormick76dfc022013-04-03 12:41:12 -0700440 android.net.wifi.p2p.WifiP2pManager.PeerListListener#onPeersAvailable onPeersAvailable()}, which is defined in
Robert Ly12a1de02011-11-02 11:56:50 -0700441 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;
Scott Main6aad9952013-01-07 18:51:49 -0800460mManager.connect(mChannel, config, new ActionListener() {
Robert Ly12a1de02011-11-02 11:56:50 -0700461
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=
Scott Mainf5e09702013-08-22 17:19:17 -0700498 "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi P2P Demo</a> sample, shows you how
Robert Ly12a1de02011-11-02 11:56:50 -0700499 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=
Scott Mainf5e09702013-08-22 17:19:17 -0700501 "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi P2P Demo</a> sample.</p>
Robert Ly12a1de02011-11-02 11:56:50 -0700502<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>