7

As of Android 4.1, your device can detect if it's connected to a mobile hotspot (given that the mobile hotspot is also running Android 4.1 or higher). Also, you have the option to flag networks as mobile hotspots (under Settings / Data Usage / Overflow menu / Mobile Hotspots).

But how do I detect this as a -user- I meant developer? It's not stored in the WifiConfiguration, so where is it?

Some context: I want to build a simple tool for Android that checks if you are connected to a network that you or Android has flagged as a mobile hotspot. If so, it will check if no other (non-hotspot) networks are available. If so, it should connect to these other networks since those should be much faster and have no data cap. Why? Because my phones and tablets connect to (mobile) hotspots quite often, even when a better network is available.

Here is some pseudo code of what I'm looking for:

// Check if android has detected mobile hotspot
WifiManager wifiMgr = getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiMgr .getConnectionInfo();
boolean isMobileHotspot = wifiInfo.isMobileHotspot;

UPDATE Jul 3rd 2014

Okay so Matiash' answer is good but ConnectivityManager.isActiveNetworkMetered() will only return the value for the current network. I do need that, so it helped me along, but it bring me to the next part in my tool/app:

IF the device is connected to a mobile hotspot (or a 'metered network' as Android calls it) I want to check if any of the nearby access points is a better option. So I need to know whether any of the known AP's (WifiManager.getConfiguredNetworks()) is also flagged as such before I connect to it...

I have a List<ScanResult> and a List<WifiConfiguration>, looks like neither of them has this information.

Which bring me back to my initial question: Is there a way to retrieve the Mobile Hotspots (as configured by Android and/or user) under Data Usage? And this time I mean ALL of them.

UPDATE Jul 7th 2014

I've posted a feature request in the AOSP Issue Tracker for access (readonly) to the NetworkPolicyManager. Plz vote on it here: https://code.google.com/p/android/issues/detail?id=73206&thanks=73206&ts=1404719243

REJH
  • 3,273
  • 5
  • 31
  • 56
  • You'd better ask a separate question for the "it bring me to the next part in my tool/app". I'd probably cache the known networks that have recently been connected to and maintain an `isMetered` flag in the cache. – Jeroen Wiert Pluimers Jul 06 '14 at 06:11
  • 1
    Yup that's what i'm doing now. Will post an update and/or open a new question. Thnx : – REJH Jul 06 '14 at 18:51
  • any updates? did you find a solution? – Shreyans Mar 21 '16 at 02:18
  • Nope. I monitor the network and keep track of metered networks myself, android doesn't allow for this to be detected – REJH Mar 21 '16 at 06:14

3 Answers3

6

You can access this information by calling ConnectivityManager.isActiveNetworkMetered().

This will return whether the active connection is a hotspot (as defined in Data Usage -> Mobile Hotspots).

About the second part, I'm sorry but I don't think that's possible. The flag is not public, and even if you get the object that could be used to retrieve it (android.net.NetworkPolicyManager) by reflection:

Object npm = Class.forName("android.net.NetworkPolicyManager").getDeclaredMethod("from", Context.class).invoke(null, this);
Object policies = npm.getClass().getDeclaredMethod("getNetworkPolicies").invoke(npm);

calling getNetworkPolicies() requires the MANAGE_NETWORK_POLICY permission, which cannot be obtained by non-system apps, because it has a "signature" protection level.

I hope to be proved incorrect though. :) Maybe looking at the source code of the Android activity that manages this information (https://github.com/android/platform_packages_apps_settings/blob/master/src/com/android/settings/net/DataUsageMeteredSettings.java), in particular the buildWifiPref() method, will provide some clue.

matiash
  • 54,791
  • 16
  • 125
  • 154
  • Ah. But now the next question: Is there a way to find out if a known network (the list you get from WifiManager.getConfiguredNetworks()) is a 'metered network' before I connect to it? – REJH Jul 03 '14 at 13:11
  • Edited the OP and removed the 'answered' flag because this is not the complete answer I'm looking for. See OP for details. – REJH Jul 03 '14 at 13:17
  • 1
    @REJH Edited answer. Hope you find a solution, but I'm afraid it's not possible. Sorry – matiash Jul 03 '14 at 15:42
  • Thanks. Well, you're answer did help me at least detect if the CURRENT network is metered. I've been digging through the AOSP Settings app to see how they do it and it looks like they use android.net.NetworkTemplate and .NetworkTemplateEditor. Sadly, an 'import android.NetworkTemplate' doesn't work. I guess it's not part of the stuff that is accessible by the SDK? I'm thinking to try java reflection (or whatever it's called). Anyway. Will update this post if I find something useful. EDIT: Lol just saw you were pointing me in that direction. Thnx again – REJH Jul 03 '14 at 16:23
0

I do not know if what you want is possible but you can check whether your device is connected to a network by checking the ip. You can use the tool below to see if you has ip, and shalt know if he is connected to a network or not.

public static Boolean check_connection(final Context _context)
  {
      boolean connected;

      ConnectivityManager conectivtyManager = (ConnectivityManager) _context
              .getSystemService(Context.CONNECTIVITY_SERVICE);

      if (conectivtyManager.getActiveNetworkInfo() != null
              && conectivtyManager.getActiveNetworkInfo().isAvailable()
              && conectivtyManager.getActiveNetworkInfo().isConnected())
      {
          connected = true;

      } else
      {
          connected = false;
      }
      return connected;
  }
Ludger
  • 362
  • 3
  • 16
  • Thanks but that was not what I was looking for. matiash got what I wanted. Thanks anyways :D – REJH Jul 01 '14 at 18:16
0
    //Check if hotspot tethering is enabled
    try {
        ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        boolean isMobileData = connectivityManager.isActiveNetworkMetered();

        if(isMobileData) {
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface networkInterface : interfaces) {
                if (networkInterface.getName().equals("ap0")) {
                    //Tethering is enabled
                    SendHotspotEnabledHandler sendHotspotEnabledHandler = new SendHotspotEnabledHandler(new WeakReference<Context>(SendInstalledAppsService.this));
                    sendHotspotEnabledHandler.execute();
                    break;
                }
            }
        }

    } catch (SocketException e) {
    }