I am connecting different devices with wifi hotspot AP programatically in my android app, How can i detect the clients being connected and disconnected and to the wifi hotspot AP Programmatically ? Is there any callback event in Android API to give information regarding the connection or disconnection events of individual devices ? Thanks in advance.
-
You are only able to control the device which is running your application using `BroadcastReceiver` targeting to `Connectivity`. – Stan Feb 03 '14 at 09:47
-
Duplicate of http://stackoverflow.com/questions/19879708/android-wifi-hotspot-client-connection-events. But that question don't have an answer. – leesei Feb 04 '14 at 08:01
5 Answers
Unfortunately there is no public API to give information about this... But you can read /proc/net/arp file and see the clients connected to your Access Point.
/proc/net/arp file have 6 fields: IP address, HW type, Flags, HW address, Mask and Device
The problem is when a client get disconnected, because it doesn't disappear from the file. A solution may be to do ping to every client and wait for response, but for me this isn't a good solution because some clients don't respond to ping. If you like this solution check this project on GitHub --> https://github.com/nickrussler/Android-Wifi-Hotspot-Manager-Class/tree/master/src/com/whitebyte
What i have did is: read /proc/net/arp and check the FLAGS field, when the value is 0x2 the station is connected and 0x0 is disconnected, but to refresh this field I need to clear ARP cache from time to time, and i did it with this command: ip neigh flush all
I hope i helped you

- 151
- 1
- 3
-
Have you implemented code to clear ARP and did you able to get updated status of each clients connected? If YES, please share me the code... Thanks in advance. – SomeswarReddy Jun 03 '15 at 12:54
-
1As of now (on API 23, 24 and 26) the flag for each listed device is `0x2` even if the device is disconnected – Cliff Burton Jan 06 '18 at 19:49
-
Hey As mentioned about even after I disconnect on reading /proc/net/arp it shows disconnected device so as it is mentioned in answer that we have to pass command ip neigh flush all.How can I do this?And is rooting necessary to issue this command then? – Nimish Bansal Mar 10 '18 at 19:46
-
-
is it possible to write this arp file? (Like disconnect the devices that are connect in to hotspot) – Dinith Feb 12 '20 at 04:28
This method works for me but this is detecting only version 4.0 and above; it is not able to find the devices with version 2.2 or 2.3 which is connected with hotspot.
public void getClientList() {
int macCount = 0;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("/proc/net/arp"));
String line;
while ((line = br.readLine()) != null) {
String[] splitted = line.split(" +");
if (splitted != null ) {
// Basic sanity check
String mac = splitted[3];
System.out.println("Mac : Outside If "+ mac );
if (mac.matches("..:..:..:..:..:..")) {
macCount++;
/* ClientList.add("Client(" + macCount + ")");
IpAddr.add(splitted[0]);
HWAddr.add(splitted[3]);
Device.add(splitted[5]);*/
System.out.println("Mac : "+ mac + " IP Address : "+splitted[0] );
System.out.println("Mac_Count " + macCount + " MAC_ADDRESS "+ mac);
Toast.makeText(
getApplicationContext(),
"Mac_Count " + macCount + " MAC_ADDRESS "
+ mac, Toast.LENGTH_SHORT).show();
}
/* for (int i = 0; i < splitted.length; i++)
System.out.println("Addressssssss "+ splitted[i]);*/
}
}
} catch(Exception e) {
}
}
-
Hi Prabhu, is there a way to get client device details which are not only connected to the hotspot but also also available within range? – Parag Kadam Apr 17 '17 at 15:02
-
Android 10 restricts the permission for access to the /proc/net directory, so some of the solutions above are no longer feasible, but the 'ip' command is still available
private fun getARPIps(): List<Pair<String, String>> {
val result = mutableListOf<Pair<String, String>>()
try {
// val args = listOf("ip", "neigh")
// val cmd = ProcessBuilder(args)
// val process: Process = cmd.start()
val process = Runtime.getRuntime().exec("ip neigh")
val reader = BufferedReader(InputStreamReader(process.inputStream))
reader.forEachLine {
if (!it.contains("FAILED")) {
val split = it.split("\\s+".toRegex())
if (split.size > 4 && split[0].matches(Regex("([0-9]{1,3}\\.){3}[0-9]{1,3}"))) {
result.add(Pair(split[0], split[4]))
}
}
}
val errReader = BufferedReader(InputStreamReader(process.errorStream))
errReader.forEachLine {
Log.e(TAG, it)
// post the error message to server
}
reader.close()
errReader.close()
process.destroy()
} catch (e: Exception){
e.printStackTrace()
// post the error message to server
}
return result
}

- 169
- 1
- 7
-
-
-
i can run it using exec command(which you have commented out) but not using process. i am using Redmi Note 8 Pro – MbPCM Jan 14 '20 at 09:04
-
"ip neigh" doesn't seem to work anymore starting from Android 11 (and your apps targets SDK 30 or higher). – Dieter27 Feb 11 '21 at 15:05
@SuppressWarnings("ConstantConditions")
public static String getClientMacByIP(String ip)
{
String res = "";
if (ip == null)
return res;
String flushCmd = "sh ip -s -s neigh flush all";
Runtime runtime = Runtime.getRuntime();
try
{
runtime.exec(flushCmd,null,new File("/proc/net"));
}
BufferedReader br;
try
{
br = new BufferedReader(new FileReader("/proc/net/arp"));
String line;
while ((line = br.readLine()) != null)
{
String[] sp = line.split(" +");
if (sp.length >= 4 && ip.equals(sp[0]))
{Assistance.Log(sp[0]+sp[2]+sp[3],ALERT_STATES.ALERT_STATE_LOG);
String mac = sp[3];
if (mac.matches("..:..:..:..:..:..") && sp[2].equals("0x2"))
{
res = mac;
break;
}
}
}
br.close();
}
catch (Exception e)
{}
return res;
}
//--------------------------------------------------------
@SuppressWarnings("ConstantConditions")
public static String getClientIPByMac(String mac)
{
String res = "";
if (mac == null)
return res;
String flushCmd = "sh ip -s -s neigh flush all";
Runtime runtime = Runtime.getRuntime();
try
{
runtime.exec(flushCmd,null,new File("/proc/net"));
}
BufferedReader br;
try
{
br = new BufferedReader(new FileReader("/proc/net/arp"));
String line;
while ((line = br.readLine()) != null)
{
String[] sp = line.split(" +");
if (sp.length >= 4 && mac.equals(sp[3]))
{
String ip = sp[0];
if (ip.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}") && sp[2].equals("0x2"))
{
res = ip;
break;
}
}
}
br.close();
}
catch (Exception e)
{}
return res;
}

- 3,068
- 27
- 28
you can use BroadcastReciever "android.net.wifi.WIFI_HOTSPOT_CLIENTS_CHANGED" to detect client connection. In your AndroidManifest:
<receiver
android:name=".WiFiConnectionReciever"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.net.wifi.WIFI_HOTSPOT_CLIENTS_CHANGED" />
</intent-filter>
</receiver>
and in your activity
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction("android.net.wifi.WIFI_HOTSPOT_CLIENTS_CHANGED");
rcv = new WiFiConnectionReciever();
registerReceiver(rcv,
mIntentFilter);

- 1
-
-
-
these are just two way to register broadcast receivers, should have added "or" between them while writing – MbPCM Jan 07 '20 at 15:16