12

I am building an application which can transfer data between a mobile and a Wi-Fi device... The mobile has got the AP enabled (through code) and another device connects to this specific network... How can I detect through code to see the details of the devices connected to the network(AP)?** Is there a solution for this?

I have seen an application called Wifi Hot spot in HTC Desire that does this functionality of showing the IP addresses of the devices connected to the network. How can this be achieved?

Check out Review: Sprint Mobile Hotspot on HTC EVO 4G.

It shows an application that can actually display the connected users. How can we do that programmatically? Is there an API for that?

For creating an access point:

private void createWifiAccessPoint() {
    if (wifiManager.isWifiEnabled())
    {
        wifiManager.setWifiEnabled(false);
    }
    Method[] wmMethods = wifiManager.getClass().getDeclaredMethods(); //Get all declared methods in WifiManager class
    boolean methodFound = false;

    for (Method method: wmMethods){
        if (method.getName().equals("setWifiApEnabled")){
            methodFound = true;
            WifiConfiguration netConfig = new WifiConfiguration();
            netConfig.SSID = "\""+ssid+"\"";
            netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            //netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            //netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            //netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            //netConfig.preSharedKey = password;
            //netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            //netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            //netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            //netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

            try {
                boolean apstatus = (Boolean) method.invoke(wifiManager, netConfig,true);
                //statusView.setText("Creating a Wi-Fi Network \""+netConfig.SSID+"\"");
                for (Method isWifiApEnabledmethod: wmMethods)
                {
                    if (isWifiApEnabledmethod.getName().equals("isWifiApEnabled")){
                        while (!(Boolean)isWifiApEnabledmethod.invoke(wifiManager)){
                        };
                        for (Method method1: wmMethods){
                            if(method1.getName().equals("getWifiApState")){
                                int apstate;
                                apstate = (Integer)method1.invoke(wifiManager);
                                //                      netConfig = (WifiConfiguration)method1.invoke(wifi);
                                //statusView.append("\nSSID:"+netConfig.SSID+"\nPassword:"+netConfig.preSharedKey+"\n");
                            }
                        }
                    }
                }

                if(apstatus)
                {
                    System.out.println("SUCCESSdddd");
                    //statusView.append("\nAccess Point Created!");
                    //finish();
                    //Intent searchSensorsIntent = new Intent(this,SearchSensors.class);
                    //startActivity(searchSensorsIntent);
                }
                else
                {
                    System.out.println("FAILED");

                    //statusView.append("\nAccess Point Creation failed!");
                }
            }
            catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
            catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
    if (!methodFound){
        //statusView.setText("Your phone's API does not contain setWifiApEnabled method to configure an access point");
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Arun Abraham
  • 4,011
  • 14
  • 54
  • 75
  • Thats not right, the WiFi Hotspot on the HTC Desire doesn't show you which devices are connected to the same WiFi-Network than the Desire but it opens a own WiFi-Hotspot (and so a WiFi-Network) and acts as a own access point. That is why it can display the connected devices, because it is its own network. – theomega Mar 09 '11 at 14:28
  • Ok....i am programmatically able to establish a Wifi-Access point... Now will be able to detect the devices connected to this network ? – Arun Abraham Mar 09 '11 at 14:38
  • Where do you essablish the Access-Point? On an Non-Android-Device? Then yes. On Android it will get quite difficult without root-access to get the data in a normal app. – theomega Mar 09 '11 at 14:50
  • I am establishing the access point on an android device... – Arun Abraham Mar 09 '11 at 14:59
  • 2
    Your code works fine, but on my htc desire when I turn on hot spot programatically - DHCP disables..... WHY??????? – timonvlad Mar 30 '12 at 07:34
  • @Arun Abraham I have the same requirement of getting the details of devices connected to my network using Wi-Fi Teethring. Have you got any solution for it? I can't go for ARP or RARP because I have no info about the devices which are connected to my teethring network. – Sagar Trehan Feb 04 '15 at 07:01

3 Answers3

8

You could read the /proc/net/arp file to read all the ARP entries. See the example in the blog post Android: Howto find the hardware MAC address of a remote host. In the ARP table, search for all the hosts that belong to your Wi-Fi network based on the IP address.

Here is example code, which counts the number of hosts connected to the AP. This code assumes that one ARP entry is for the phone connected to the network and the remaining ones are from hosts connected to the AP.

private int countNumMac()
{
    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 && splitted.length >= 4) {
                // Basic sanity check
                String mac = splitted[3];
                if (mac.matches("..:..:..:..:..:..")) {
                    macCount++;
                }
            }
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    finally {
        try {
            br.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    if (macCount == 0)
        return 0;
    else
        return macCount-1; //One MAC address entry will be for the host.
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Paul
  • 99
  • 1
  • 1
    how did you know that you had to access this file ??/proc/net/arp... any source for this?? – Arun Abraham Mar 16 '11 at 13:49
  • 1
    /proc is a standard linux file system which gives a lot of information about the kernel. You can find details about /proc/net at http://linuxdevcenter.com/pub/a/linux/2000/11/16/LinuxAdmin.html . Google search of /proc will give you a ton on info. – Paul Mar 17 '11 at 05:55
  • 2
    This is incorrect as the ARP tables don't necessarily refresh when a device disconnects. One say say, that you could simply ping all the devices in the table to see which IPs are active but it is quite possible that a device is firewalled to not respond to ICMP request and your ping would fail. This solution, although a working one, isn't robust and accurate. – Mridang Agarwalla Jul 02 '13 at 10:12
  • So,... is there any other alternative solutions @MridangAgarwalla for checking the clients still connected or not? – gumuruh Aug 08 '14 at 17:55
  • What if I not know MAC or IP how can I get details of devices connected with my Wi-Fi Teethring network? Please help – Sagar Trehan Feb 04 '15 at 07:04
5

You could ping the device if you know its host-name or its IP address.

    Runtime runtime = Runtime.getRuntime();
    Process proc = runtime.exec("ping -c 1   " + hostname);
    proc.waitFor();

You could do an IP address scan, trying every IP address on the network for a response using a ping like above or trying to connect using TCP or UDP.

If you know the MAC address, you could use the ARP table.

If you got some own software running on the devices, you could send out UDP packets on every device and listen for them on your Android device. See Sending and receiving UDP broadcast packets in Android on how to do this.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
theomega
  • 31,591
  • 21
  • 89
  • 127
  • is'nt there any other value to check for the devices connected to the network ? So that i could iterate through and find the required one... – Arun Abraham Mar 08 '11 at 15:13
  • IN my requirement, i have a wifi controller which will connect to the device(take for example one mobile in which i have the app installed, i have AP enabled and from the other device i have connected to this network)... now how do i find out in the device(app installed), the devices connected to the network.. sending UDP packets would require me to install another app on the other device..anyway..how do i listen for UDP packets? – Arun Abraham Mar 08 '11 at 15:26
  • 1
    Please remember that if that the firewall/router drops ICMP packets then the ping wouldn't work. You could also try to simplify the above solution by sending broadcast pings. – Mridang Agarwalla Aug 11 '14 at 06:23
3

You can use accesspoint:

WifiApControl apControl = WifiApControl.getInstance(context);

// These are cached and may no longer be connected, see
// WifiApControl.getReachableClients(int, ReachableClientListener)
List<WifiApControl.Client> clients = apControl.getClients()
mvdan
  • 476
  • 6
  • 8