How to get the client device details which is connected to wifi hotspot?
Asked Answered
A

5

11

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.

Amphithecium answered 3/2, 2014 at 8:48 Comment(2)
You are only able to control the device which is running your application using BroadcastReceiver targeting to Connectivity.Lowrance
Duplicate of #19880208. But that question don't have an answer.Mindszenty
O
13

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

Okwu answered 29/1, 2015 at 15:44 Comment(5)
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.Multifid
As of now (on API 23, 24 and 26) the flag for each listed device is 0x2 even if the device is disconnectedWireworm
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?Azores
Anyone got the answer for getting only the connected clients?Azores
is it possible to write this arp file? (Like disconnect the devices that are connect in to hotspot)Elainaelaine
A
12

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) {

    }               
}
Amphithecium answered 4/2, 2014 at 9:44 Comment(2)
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?Untwist
Is there a way to disconnect them?Elainaelaine
D
4

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
}
Dissuasive answered 10/12, 2019 at 17:12 Comment(4)
Permission Denied, Error 13Mateya
What phone do you use, can you run "ip neigh" in the shell?Dissuasive
i can run it using exec command(which you have commented out) but not using process. i am using Redmi Note 8 ProMateya
"ip neigh" doesn't seem to work anymore starting from Android 11 (and your apps targets SDK 30 or higher).Orpiment
C
1
@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;
}
Camarata answered 10/11, 2016 at 12:40 Comment(0)
P
-1

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);
Peppi answered 25/9, 2015 at 7:52 Comment(3)
where is the WiFiConnectionReciever class dudeVerruca
WIFI_HOTSPOT_CLIENTS_CHANGED is not longer available to subscribeAscension
these are just two way to register broadcast receivers, should have added "or" between them while writingMateya

© 2022 - 2024 — McMap. All rights reserved.