10

I'm developing an app that uses wifi to broadcast UDP messages between all the mobiles that are in the same network that have my app.

I managed to send/receive packets from many cellphones having an external AP, that's my router.

But given the case that there's no AP, I want users to be able to use their phone's Wifi Hotspot feature so they can still use my aplication. So one of the cellphones would be the wifi hotspot, and all the others would connect to that.

I require users to connect to a wifi by they own. Either to an external AP or to the said hotspot. Then when my application starts, it checks whether the phone is connected to a wifi network, calling the WifiManager.isWifiEnabled() and NetworkInfo.isConnected().

The problem is that if I call these functions in the cellphone that's using hotspot, the function isConnected() will return false. And I can't get the broadcast address using WifiManager.getDhcpInfo(). The other phones that are connected to the hotspot they do work perfectly. But the hotspot cellphone can't send any broadcast, since WifiManager is disabled.

So, my question would be "Is there any way to check if a cellphone is currently being a wifi hotspot? And if so, is there any way I can get its broadcast address?"

animuson
  • 53,861
  • 28
  • 137
  • 147
olivarra1
  • 3,269
  • 3
  • 23
  • 34
  • 1
    you should be able to get what you need by parsing result of shell command `ip link` and maybe `ip route` – mvp Dec 29 '12 at 10:09

1 Answers1

15

First you can check what is your IP address :

public InetAddress getIpAddress() {
  InetAddress inetAddress = null;
  InetAddress myAddr = null;

  try {
    for (Enumeration<NetworkInterface> networkInterface = NetworkInterface
      .getNetworkInterfaces(); networkInterface.hasMoreElements();) {

      NetworkInterface singleInterface = networkInterface.nextElement();

      for (Enumeration<InetAddress> IpAddresses = singleInterface.getInetAddresses(); IpAddresses
        .hasMoreElements();) {
        inetAddress = IpAddresses.nextElement();

        if (!inetAddress.isLoopbackAddress() && (singleInterface.getDisplayName()
            .contains("wlan0") ||
            singleInterface.getDisplayName().contains("eth0") ||
            singleInterface.getDisplayName().contains("ap0"))) {

          myAddr = inetAddress;
        }
      }
    }

  } catch (SocketException ex) {
    Log.e(TAG, ex.toString());
  }
  return myAddr;
}

and I used this IP to get Broadcast this way:

public InetAddress getBroadcast(InetAddress inetAddr) {

    NetworkInterface temp;
    InetAddress iAddr = null;
    try {
        temp = NetworkInterface.getByInetAddress(inetAddr);
        List<InterfaceAddress> addresses = temp.getInterfaceAddresses();

        for (InterfaceAddress inetAddress: addresses)

            iAddr = inetAddress.getBroadcast();
        Log.d(TAG, "iAddr=" + iAddr);
        return iAddr;

    } catch (SocketException e) {

        e.printStackTrace();
        Log.d(TAG, "getBroadcast" + e.getMessage());
    }
    return null;
}

It can be done of course in one method, but in my implementation separating it into two method was useful.

To identify if Wifi Tether is on you can use this code:

WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
Method[] wmMethods = wifi.getClass().getDeclaredMethods();
for (Method method: wmMethods) {
    if (method.getName().equals("isWifiApEnabled")) {

        try {
            if ((Boolean) method.invoke(wifi)) {
                isInetConnOn = true;
                iNetMode = 2;

            } else {
                Log.d(TAG, "WifiTether off");
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

If client devices needs to know if server device is mobile Hotspot, specific IP address can be used. As far as I know, all Tethering devices have the same address 192.168.43.1 It is the same on Android 2.3 and on 4.+, Checked on many phones and tablets. Of course it is not best solution but it is fast. In my application client devices checks (sends packet to this address) and my server devices response in predefined way like "yesIamInTheterModeIamYourServer".

jox
  • 2,218
  • 22
  • 32
MP23
  • 1,763
  • 20
  • 25
  • This will probably be the answer, once I check it, I will accept it. It's really interesting, but I don't need to know if the server is a Hotspot, since there's no server in my application (all the devices send and receive UDP broadcasts). Thank you very much. – olivarra1 Dec 29 '12 at 17:04
  • There's a small problem with that code. This checks for all interfaces, and if it's not the loopback, then it sets the address to that loopback. But I tried it in my device, and it has 3 interfaces, the loopback (127.0.0.1) that gets discarted correctly, the Hotspot (192.168.1.1) and the "ISP" (10.52.121.XXX). Then it doesn't get the Hotspot wifi, but the last interface there is (in my case, it was the ISP one). Checking if the IP is a private one should be enough anyway, but is there any other way of fixing that? – olivarra1 Jan 01 '13 at 10:23
  • I have updated my answer you can check that now there is one more condition, where name of interace is checked. Names differs on different phone but usually it is eth0 or wlan0, but it should be checked if there are some other names used for wifi interface – MP23 Jan 01 '13 at 14:57
  • yes, there is another name. In my case it is the ap0. – Gaucho Oct 13 '14 at 14:55
  • 1
    FYI, Samsung devices use a different address, I believe it is 192.168.68.1 – Jared Nov 26 '14 at 21:30
  • Works perfect in Nexus 5(5.0.1), Moto G(4.4.3) and Samsung Core(4.1.2). Phones that are not tethering still work with the code you provided (getting broadcast address). – Rudolf Real Dec 28 '14 at 01:14