Android API Guides --- Wi-Fi Peer-to-Peer
Wi-Fi Peer-to-Peer
Wi-Fi peer-to-peer network (P2P) for Android 4.0 (API Level 14) or a device of a higher hardware version is directly connected to the other device without an intermediate Access Point through Wi-Fi (the P2P Architecture connected to the Android wireless network conforms to the Wi-Fi direct connection in the Wi-Fi Alliance? Certification plan ). By using these APIs, you can discover and connect to other devices, each device supports Wi-Fi P2P, and then rapidly connect over a distance over a Bluetooth connection. This is an application that allows users to share data, such as a multiplayer game or photo sharing application.
The Wi-Fi P2P APIs include the following:
Methods, allowing you to discover, request, and connect to peers defined in the WifiP2pManager class.
Listener to notify you of the successful or failed WifiP2pManager method call. When the WifiP2pManager method is called, each method can receive a listener that is specified as a parameter.
Notifies you of specific events that have passed the Wi-Fi P2P architecture, such as discarding connections or newly discovered peer intentions.
You often use these three main components together. For example, you can provide a WifiP2pManager. ActionListener to call discoverPeers (), so that you can use the ActionListener. onSuccess () and ActionListener. onFailure () methods for notification. If the discoverPeers () method is used, it is found that the intention of WIFI_P2P_PEERS_CHANGED_ACTION has been changed in the Peer list and the message is also broadcast.
API Overview
This WifiP2pManager class provides some methods for your Wi-Fi hardware devices to do things like discovering and connecting to peers. The following operations are available:
Table 1. Wi network P2P Method
Method description
Initialize () Registration and Wi-Fi wireless architecture applications. This must be called before calling any other Wi-Fi point-to-point method.
Connection () starts a peering network connection with the specified device.
CancelConnect () cancels any ongoing peer-to-peer network group negotiation.
The connection information of the device requested by requestConnectInfo.
CreateGroup () creates a peer network group and the current device is the group owner.
RemoveGroup () deletes the current peer network group.
The peer group information of the requestGroupInfo () request.
DiscoverPeers () initiates Peer Discovery
RequestPeers () requests to find the current list of peers.
The WifiP2pManager method allows you to transmit messages to the audience so that the P2P architecture of the wireless network can notify you of call status activities. Use the listener Interface available for this listener and the corresponding WifiP2pManager method as described in the following table:
Table 2 Wi-Fi point-to-point listeners
Listener Interface related actions
WifiP2pManager. ActionListener connection (), cancelConnect (), createGroup (), removeGroup (), and discoverPeers ()
WifiP2pManager. ChannelListener initialization ()
WifiP2pManager. ConnectionInfoListener requestConnectInfo ()
WifiP2pManager. GroupInfoListener requestGroupInfo ()
WifiP2pManager. peerlistener requestPeers ()
When a Wi-Fi point-to-point API defines the intent, some wireless network connection P2P events occur, broadcast, when a new peering discovery or when the device's Wi-Fi status changes, for example. You can register a broadcast receiver that processes these intents to receive these intents in the application:
Table 3. P2P intent of wireless network connection
Description
WIFI_P2P_CONNECTION_CHANGED_ACTION broadcast when the device's wi-fi connection status changes.
WIFI_P2P_PEERS_CHANGED_ACTION broadcast when you call discoverPeers (). Usually you want to call requestPeers () If you handle this intent to get the same update list in the application.
WIFI_P2P_STATE_CHANGED_ACTION is enabled for Wi-Fi P2P Broadcast or disabled on the device.
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION broadcast when the device details change, such as the device name.
Create a broadcast receiver's Wi-Fi P2P intent
Broadcast receiver, which can be played by the intended Android system, the basic steps for your application to be interested in responding to events are to create a broadcast receiver to process the Wi-Fi point-to-point intent as follows:
Create an extended BroadcastReceiver class. For Class constructor, you may want WifiP2pManager and WifiP2pManager. channel, and this broadcast receiver will register the active parameters, which enables the broadcast receiver to send updates to the active and access the hardware and communication channels if needed for wireless network connection.
In the broadcast receiver, check the intention of onReceive () that you are interested in. Execution depends on any necessary action of the received intent. For example, if the broadcast receiver receives the WIFI_P2P_PEERS_CHANGED_ACTION intent, you can call the requestPeers () method to obtain the discovered peer-to-peer list.
The following code demonstrates how to create a typical broadcast receiver. The broadcast receiver requires a WifiP2pManager object as a parameter activity and uses these two classes as the intent of the broadcast receiver to receive appropriate actions:
/*** A BroadcastReceiver that notifies of important Wi-Fi p2p events.*/public class WiFiDirectBroadcastReceiver extends BroadcastReceiver { private WifiP2pManager mManager; private Channel mChannel; private MyWiFiActivity mActivity; public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel, MyWifiActivity activity) { super(); this.mManager = manager; this.mChannel = channel; this.mActivity = 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 } }}
Create a Wi-Fi P2P application
Create a Wi-Fi P2P application including creating and registering a broadcast receiver for your application, discovering peers, connecting to a peer, and transmitting data to peer. The following sections describe how to do this.
Initial settings
Before using the Wi-Fi P2P API, make sure that your application can access the Wi-Fi P2P protocol supported by hardware and devices. If you support Wi-Fi P2P, you can obtain an instance of WifiP2pManager, create and register your broadcast receiver, and start using the Wi-Fi P2P API.
Requesting permission to use the Wi-Fi hardware on the device also declares the correct minimum SDK version of your application in the Android list:
Check whether the P2P connection to the wireless network is in and supported. A good place to check that this is your broadcast receiver when it receives the WIFI_STATE_CHANGED_ACTION intent. Notify you of P2P activities in Wi-Fi status and respond accordingly:
@Overridepublic 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 P2P is enabled } else { // Wi-Fi P2P is not enabled } } ...}
In the active onCreate () method, obtain an instance of WifiP2pManager and call the initialization register with Wi-Fi wireless P2P Architecture your application (). This method returns a WifiP2pManager. Channel used to connect your applications in a Wi-Fi P2P architecture. You should also create a WifiP2pManager instance for your broadcast receiver and work with the WifiP2pManager. Channel reference object for your activities. This enables your broadcast receiver to notify you of the event activities you are interested in and update accordingly. It also allows you to manipulate the device's Wi-Fi status when necessary:
WifiP2pManager mManager;Channel mChannel;BroadcastReceiver mReceiver;...@Overrideprotected void onCreate(Bundle savedInstanceState){ ... mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); mChannel = mManager.initialize(this, getMainLooper(), null); mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this); ...}
Create an intent filter and add the same intent for your broadcast receiver check:
IntentFilter mIntentFilter;...@Overrideprotected 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 in the onResume () method of your activity and cancel registration in the onPause () method of the activity:
/* register the broadcast receiver with the intent values to be matched */@Overrideprotected void onResume() { super.onResume(); registerReceiver(mReceiver, mIntentFilter);}/* unregister the broadcast receiver */@Overrideprotected void onPause() { super.onPause(); unregisterReceiver(mReceiver);}
When you have obtained WifiP2pManager. Channel and set up a broadcast receiver, the application can enable P2P wireless networks to call and receive Wi-Fi point-to-point intentions.
Now, you can implement your application and use the Wi-Fi function P2P by calling the WifiP2pManager method. The following section describes how to act together, such as discovering and connecting peers.
Discovering peers
To discover that peers can be connected, call discoverPeers () to detect available peers within a range. The call of this function is asynchronous. A successful or failed onSuccess () and onFailure () are passed to your application. If you create a WifiP2pManager. ActionListener. This onSuccess () method only notifies you that the discovery process is successful and does not provide any information about the actual peers. It finds that, if there is:
mManager.discoverPeers(channel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { ... } @Override public void onFailure(int reasonCode) { ... }});
If the process is successful and the peer body is detected, the System Broadcasts the WIFI_P2P_PEERS_CHANGED_ACTION intent, and can listen on a broadcast receiver to obtain a list of the peers. When your application receives the WIFI_P2P_PEERS_CHANGED_ACTION intent, you can request the list of discovered peers and requestPeers (). The following code demonstrates how to set this:
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 (mManager != null) { mManager.requestPeers(mChannel, myPeerListListener); }}
This requestPeers () method is also asynchronous, which can notify you that the Peer list can be equivalent to the existing one () during the activity, which is defined in the WifiP2pManager. peerlistener interface. This onPeersAvailable () method provides a WifiP2pDeviceList, You can traverse to find the same level that you want to connect.
Connect to your peers
After you have figured out that you want to obtain a list of possible peers, connect to the device and call the connect () method to connect to the device. This method call needs to contain the device information to connect to a WifiP2pConfig object. You can notify the successful or failed connection through WifiP2pManager. ActionListener. The following code creates a connection to a device:
//obtain a peer from the WifiP2pDeviceListWifiP2pDevice device;WifiP2pConfig config = new WifiP2pConfig();config.deviceAddress = device.deviceAddress;mManager.connect(mChannel, config, new ActionListener() { @Override public void onSuccess() { //success logic } @Override public void onFailure(int reason) { //failure logic }});
Transmit data
Once a connection is established, you can use a socket to transmit data between devices. The basic steps for data transmission are as follows:
Create a ServerSocket. This socket waits for the connection from the specified port of the client to the block until it occurs, so this is done in the background thread.
Create a client Socket. The client uses the IP address and port of the server socket to connect to the server device.
Send data from the client to the server. When the client socket is successfully connected to the server socket, the data and byte stream server sent from the client can be used.
The server socket waits for the client to connect (use the accept () method ). This call block is called until the client connects, so this is another thread. When a connection occurs, the server device can receive data from the client. Execute any actions related to the data, such as saving it to a file or presenting it to the user.
The following example shows how to create a client-server socket communication and transmit JPEG images from the client and service to the server. For a complete working example, compile and run a Wi-Fi point-to-point demonstration 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 client socket and the server socket for data transmission. In this example, the JPEG file on the file system of the client device is transmitted.
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 } } }}