1 page.title=Wi-Fi Peer-to-Peer 2 page.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 38 hardware to connect directly to each other via Wi-Fi without an intermediate access point (Android's 39 Wi-Fi P2P framework complies with the Wi-Fi Alliance's Wi-Fi Direct™ certification program). 40 Using these APIs, you can discover and connect to other devices when each device supports Wi-Fi P2P, 41 then communicate over a speedy connection across distances much longer than a Bluetooth connection. 42 This is useful for applications that share data among users, such as a multiplayer game or 43 a 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 */ 242 public 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 @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 <uses-sdk android:minSdkVersion="14" /> 290 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 291 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 292 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> 293 <uses-permission android:name="android.permission.INTERNET" /> 294 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 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 @Override 304 public 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> 331 WifiP2pManager mManager; 332 Channel mChannel; 333 BroadcastReceiver mReceiver; 334 ... 335 @Override 336 protected 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> 349 IntentFilter mIntentFilter; 350 ... 351 @Override 352 protected 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 @Override 369 protected void onResume() { 370 super.onResume(); 371 registerReceiver(mReceiver, mIntentFilter); 372 } 373 /* unregister the broadcast receiver */ 374 @Override 375 protected 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> 404 mManager.discoverPeers(channel, new WifiP2pManager.ActionListener() { 405 @Override 406 public void onSuccess() { 407 ... 408 } 409 410 @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> 425 PeerListListener myPeerListListener; 426 ... 427 if (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 457 WifiP2pDevice device; 458 WifiP2pConfig config = new WifiP2pConfig(); 459 config.deviceAddress = device.deviceAddress; 460 mManager.connect(mChannel, config, new ActionListener() { 461 462 @Override 463 public void onSuccess() { 464 //success logic 465 } 466 467 @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> 503 public 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 @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 @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> 566 Context context = this.getApplicationContext(); 567 String host; 568 int port; 569 int len; 570 Socket socket = new Socket(); 571 byte buf[] = new byte[1024]; 572 ... 573 try { 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 */ 604 finally { 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