1 page.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 */ 238 public 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 @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 <uses-sdk android:minSdkVersion="14" /> 286 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 287 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 288 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> 289 <uses-permission android:name="android.permission.INTERNET" /> 290 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 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 @Override 300 public 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> 327 WifiP2pManager mManager; 328 Channel mChannel; 329 BroadcastReceiver mReceiver; 330 ... 331 @Override 332 protected void onCreate(Bundle savedInstanceState){ 333 ... 334 mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); 335 mChannel = mManager.initialize(this, getMainLooper(), null); 336 mReceiver = new WiFiDirectBroadcastReceiver(manager, channel, this); 337 ... 338 } 339 </pre> 340 </li> 341 342 <li>Create an intent filter and add the same intents that your 343 broadcast receiver checks for: 344 <pre> 345 IntentFilter mIntentFilter; 346 ... 347 @Override 348 protected 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 @Override 365 protected void onResume() { 366 super.onResume(); 367 registerReceiver(mReceiver, mIntentFilter); 368 } 369 /* unregister the broadcast receiver */ 370 @Override 371 protected void onPause() { 372 super.onPause(); 373 unregisterReceiver(mReceiver); 374 } 375 </pre> 376 377 <p>When you have obtained a {@link android.net.wifi.p2p.WifiP2pManager.Channel} and 378 set up a broadcast receiver, your application can make Wi-Fi Direct method calls and receive 379 Wi-Fi Direct intents.</p> 380 </li> 381 382 <p>You can now implement your application and use the Wi-Fi Direct features by calling the 383 methods in {@link android.net.wifi.p2p.WifiP2pManager}. The next sections describe how to do common actions 384 such as discovering and connecting to peers.</p> 385 </ol> 386 387 <h3 id="discovering">Discovering peers</h3> 388 389 <p>To discover peers that are available to connect to, call {@link 390 android.net.wifi.p2p.WifiP2pManager#discoverPeers discoverPeers()} to detect 391 available peers that are in range. The call to this function is asynchronous and a success or 392 failure is communicated to your application with {@link 393 android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess onSuccess()} and {@link 394 android.net.wifi.p2p.WifiP2pManager.ActionListener#onFailure onFailure()} if you created a 395 {@link android.net.wifi.p2p.WifiP2pManager.ActionListener}. The 396 {@link android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess onSuccess()} method only notifies you 397 that the discovery process succeeded and does not provide any information about the actual peers 398 that it discovered, if any:</p> 399 <pre> 400 manager.discoverPeers(channel, new WifiP2pManager.ActionListener() { 401 @Override 402 public void onSuccess() { 403 ... 404 } 405 406 @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> 421 PeerListListener myPeerListListener; 422 ... 423 if (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 453 WifiP2pDevice device; 454 WifiP2pConfig config = new WifiP2pConfig(); 455 config.deviceAddress = device.deviceAddress; 456 manager.connect(channel, config, new ActionListener() { 457 458 @Override 459 public void onSuccess() { 460 //success logic 461 } 462 463 @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> 499 public 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 @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 @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> 562 Context context = this.getApplicationContext(); 563 String host; 564 int port; 565 int len; 566 Socket socket = new Socket(); 567 byte buf[] = new byte[1024]; 568 ... 569 try { 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 */ 600 finally { 601 if (socket != null) { 602 if (socket.isConnected()) { 603 try { 604 socket.close(); 605 } catch (IOException e) { 606 //catch logic 607 } 608 } 609 } 610 } 611 </pre> 612