diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index be0ca0e70caec..b8d95e2f107bc 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -364,6 +364,9 @@
Wi-Fi Direct allows Android 4.0 (API level 14) or later devices with the appropriate hardware + to connect directly to each other via Wi-Fi without an intermediate access point. + Using these APIs, you can discover and connect to other devices when each device supports Wi-Fi Direct, + then communicate over a speedy connection across distances much longer than a Bluetooth connection. + This is useful for applications that share data among users, such as a multiplayer game or + a photo sharing application.
+ +The Wi-Fi Direct APIs consist of the following main parts:
+ +You often use these three main components of the APIs together. For example, you can + provide a {@link android.net.wifi.p2p.WifiP2pManager.ActionListener} to a call to {@link + android.net.wifi.p2p.WifiP2pManager#discoverPeers discoverPeers()}, so that you can be + notified with the {@link android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess + ActionListener.onSuccess()} and {@link android.net.wifi.p2p.WifiP2pManager.ActionListener#onFailure + ActionListener.onFailure()} + methods. A {@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent is + also broadcast if the {@link android.net.wifi.p2p.WifiP2pManager#discoverPeers discoverPeers()} + method discovers that the peers list has changed.
+ +The {@link android.net.wifi.p2p.WifiP2pManager} class provides methods to allow you to interact with + the Wi-Fi hardware on your device to do things like discover and connect to peers. The following actions + are available:
+ +Table 1.Wi-Fi Direct Methods
+ +| Method | +Description | +
|---|---|
| {@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()} | +Registers the application with the Wi-Fi framework. This must be called before calling any other Wi-Fi Direct method. | +
| {@link android.net.wifi.p2p.WifiP2pManager#connect connect()} | +Starts a peer-to-peer connection with a device with the specified configuration. | +
| {@link android.net.wifi.p2p.WifiP2pManager#cancelConnect cancelConnect()} | +Cancels any ongoing peer-to-peer group negotiation. | +
| {@link android.net.wifi.p2p.WifiP2pManager#requestConnectionInfo requestConnectInfo()} | +Requests a device's connection information. | +
| {@link android.net.wifi.p2p.WifiP2pManager#createGroup createGroup()} | +Creates a peer-to-peer group with the current device as the group owner. | +
| {@link android.net.wifi.p2p.WifiP2pManager#removeGroup removeGroup()} | +Removes the current peer-to-peer group. | +
| {@link android.net.wifi.p2p.WifiP2pManager#requestGroupInfo requestGroupInfo()} | +Requests peer-to-peer group information. | +
| {@link android.net.wifi.p2p.WifiP2pManager.PeerListListener#discoverPeers discoverPeers()} | +Initiates peer discovery | +
| {@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()} | +Requests the current list of discovered peers. | +
{@link android.net.wifi.p2p.WifiP2pManager} methods let you pass in a listener, + so that the Wi-Fi Direct framework can notify your + activity of the status of a call. The available listener interfaces and the + corresponding {@link android.net.wifi.p2p.WifiP2pManager} method calls that use the listeners + are described in the following table:
+ +Table 2. Wi-Fi Direct Listeners
+ +| Listener interface | +Associated actions | +
|---|---|
| {@link android.net.wifi.p2p.WifiP2pManager.ActionListener} | +{@link android.net.wifi.p2p.WifiP2pManager#connect connect()}, {@link + android.net.wifi.p2p.WifiP2pManager#cancelConnect cancelConnect()}, {@link + android.net.wifi.p2p.WifiP2pManager#createGroup createGroup()}, {@link + android.net.wifi.p2p.WifiP2pManager#removeGroup removeGroup()}, and {@link + android.net.wifi.p2p.WifiP2pManager.PeerListListener#discoverPeers discoverPeers()} | +
| {@link android.net.wifi.p2p.WifiP2pManager.ChannelListener} | +{@link android.net.wifi.p2p.WifiP2pManager#initialize initialize()} | +
| {@link android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener} | +{@link android.net.wifi.p2p.WifiP2pManager#requestConnectionInfo requestConnectInfo()} | +
| {@link android.net.wifi.p2p.WifiP2pManager.GroupInfoListener} | +{@link android.net.wifi.p2p.WifiP2pManager#requestGroupInfo requestGroupInfo()} | +
| {@link android.net.wifi.p2p.WifiP2pManager.PeerListListener} | +{@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()} | +
The Wi-Fi Direct APIs define intents that are broadcast when certain Wi-Fi Direct events happen, + such as when a new peer is discovered or when a device's Wi-Fi state changes. You can register + to receive these intents in your application by creating a broadcast + receiver that handles these intents:
+ +Table 3. Wi-Fi Direct Intents
+ +| Intent | +Description | +
|---|---|
| {@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION} | +Broadcast when the state of the device's Wi-Fi connection changes. | +
| {@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} | +Broadcast when you call {@link + android.net.wifi.p2p.WifiP2pManager.PeerListListener#discoverPeers discoverPeers()}. You + usually want to call {@link android.net.wifi.p2p.WifiP2pManager.PeerListListener#requestPeers + requestPeers()} to get an updated list of peers if you handle this intent in your + application. | +
| {@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION} | +Broadcast when Wi-Fi Direct is enabled or disabled on the device. | +
| {@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_THIS_DEVICE_CHANGED_ACTION} | +Broadcast when a device's details have changed, such as the device's name. | +
A broadcast receiver allows you to receive intents broadcast by the Android system, + so that your application can respond to events that you are interested in. The basic steps + for creating a broadcast receiver to handle Wi-Fi Direct intents are as follows:
+ +{@link android.content.BroadcastReceiver#onReceive onReceive()}.
+ Carry out any necessary actions depending on the intent that is
+ received. For example, if the broadcast receiver receives a {@link
+ android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent, you can call the
+ {@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()} method to get a list of
+ the currently discovered peers.The following code shows you how to create a typical broadcast receiver. The broadcast + receiver takes a {@link android.net.wifi.p2p.WifiP2pManager} object and an activity as + arguments and uses these two classes to appropriately carry out the needed actions when the + broadcast receiver receives an intent:
+ +
+/**
+ * A BroadcastReceiver that notifies of important Wi-Fi p2p events.
+ */
+public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
+
+ private WifiP2pManager manager;
+ private Channel channel;
+ private MyWiFiActivity activity;
+
+ public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel,
+ MyWifiActivity activity) {
+ super();
+ this.manager = manager;
+ this.channel = channel;
+ this.activity = activity;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
+ // Check to see if Wi-Fi is enabled and notify appropriate activity
+ } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
+ // Call WifiP2pManager.requestPeers() to get a list of current peers
+ } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
+ // Respond to new connection or disconnections
+ } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
+ // Respond to this device's wifi state changing
+ }
+ }
+}
+
+
+ Creating a Wi-Fi Direct application involves creating and registering a + broadcast receiver for your application, discovering peers, connecting to a peer, and + transferring data to a peer. The following sections describe how to do this.
+ +Before using the Wi-Fi Direct APIs, you must ensure that your application can access + the hardware and that the device supports the Wi-Fi Direct protocol. If Wi-Fi Direct is supported, + you can obtain an instance of {@link android.net.wifi.p2p.WifiP2pManager}, create and register + your broadcast receiver, and begin using the Wi-Fi Direct APIs.
+Request permission to use the Wi-Fi hardware on the device and also declare + your application to have the correct minimum SDK version in the Android manifest:
++<uses-sdk android:minSdkVersion="14" /> +<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> +<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> +<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> +<uses-permission android:name="android.permission.INTERNET" /> +<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> ++
+@Override
+public void onReceive(Context context, Intent intent) {
+ ...
+ String action = intent.getAction();
+ if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
+ int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
+ if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
+ // Wifi Direct is enabled
+ } else {
+ // Wi-Fi Direct is not enabled
+ }
+ }
+ ...
+}
+
+
+WifiP2pManager mManager;
+Channel mChannel;
+BroadcastReceiver mReceiver;
+...
+@Override
+protected void onCreate(Bundle savedInstanceState){
+ ...
+ mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
+ mChannel = mManager.initialize(this, getMainLooper(), null);
+ Receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
+ ...
+}
+
+
+IntentFilter mIntentFilter;
+...
+@Override
+protected void onCreate(Bundle savedInstanceState){
+ ...
+ mIntentFilter = new IntentFilter();
+ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
+ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
+ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
+ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
+ ...
+}
+
+
+/* register the broadcast receiver with the intent values to be matched */
+@Override
+protected void onResume() {
+ super.onResume();
+ registerReceiver(receiver, intentFilter);
+}
+/* unregister the broadcast receiver */
+@Override
+protected void onPause() {
+ super.onPause();
+ unregisterReceiver(receiver);
+}
+
+
+ When you have obtained a {@link android.net.wifi.p2p.WifiP2pManager.Channel} and + set up a broadcast receiver, your application can make Wi-Fi Direct method calls and receive + Wi-Fi Direct intents.
+You can now implement your application and use the Wi-Fi Direct features by calling the + methods in {@link android.net.wifi.p2p.WifiP2pManager}. The next sections describe how to do common actions + such as discovering and connecting to peers.
+To discover peers that are available to connect to, call {@link + android.net.wifi.p2p.WifiP2pManager#discoverPeers discoverPeers()} to detect + available peers that are in range. The call to this function is asynchronous and a success or + failure is communicated to your application with {@link + android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess onSuccess()} and {@link + android.net.wifi.p2p.WifiP2pManager.ActionListener#onFailure onFailure()} if you created a + {@link android.net.wifi.p2p.WifiP2pManager.ActionListener}. The + {@link android.net.wifi.p2p.WifiP2pManager.ActionListener#onSuccess onSuccess()} method only notifies you + that the discovery process succeeded and does not provide any information about the actual peers + that it discovered, if any:
+
+manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
+ @Override
+ public void onSuccess() {
+ ...
+ }
+
+ @Override
+ public void onFailure(int reasonCode) {
+ ...
+ }
+});
+
+
+
+If the discovery process succeeds and detects peers, the system broadcasts the {@link + android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent, which you can listen + for in a broadcast receiver to obtain a list of peers. When your application receives the {@link + android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION} intent, you can request a + list of the discovered peers with {@link + android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()}. The following code shows how to set this up:
+
+PeerListListener myPeerListListener;
+...
+if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
+
+ // request available peers from the wifi p2p manager. This is an
+ // asynchronous call and the calling activity is notified with a
+ // callback on PeerListListener.onPeersAvailable()
+ if (manager != null) {
+ manager.requestPeers(channel, myPeerListListener);
+ }
+}
+
+
+ The {@link android.net.wifi.p2p.WifiP2pManager#requestPeers requestPeers()} method is also + asynchronous and can notify your activity when a list of peers is available with {@link + android.net.wifi.p2p.WifiP2pManager.PeerListListener#onPeersAvailable onPeersAvailable()}, which is defined in the + the {@link android.net.wifi.p2p.WifiP2pManager.PeerListListener} interface. The {@link + android.net.wifi.p2p.WifiP2pManager.PeerListListener#onPeersAvailable onPeersAvailable()} method + provides you with an {@link android.net.wifi.p2p.WifiP2pDeviceList}, which you can iterate + through to find the peer that you want to connect to.
+ +When you have figured out the device that you want to connect to after obtaining a list of + possible peers, call the {@link android.net.wifi.p2p.WifiP2pManager#connect connect()} method to + connect to the device. This method call requires a {@link android.net.wifi.p2p.WifiP2pConfig} + object that contains the information of the device to connect to. + You can be notified of a connection success or failure through the {@link + android.net.wifi.p2p.WifiP2pManager.ActionListener}. The following code + shows you how to create a connection to a desired device:
+
+//obtain a peer from the WifiP2pDeviceList
+WifiP2pDevice device;
+WifiP2pConfig config = new WifiP2pConfig();
+config.deviceAddress = device.deviceAddress;
+manager.connect(channel, config, new ActionListener() {
+
+ @Override
+ public void onSuccess() {
+ //success logic
+ }
+
+ @Override
+ public void onFailure(int reason) {
+ //failure logic
+ }
+});
+
+
+
+
+ Once a connection is established, you can transfer data between the devices with + sockets. The basic steps of transferring data are as follows:
+ +The following example, modified from the Wi-Fi Direct Demo sample, shows you how + to create this client-server socket communication and transfer JPEG images from a client + to a server with a service. For a complete working example, compile and run the Wi-Fi Direct Demo sample.
++public static class FileServerAsyncTask extends AsyncTask+ +{ + + private Context context; + private TextView statusText; + + public FileServerAsyncTask(Context context, View statusText) { + this.context = context; + this.statusText = (TextView) statusText; + } + + @Override + protected String doInBackground(Void... params) { + try { + + /** + * Create a server socket and wait for client connections. This + * call blocks until a connection is accepted from a client + */ + ServerSocket serverSocket = new ServerSocket(8888); + Socket client = serverSocket.accept(); + + /** + * If this code is reached, a client has connected and transferred data + * Save the input stream from the client as a JPEG file + */ + final File f = new File(Environment.getExternalStorageDirectory() + "/" + + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis() + + ".jpg"); + + File dirs = new File(f.getParent()); + if (!dirs.exists()) + dirs.mkdirs(); + f.createNewFile(); + InputStream inputstream = client.getInputStream(); + copyFile(inputstream, new FileOutputStream(f)); + serverSocket.close(); + return f.getAbsolutePath(); + } catch (IOException e) { + Log.e(WiFiDirectActivity.TAG, e.getMessage()); + return null; + } + } + + /** + * Start activity that can handle the JPEG image + */ + @Override + protected void onPostExecute(String result) { + if (result != null) { + statusText.setText("File copied - " + result); + Intent intent = new Intent(); + intent.setAction(android.content.Intent.ACTION_VIEW); + intent.setDataAndType(Uri.parse("file://" + result), "image/*"); + context.startActivity(intent); + } + } +} +
On the client, connect to the server socket with a client socket and transfer data. This example + transfers a JPEG file on the client device's file system.
+ +
+Context context = this.getApplicationContext();
+String host;
+int port;
+int len;
+Socket socket = new Socket();
+byte buf[] = new byte[1024];
+...
+try {
+ /**
+ * Create a client socket with the host,
+ * port, and timeout information.
+ */
+ socket.bind(null);
+ socket.connect((new InetSocketAddress(host, port)), 500);
+
+ /**
+ * Create a byte stream from a JPEG file and pipe it to the output stream
+ * of the socket. This data will be retrieved by the server device.
+ */
+ OutputStream outputStream = socket.getOutputStream();
+ ContentResolver cr = context.getContentResolver();
+ InputStream inputStream = null;
+ inputStream = cr.openInputStream(Uri.parse("path/to/picture.jpg"));
+ while ((len = inputStream.read(buf)) != -1) {
+ outputStream.write(buf, 0, len);
+ }
+ outputStream.close();
+ inputStream.close();
+} catch (FileNotFoundException e) {
+ //catch logic
+} catch (IOException e) {
+ //catch logic
+}
+
+/**
+ * Clean up any open sockets when done
+ * transferring or if an exception occurred.
+ */
+finally {
+ if (socket != null) {
+ if (socket.isConnected()) {
+ try {
+ socket.close();
+ } catch (IOException e) {
+ //catch logic
+ }
+ }
+ }
+}
+