Original address: Http://android.xsoftlab.net/training/connect-devices-wirelessly/wifi-direct.html#permissions
Wi-Fi peer-to-peer APIs allow programs to communicate directly with nearby devices, and the Android Wi-Fi peer-to-frame is powered by Wi-Fi Direct. Wi-Fi peer technology enables programs to quickly retrieve and connect to nearby devices. Its coverage is larger than the Bluetooth coverage range.
This class will learn how to search for nearby devices and connect to them with Wi-Fi peer-to-peer technology.
Set app Permissions
If you want to use Wi-Fi peer technology, you need to add change\_wifi\_state, Access\_wifi\_state, Internet three permissions to your program's manifest file. Wi-Fi peer does not require an Internet connection, but it requires the use of standard Java socket Communication technology, so internet access is required:
<manifest xmlns: android = "http://schemas.android.com/apk/res/android"
package = "com.example.android.nsdchat"
...
<uses-permission
android: required = "true"
android: name = "android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android: required = "true"
android: name = "android.permission.CHANGE_WIFI_STATE" />
<uses-permission
android: required = "true"
android: name = "android.permission.INTERNET" />
...
Set up broadcast receiver and P2P administrator
Using WI-FI P2P technology, you need to monitor the broadcast intent, which will notify the program of certain events. So you need to add IntentFilter in the program and set it to listen to the following behavior:
WIFI \ _P2P \ _STATE \ _CHANGED \ _ACTION
Monitor if Wi-Fi P2P is available
WIFI \ _P2P \ _PEERS \ _CHANGED \ _ACTION
Monitor WI-FI P2P list changes
WIFI \ _P2P \ _CONNECTION \ _CHANGED \ _ACTION
Monitor Wi-Fi P2P connection status
WIFI \ _P2P \ _THIS \ _DEVICE \ _CHANGED \ _ACTION
Monitoring device configuration changes
private final IntentFilter intentFilter = new IntentFilter ();
...
@Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.main);
// Indicates a change in the Wi-Fi P2P status.
intentFilter.addAction (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
// Indicates a change in the list of available peers.
intentFilter.addAction (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
// Indicates the state of Wi-Fi P2P connectivity has changed.
intentFilter.addAction (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
// Indicates this device ‘s details have changed.
intentFilter.addAction (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
...
}
At the end of the onCreate () method, you need to get an instance of WifiP2pManager, and then call its initialize () method. This method will return a WifiP2pManager.Channel object, which is used to establish connection between the application layer and the Wi-Fi P2P framework.
@Override
Channel mChannel;
public void onCreate (Bundle savedInstanceState) {
....
mManager = (WifiP2pManager) getSystemService (Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize (this, getMainLooper (), null);
}
Next, create a new BroadcastReceiver class, which is used to monitor the Wi-Fi P2P state changes of the system. In the onReceive () method, you need to add some basic judgment conditions to deal with each P2P state and process:
@Override
public void onReceive (Context context, Intent intent) {
String action = intent.getAction ();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals (action)) {
// Determine if Wifi P2P mode is enabled or not, alert
// the Activity.
int state = intent.getIntExtra (WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
activity.setIsWifiP2pEnabled (true);
} else {
activity.setIsWifiP2pEnabled (false);
}
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals (action)) {
// The peer list has changed! We should probably do something about
// that.
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals (action)) {
// Connection state changed! We should probably do something about
// that.
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals (action)) {
DeviceListFragment fragment = (DeviceListFragment) activity.getFragmentManager ()
.findFragmentById (R.id.frag_list);
fragment.updateThisDevice ((WifiP2pDevice) intent.getParcelableExtra (
WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
}
}
Finally, add the broadcast receiver and intent filter to the context, and need to log off the broadcast receiver when the Activity is paused. The best place to put this code is the onResume () method and onPause () method.
/ ** register the BroadcastReceiver with the intent values to be matched * /
@Override
public void onResume () {
super.onResume ();
receiver = new WiFiDirectBroadcastReceiver (mManager, mChannel, this);
registerReceiver (receiver, intentFilter);
}
@Override
public void onPause () {
super.onPause ();
unregisterReceiver (receiver);
}
Initialize endpoint search
If you want to use Wi-Fi P2P to search for nearby devices, you need to call the discoverPeers () method. This method requires the following parameters:
The WifiP2pManager.Channel object obtained when initializing the P2P administrator.
The implementation of WifiP2pManager.ActionListener, which is used to monitor the success of the search.
mManager.discoverPeers (mChannel, new WifiP2pManager.ActionListener () {
@Override
public void onSuccess () {
// Code for when the discovery initiation is successful goes here.
// No services have actually been discovered yet, so this method
// can often be left blank. Code for peer discovery goes in the
// onReceive method, detailed below.
}
@Override
public void onFailure (int reasonCode) {
// Code for when the discovery initiation fails goes here.
// Alert the user that something went wrong.
}
});
Keep in mind that here only the endpoint search is initialized. The discoverPeers () method will return immediately after starting the search process. If the endpoint search process is successfully initialized, the system will automatically call the callback method set during initialization. In addition, the endpoint search function will remain active until the connection is initialized or the P2P group establishes a connection.
Get endpoint list
Next, you need to obtain and process the endpoint list. First, you need to implement the WifiP2pManager.PeerListListener interface, which provides the endpoint information found by WI-FI P2P. The following code demonstrates this process:
private List peers = new ArrayList ();
...
private PeerListListener peerListListener = new PeerListListener () {
@Override
public void onPeersAvailable (WifiP2pDeviceList peerList) {
// Out with the old, in with the new.
peers.clear ();
peers.addAll (peerList.getDeviceList ());
// If an AdapterView is backed by this data, notify it
// of the change. For instance, if you have a ListView of available
// peers, trigger an update.
((WiFiPeerListAdapter) getListAdapter ()). NotifyDataSetChanged ();
if (peers.size () == 0) {
Log.d (WiFiDirectActivity.TAG, "No devices found");
return;
}
}
}
Now you need to modify the onReceive () method of the broadcast receiver and call the requestPeers () method when you receive the WIFI \ _P2P \ _STATE \ _CHANGED \ _ACTION behavior. Before that, you need to pass the instance of the listener to the broadcast receiver. The conventional way is to pass this listener in the construction method of the broadcast receiver. ,
public void onReceive (Context context, Intent intent) {
...
else 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, peerListListener);
}
Log.d (WiFiDirectActivity.TAG, "P2P peers changed");
} ...
}
Now, the behavior of WIFI \ _P2P \ _STATE \ _CHANGED \ _ACTION will trigger the update of the endpoint list.
Connect to endpoint
In order to connect to the endpoint, you need to create a new WifiP2pConfig object, and then copy the data in WifiP2pDevice into this object. WifiP2pDevice represents the device to be connected. Then call the connect () method.
@Override
public void connect () {
// Picking the first device found on the network.
WifiP2pDevice device = peers.get (0);
WifiP2pConfig config = new WifiP2pConfig ();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
mManager.connect (mChannel, config, new ActionListener () {
@Override
public void onSuccess () {
// WiFiDirectBroadcastReceiver will notify us. Ignore for now.
}
@Override
public void onFailure (int reason) {
Toast.makeText (WiFiDirectActivity.this, "Connect failed. Retry.",
Toast.LENGTH_SHORT) .show ();
}
});
}
The WifiP2pManager.ActionListener interface in the above code will only be called if the initialization is successful or failed. If you want to monitor the connection status change, you need to implement the WifiP2pManager.ConnectionInfoListener interface, its method onConnectionInfoAvailable () will be called back when the connection status changes. In the case where multiple devices are connected to one device (such as multi-player interactive games or chat-like apps), one of the devices will be designated as the "group owner".
@Override
public void onConnectionInfoAvailable (final WifiP2pInfo info) {
// InetAddress from WifiP2pInfo struct.
InetAddress groupOwnerAddress = info.groupOwnerAddress.getHostAddress ());
// After the group negotiation, we can determine the group owner.
if (info.groupFormed && info.isGroupOwner) {
// Do whatever tasks are specific to the group owner.
// One common case is creating a server thread and accepting
// incoming connections.
} else if (info.groupFormed) {
// The other device acts as the client. In this case,
// you ‘ll want to create a client thread that connects to the group
// owner.
}
}
Now go back to the onReceive () method of the broadcast receiver and modify the part that listens to WIFI \ _P2P \ _CONNECTION \ _CHANGED \ _ACTION. When this intention is received, call the requestConnectionInfo () method. This is an asynchronous method, so the result will be called back via the parameter: connection information listener.
...
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals (action)) {
if (mManager == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra (WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected ()) {
// We are connected with the other device, request connection
// info to find group owner IP
mManager.requestConnectionInfo (mChannel, connectionListener);
}
...
Android Official Development Document Training Series Course Chinese Version: Connect a wireless device to create a P2P connection through WIFI