1 page.title=Wi-Fi Direct 2 page.tags="wireless","WifiP2pManager" 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 Direct Intents</a></li> 13 14 <li> 15 <a href="#creating-app">Creating a Wi-Fi Direct 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>Related Samples</h2> 29 <ol> 30 <li><a href="{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a></li> 31 </ol> 32 </div> 33 </div> 34 35 <p>Wi-Fi Direct allows Android 4.0 (API level 14) or later devices with the appropriate hardware 36 to connect directly to each other via Wi-Fi without an intermediate access point. 37 Using these APIs, you can discover and connect to other devices when each device supports Wi-Fi Direct, 38 then communicate over a speedy connection across distances much longer than a Bluetooth connection. 39 This is useful for applications that share data among users, such as a multiplayer game or 40 a photo sharing application.</p> 41 42 <p>The Wi-Fi Direct APIs consist of the following main parts:</p> 43 44 <ul> 45 <li>Methods that allow you to discover, request, and connect to peers are defined 46 in the {@link android.net.wifi.p2p.WifiP2pManager} class.</li> 47 48 <li>Listeners that allow you to be notified of the success or failure of {@link 49 android.net.wifi.p2p.WifiP2pManager} method calls. When calling {@link 50 android.net.wifi.p2p.WifiP2pManager} methods, each method can receive a specific listener 51 passed in as a parameter.</li> 52 53 <li>Intents that notify you of specific events detected by the Wi-Fi Direct framework, 54 such as a dropped connection or a newly discovered peer.</li> 55 </ul> 56 57 <p>You often use these three main components of the APIs together. For example, you can 58 provide a {@link android.net.wifi.p2p.WifiP2pManager.ActionListener} to a call to {@link 59 android.net.wifi.p2p.WifiP2pManager#discoverPeers discoverPeers()}, so that you can be 60 notified with the {@link android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess 61 ActionListener.onSuccess()} and {@link android.net.wifi.p2p.WifiP2pManager.ActionListener#onFailure 62 ActionListener.onFailure()} 63 methods. A {@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent is 64 also broadcast if the {@link android.net.wifi.p2p.WifiP2pManager#discoverPeers discoverPeers()} 65 method discovers that the peers list has changed.</p> 66 67 <h2 id="api">API Overview</h2> 68 69 <p>The {@link android.net.wifi.p2p.WifiP2pManager} class provides methods to allow you to interact with 70 the Wi-Fi hardware on your device to do things like discover and connect to peers. The following actions 71 are available:</p> 72 73 <p class="table-caption"><strong>Table 1.</strong>Wi-Fi Direct Methods</p> 74 75 <table> 76 <tr> 77 <th>Method</th> 78 <th>Description</th> 79 </tr> 80 81 <tr> 82 <td>{@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</td> 83 <td>Registers the application with the Wi-Fi framework. This must be called before calling any other Wi-Fi Direct method.</td> 84 </tr> 85 86 <tr> 87 <td>{@link android.net.wifi.p2p.WifiP2pManager#connect connect()}</td> 88 <td>Starts a peer-to-peer connection with a device with the specified configuration.</td> 89 </tr> 90 91 <tr> 92 <td>{@link android.net.wifi.p2p.WifiP2pManager#cancelConnect cancelConnect()}</td> 93 <td>Cancels any ongoing peer-to-peer group negotiation.</td> 94 </tr> 95 96 <tr> 97 <td>{@link android.net.wifi.p2p.WifiP2pManager#requestConnectionInfo requestConnectInfo()}</td> 98 <td>Requests a device's connection information.</td> 99 </tr> 100 101 <tr> 102 <td>{@link android.net.wifi.p2p.WifiP2pManager#createGroup createGroup()}</td> 103 <td>Creates a peer-to-peer group with the current device as the group owner.</td> 104 </tr> 105 106 <tr> 107 <td>{@link android.net.wifi.p2p.WifiP2pManager#removeGroup removeGroup()}</td> 108 <td>Removes the current peer-to-peer group.</td> 109 </tr> 110 111 <tr> 112 <td>{@link android.net.wifi.p2p.WifiP2pManager#requestGroupInfo requestGroupInfo()}</td> 113 <td>Requests peer-to-peer group information.</td> 114 </tr> 115 116 <tr> 117 <td>{@link android.net.wifi.p2p.WifiP2pManager.PeerListListener#discoverPeers discoverPeers()}</td> 118 <td>Initiates peer discovery </td> 119 </tr> 120 121 <tr> 122 <td>{@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()}</td> 123 <td>Requests the current list of discovered peers.</td> 124 </tr> 125 </table> 126 127 128 <p>{@link android.net.wifi.p2p.WifiP2pManager} methods let you pass in a listener, 129 so that the Wi-Fi Direct framework can notify your 130 activity of the status of a call. The available listener interfaces and the 131 corresponding {@link android.net.wifi.p2p.WifiP2pManager} method calls that use the listeners 132 are described in the following table:</p> 133 134 <p class="table-caption"><strong>Table 2.</strong> Wi-Fi Direct Listeners</p> 135 136 <table> 137 <tr> 138 <th>Listener interface</th> 139 <th>Associated actions</th> 140 </tr> 141 <tr> 142 <td>{@link android.net.wifi.p2p.WifiP2pManager.ActionListener}</td> 143 <td>{@link android.net.wifi.p2p.WifiP2pManager#connect connect()}, {@link 144 android.net.wifi.p2p.WifiP2pManager#cancelConnect cancelConnect()}, {@link 145 android.net.wifi.p2p.WifiP2pManager#createGroup createGroup()}, {@link 146 android.net.wifi.p2p.WifiP2pManager#removeGroup removeGroup()}, and {@link 147 android.net.wifi.p2p.WifiP2pManager.PeerListListener#discoverPeers discoverPeers()}</td> 148 </tr> 149 150 <tr> 151 <td>{@link android.net.wifi.p2p.WifiP2pManager.ChannelListener}</td> 152 <td>{@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</td> 153 </tr> 154 155 <tr> 156 <td>{@link android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener}</td> 157 <td>{@link android.net.wifi.p2p.WifiP2pManager#requestConnectionInfo requestConnectInfo()}</td> 158 </tr> 159 160 <tr> 161 <td>{@link android.net.wifi.p2p.WifiP2pManager.GroupInfoListener}</td> 162 <td>{@link android.net.wifi.p2p.WifiP2pManager#requestGroupInfo requestGroupInfo()}</td> 163 </tr> 164 165 <tr> 166 <td>{@link android.net.wifi.p2p.WifiP2pManager.PeerListListener}</td> 167 <td>{@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()}</td> 168 </tr> 169 </table> 170 171 <p>The Wi-Fi Direct APIs define intents that are broadcast when certain Wi-Fi Direct events happen, 172 such as when a new peer is discovered or when a device's Wi-Fi state changes. You can register 173 to receive these intents in your application by <a href="#creating-br">creating a broadcast 174 receiver</a> that handles these intents:</p> 175 176 <p class="table-caption"><strong>Table 3.</strong> Wi-Fi Direct Intents</p> 177 178 <table> 179 <tr> 180 <th>Intent</th> 181 <th>Description</th> 182 </tr> 183 <tr> 184 <td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION}</td> 185 <td>Broadcast when the state of the device's Wi-Fi connection changes.</td> 186 </tr> 187 <tr> 188 <td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION}</td> 189 <td>Broadcast when you call {@link 190 android.net.wifi.p2p.WifiP2pManager.PeerListListener#discoverPeers discoverPeers()}. You 191 usually want to call {@link android.net.wifi.p2p.WifiP2pManager.PeerListListener#requestPeers 192 requestPeers()} to get an updated list of peers if you handle this intent in your 193 application.</td> 194 </tr> 195 <tr> 196 <td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION}</td> 197 <td>Broadcast when Wi-Fi Direct is enabled or disabled on the device.</td> 198 </tr> 199 <tr> 200 <td>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_THIS_DEVICE_CHANGED_ACTION}</td> 201 <td>Broadcast when a device's details have changed, such as the device's name.</td> 202 </tr> 203 </table> 204 205 206 207 <h2 id="creating-br">Creating a Broadcast Receiver for Wi-Fi Direct Intents</h2> 208 209 <p>A broadcast receiver allows you to receive intents broadcast by the Android system, 210 so that your application can respond to events that you are interested in. The basic steps 211 for creating a broadcast receiver to handle Wi-Fi Direct intents are as follows:</p> 212 213 <ol> 214 <li>Create a class that extends the {@link android.content.BroadcastReceiver} class. For the 215 class' constructor, you most likely want to have parameters for the {@link 216 android.net.wifi.p2p.WifiP2pManager}, {@link android.net.wifi.p2p.WifiP2pManager.Channel}, and 217 the activity that this broadcast receiver will be registered in. This allows the broadcast 218 receiver to send updates to the activity as well as have access to the Wi-Fi hardware and a 219 communication channel if needed.</li> 220 221 <li>In the broadcast receiver, check for the intents that you are interested in 222 <code>{@link android.content.BroadcastReceiver#onReceive onReceive()}</code>. 223 Carry out any necessary actions depending on the intent that is 224 received. For example, if the broadcast receiver receives a {@link 225 android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent, you can call the 226 {@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()} method to get a list of 227 the currently discovered peers.</li> 228 </ol> 229 230 <p>The following code shows you how to create a typical broadcast receiver. The broadcast 231 receiver takes a {@link android.net.wifi.p2p.WifiP2pManager} object and an activity as 232 arguments and uses these two classes to appropriately carry out the needed actions when the 233 broadcast receiver receives an intent:</p> 234 235 <pre> 236 /** 237 * A BroadcastReceiver that notifies of important Wi-Fi p2p events. 238 */ 239 public class WiFiDirectBroadcastReceiver extends BroadcastReceiver { 240 241 private WifiP2pManager mManager; 242 private Channel mChannel; 243 private MyWiFiActivity mActivity; 244 245 public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel, 246 MyWifiActivity activity) { 247 super(); 248 this.mManager = manager; 249 this.mChannel = channel; 250 this.mActivity = activity; 251 } 252 253 @Override 254 public void onReceive(Context context, Intent intent) { 255 String action = intent.getAction(); 256 257 if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { 258 // Check to see if Wi-Fi is enabled and notify appropriate activity 259 } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { 260 // Call WifiP2pManager.requestPeers() to get a list of current peers 261 } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { 262 // Respond to new connection or disconnections 263 } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { 264 // Respond to this device's wifi state changing 265 } 266 } 267 } 268 </pre> 269 270 <h2 id="creating-app">Creating a Wi-Fi Direct Application</h2> 271 272 <p>Creating a Wi-Fi Direct application involves creating and registering a 273 broadcast receiver for your application, discovering peers, connecting to a peer, and 274 transferring data to a peer. The following sections describe how to do this.</p> 275 276 <h3 id="setup">Initial setup</h3> 277 <p>Before using the Wi-Fi Direct APIs, you must ensure that your application can access 278 the hardware and that the device supports the Wi-Fi Direct protocol. If Wi-Fi Direct is supported, 279 you can obtain an instance of {@link android.net.wifi.p2p.WifiP2pManager}, create and register 280 your broadcast receiver, and begin using the Wi-Fi Direct APIs.</p> 281 <ol> 282 <li> 283 <p>Request permission to use the Wi-Fi hardware on the device and also declare 284 your application to have the correct minimum SDK version in the Android manifest:</p> 285 <pre> 286 <uses-sdk android:minSdkVersion="14" /> 287 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 288 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 289 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> 290 <uses-permission android:name="android.permission.INTERNET" /> 291 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 292 </pre> 293 </li> 294 295 <li>Check to see if Wi-Fi Direct is on and supported. A good place to check this is in your 296 broadcast receiver when it receives the {@link 297 android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION} intent. Notify your 298 activity of the Wi-Fi Direct state and react accordingly: 299 <pre> 300 @Override 301 public void onReceive(Context context, Intent intent) { 302 ... 303 String action = intent.getAction(); 304 if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { 305 int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1); 306 if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { 307 // Wifi Direct is enabled 308 } else { 309 // Wi-Fi Direct is not enabled 310 } 311 } 312 ... 313 } 314 </pre> 315 </li> 316 317 <li>In your activity's {@link android.app.Activity#onCreate onCreate()} method, obtain an instance of {@link 318 android.net.wifi.p2p.WifiP2pManager} and register your application with the Wi-Fi Direct 319 framework by calling {@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()}. This 320 method returns a {@link android.net.wifi.p2p.WifiP2pManager.Channel}, which is used to connect 321 your application to the Wi-Fi Direct framework. You should also create an instance of your 322 broadcast receiver with the {@link 323 android.net.wifi.p2p.WifiP2pManager} and {@link android.net.wifi.p2p.WifiP2pManager.Channel} 324 objects along with a reference to your activity. This allows your broadcast receiver to notify 325 your activity of interesting events and update it accordingly. It also lets you manipulate the device's 326 Wi-Fi state if necessary: 327 <pre> 328 WifiP2pManager mManager; 329 Channel mChannel; 330 BroadcastReceiver mReceiver; 331 ... 332 @Override 333 protected void onCreate(Bundle savedInstanceState){ 334 ... 335 mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); 336 mChannel = mManager.initialize(this, getMainLooper(), null); 337 mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this); 338 ... 339 } 340 </pre> 341 </li> 342 343 <li>Create an intent filter and add the same intents that your 344 broadcast receiver checks for: 345 <pre> 346 IntentFilter mIntentFilter; 347 ... 348 @Override 349 protected void onCreate(Bundle savedInstanceState){ 350 ... 351 mIntentFilter = new IntentFilter(); 352 mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); 353 mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); 354 mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); 355 mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); 356 ... 357 } 358 </pre> 359 </li> 360 361 <li>Register the broadcast receiver in the {@link android.app.Activity#onResume()} method 362 of your activity and unregister it in the {@link android.app.Activity#onPause()} method of your activity: 363 <pre> 364 /* register the broadcast receiver with the intent values to be matched */ 365 @Override 366 protected void onResume() { 367 super.onResume(); 368 registerReceiver(mReceiver, mIntentFilter); 369 } 370 /* unregister the broadcast receiver */ 371 @Override 372 protected void onPause() { 373 super.onPause(); 374 unregisterReceiver(mReceiver); 375 } 376 </pre> 377 378 <p>When you have obtained a {@link android.net.wifi.p2p.WifiP2pManager.Channel} and 379 set up a broadcast receiver, your application can make Wi-Fi Direct method calls and receive 380 Wi-Fi Direct intents.</p> 381 </li> 382 383 <p>You can now implement your application and use the Wi-Fi Direct features by calling the 384 methods in {@link android.net.wifi.p2p.WifiP2pManager}. The next sections describe how to do common actions 385 such as discovering and connecting to peers.</p> 386 </ol> 387 388 <h3 id="discovering">Discovering peers</h3> 389 390 <p>To discover peers that are available to connect to, call {@link 391 android.net.wifi.p2p.WifiP2pManager#discoverPeers discoverPeers()} to detect 392 available peers that are in range. The call to this function is asynchronous and a success or 393 failure is communicated to your application with {@link 394 android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess onSuccess()} and {@link 395 android.net.wifi.p2p.WifiP2pManager.ActionListener#onFailure onFailure()} if you created a 396 {@link android.net.wifi.p2p.WifiP2pManager.ActionListener}. The 397 {@link android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess onSuccess()} method only notifies you 398 that the discovery process succeeded and does not provide any information about the actual peers 399 that it discovered, if any:</p> 400 <pre> 401 mManager.discoverPeers(channel, new WifiP2pManager.ActionListener() { 402 @Override 403 public void onSuccess() { 404 ... 405 } 406 407 @Override 408 public void onFailure(int reasonCode) { 409 ... 410 } 411 }); 412 413 </pre> 414 415 <p>If the discovery process succeeds and detects peers, the system broadcasts the {@link 416 android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent, which you can listen 417 for in a broadcast receiver to obtain a list of peers. When your application receives the {@link 418 android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent, you can request a 419 list of the discovered peers with {@link 420 android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()}. The following code shows how to set this up:</p> 421 <pre> 422 PeerListListener myPeerListListener; 423 ... 424 if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { 425 426 // request available peers from the wifi p2p manager. This is an 427 // asynchronous call and the calling activity is notified with a 428 // callback on PeerListListener.onPeersAvailable() 429 if (mManager != null) { 430 mManager.requestPeers(mChannel, myPeerListListener); 431 } 432 } 433 </pre> 434 435 <p>The {@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()} method is also 436 asynchronous and can notify your activity when a list of peers is available with {@link 437 android.net.wifi.p2p.WifiP2pManager.PeerListListener#onPeersAvailable onPeersAvailable()}, which is defined in 438 the {@link android.net.wifi.p2p.WifiP2pManager.PeerListListener} interface. The {@link 439 android.net.wifi.p2p.WifiP2pManager.PeerListListener#onPeersAvailable onPeersAvailable()} method 440 provides you with an {@link android.net.wifi.p2p.WifiP2pDeviceList}, which you can iterate 441 through to find the peer that you want to connect to.</p> 442 443 <h3 id="connecting">Connecting to peers</h3> 444 445 <p>When you have figured out the device that you want to connect to after obtaining a list of 446 possible peers, call the {@link android.net.wifi.p2p.WifiP2pManager#connect connect()} method to 447 connect to the device. This method call requires a {@link android.net.wifi.p2p.WifiP2pConfig} 448 object that contains the information of the device to connect to. 449 You can be notified of a connection success or failure through the {@link 450 android.net.wifi.p2p.WifiP2pManager.ActionListener}. The following code 451 shows you how to create a connection to a desired device:</p> 452 <pre> 453 //obtain a peer from the WifiP2pDeviceList 454 WifiP2pDevice device; 455 WifiP2pConfig config = new WifiP2pConfig(); 456 config.deviceAddress = device.deviceAddress; 457 mManager.connect(mChannel, config, new ActionListener() { 458 459 @Override 460 public void onSuccess() { 461 //success logic 462 } 463 464 @Override 465 public void onFailure(int reason) { 466 //failure logic 467 } 468 }); 469 470 </pre> 471 472 473 <h3 id="transferring">Transferring data</h3> 474 <p>Once a connection is established, you can transfer data between the devices with 475 sockets. The basic steps of transferring data are as follows:</p> 476 477 <ol> 478 <li>Create a {@link java.net.ServerSocket}. This socket waits for a connection from a client on a specified 479 port and blocks until it happens, so do this in a background thread.</li> 480 481 <li>Create a client {@link java.net.Socket}. The client uses the IP address and port of 482 the server socket to connect to the server device.</li> 483 484 <li>Send data from the client to the server. When the client 485 socket successfully connects to the server socket, you can send data from the client to the server 486 with byte streams. </li> 487 488 <li>The server socket waits for a client connection (with the {@link java.net.ServerSocket#accept()} method). This 489 call blocks until a client connects, so call this is another thread. When a connection happens, the server device can receive 490 the data from the client. Carry out any actions with this data, such as saving it to a file 491 or presenting it to the user.</li> 492 </ol> 493 494 <p>The following example, modified from the <a href= 495 "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a> sample, shows you how 496 to create this client-server socket communication and transfer JPEG images from a client 497 to a server with a service. For a complete working example, compile and run the <a href= 498 "{@docRoot}resources/samples/WiFiDirectDemo/index.html">Wi-Fi Direct Demo</a> sample.</p> 499 <pre> 500 public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> { 501 502 private Context context; 503 private TextView statusText; 504 505 public FileServerAsyncTask(Context context, View statusText) { 506 this.context = context; 507 this.statusText = (TextView) statusText; 508 } 509 510 @Override 511 protected String doInBackground(Void... params) { 512 try { 513 514 /** 515 * Create a server socket and wait for client connections. This 516 * call blocks until a connection is accepted from a client 517 */ 518 ServerSocket serverSocket = new ServerSocket(8888); 519 Socket client = serverSocket.accept(); 520 521 /** 522 * If this code is reached, a client has connected and transferred data 523 * Save the input stream from the client as a JPEG file 524 */ 525 final File f = new File(Environment.getExternalStorageDirectory() + "/" 526 + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis() 527 + ".jpg"); 528 529 File dirs = new File(f.getParent()); 530 if (!dirs.exists()) 531 dirs.mkdirs(); 532 f.createNewFile(); 533 InputStream inputstream = client.getInputStream(); 534 copyFile(inputstream, new FileOutputStream(f)); 535 serverSocket.close(); 536 return f.getAbsolutePath(); 537 } catch (IOException e) { 538 Log.e(WiFiDirectActivity.TAG, e.getMessage()); 539 return null; 540 } 541 } 542 543 /** 544 * Start activity that can handle the JPEG image 545 */ 546 @Override 547 protected void onPostExecute(String result) { 548 if (result != null) { 549 statusText.setText("File copied - " + result); 550 Intent intent = new Intent(); 551 intent.setAction(android.content.Intent.ACTION_VIEW); 552 intent.setDataAndType(Uri.parse("file://" + result), "image/*"); 553 context.startActivity(intent); 554 } 555 } 556 } 557 </pre> 558 559 <p>On the client, connect to the server socket with a client socket and transfer data. This example 560 transfers a JPEG file on the client device's file system.</p> 561 562 <pre> 563 Context context = this.getApplicationContext(); 564 String host; 565 int port; 566 int len; 567 Socket socket = new Socket(); 568 byte buf[] = new byte[1024]; 569 ... 570 try { 571 /** 572 * Create a client socket with the host, 573 * port, and timeout information. 574 */ 575 socket.bind(null); 576 socket.connect((new InetSocketAddress(host, port)), 500); 577 578 /** 579 * Create a byte stream from a JPEG file and pipe it to the output stream 580 * of the socket. This data will be retrieved by the server device. 581 */ 582 OutputStream outputStream = socket.getOutputStream(); 583 ContentResolver cr = context.getContentResolver(); 584 InputStream inputStream = null; 585 inputStream = cr.openInputStream(Uri.parse("path/to/picture.jpg")); 586 while ((len = inputStream.read(buf)) != -1) { 587 outputStream.write(buf, 0, len); 588 } 589 outputStream.close(); 590 inputStream.close(); 591 } catch (FileNotFoundException e) { 592 //catch logic 593 } catch (IOException e) { 594 //catch logic 595 } 596 597 /** 598 * Clean up any open sockets when done 599 * transferring or if an exception occurred. 600 */ 601 finally { 602 if (socket != null) { 603 if (socket.isConnected()) { 604 try { 605 socket.close(); 606 } catch (IOException e) { 607 //catch logic 608 } 609 } 610 } 611 } 612 </pre> 613