Wi-Fi Direct Integration in Mobile Applications
Wi-Fi Direct allows two devices to connect directly without an access point. This is a powerful tool for transferring large files, collaboration, or gaming sessions—but one of the most complex wireless protocols to implement on mobile platforms. iOS doesn't support Wi-Fi Direct in public API at all. Android supports it, but with caveats.
Android: Wi-Fi P2P API
WifiP2pManager is the main class. It works through Broadcast Receiver with intents WIFI_P2P_STATE_CHANGED_ACTION, WIFI_P2P_PEERS_CHANGED_ACTION, WIFI_P2P_CONNECTION_CHANGED_ACTION.
Initialization
val manager = getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManager
val channel = manager.initialize(this, mainLooper, null)
Permissions (Android 13+)
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Android 13+ -->
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
ACCESS_FINE_LOCATION is needed for peer discovery on Android < 13. On Android 13+—NEARBY_WIFI_DEVICES, but without usesPermissionFlags="neverForLocation" the system still requires geolocation. This raises user questions ("why does our file manager need location?").
Discovery and Connection
manager.discoverPeers(channel, object : WifiP2pManager.ActionListener {
override fun onSuccess() { /* scanning started */ }
override fun onFailure(reason: Int) {
// reason: ERROR=0, P2P_UNSUPPORTED=1, BUSY=2
}
})
// In BroadcastReceiver on WIFI_P2P_PEERS_CHANGED_ACTION:
manager.requestPeers(channel) { peers ->
val deviceList = peers.deviceList
// show list to user
}
// Connection to selected device:
val config = WifiP2pConfig().apply {
deviceAddress = selectedDevice.deviceAddress
wps.setup = WpsInfo.PBC
}
manager.connect(channel, config, object : WifiP2pManager.ActionListener {
override fun onSuccess() { /* request sent, wait for WIFI_P2P_CONNECTION_CHANGED_ACTION */ }
override fun onFailure(reason: Int) { }
})
Data Transfer
After connection is established, one device becomes Group Owner (GO). GO has fixed IP 192.168.49.1, client gets IP from DHCP.
// On WIFI_P2P_CONNECTION_CHANGED_ACTION:
manager.requestConnectionInfo(channel) { info ->
if (info.groupFormed) {
val groupOwnerAddress = info.groupOwnerAddress.hostAddress
if (info.isGroupOwner) {
// start ServerSocket
startServer()
} else {
// connect to groupOwnerAddress:PORT
startClient(groupOwnerAddress)
}
}
}
After this—regular Socket / ServerSocket. Wi-Fi Direct doesn't provide high-level file transfer protocol, only TCP/UDP connection.
Issues That Always Occur
Connection stability. Wi-Fi Direct connections are unstable on some chipsets (Qualcomm vs MediaTek behave differently). Reconnect on break is mandatory.
Only one P2P connection at a time. Device can't be connected to Wi-Fi AP and participate in Wi-Fi Direct group simultaneously on most devices. On Android 10+, this partially changed with WifiP2pConfig.Builder.setNetworkName(), but not everywhere.
iOS. No native Wi-Fi Direct. For cross-platform peer-to-peer, consider MultipeerConnectivity (iOS-only, via Wi-Fi/Bluetooth), or Nearby Connections API from Google (Android + iOS via single SDK).
Cross-Platform Alternatives
| Technology | iOS | Android | Range | Speed |
|---|---|---|---|---|
| Wi-Fi Direct | ❌ | ✅ | ~200m | up to 250 Mbps |
| MultipeerConnectivity | ✅ | ❌ | ~100m | up to 100 Mbps |
| Nearby Connections API | ✅ | ✅ | ~100m | up to 50 Mbps |
| BLE | ✅ | ✅ | ~50m | 1-3 Mbps |
Wi-Fi Direct integration (Android) timeline: 3-5 days for basic implementation, 1-2 weeks with reliable reconnection and file transfer. Cost is calculated individually.







