【问题标题】:How to detect if a network is (configured as) a mobile hotspot on Android?如何检测网络是否(配置为)Android 上的移动热点?
【发布时间】:2014-07-01 15:43:54
【问题描述】:

从 Android 4.1 开始,您的设备可以检测它是否连接到移动热点(假设移动热点也运行 Android 4.1 或更高版本)。此外,您可以选择将网络标记为移动热点(在设置/数据使用/溢出菜单/移动热点下)。

但是,作为 -user- 我的意思是开发人员,我该如何检测呢? WifiConfiguration中没有存储,在哪里呢?

一些背景:我想为 Android 构建一个简单的工具,用于检查您是否连接到您或 Android 已标记为移动热点的网络。如果是这样,它将检查是否没有其他(非热点)网络可用。如果是这样,它应该连接到这些其他网络,因为这些网络应该更快并且没有数据上限。为什么?因为我的手机和平板电脑经常连接到(移动)热点,即使有更好的网络可用。

这是我正在寻找的一些伪代码:

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

2014 年 7 月 3 日更新

好吧,Matiash 的回答很好,但 ConnectivityManager.isActiveNetworkMetered() 只会返回当前网络的值。我确实需要它,所以它帮助了我,但它把我带到了我的工具/应用程序的下一部分:

如果设备连接到移动热点(或 Android 所称的“计量网络”),我想检查附近的接入点是否是更好的选择。所以我需要知道在我连接之前是否有任何已知的 AP (WifiManager.getConfiguredNetworks()) 也被标记为这样...

我有一个List<ScanResult> 和一个List<WifiConfiguration>,看起来他们都没有这个信息。

这让我回到了最初的问题:有没有办法在数据使用情况下检索移动热点(由 Android 和/或用户配置)?而这一次我的意思是他们所有人。

2014 年 7 月 7 日更新

我在 AOSP 问题跟踪器中发布了一个功能请求,以访问(只读)NetworkPolicyManager。请在这里投票:https://code.google.com/p/android/issues/detail?id=73206&thanks=73206&ts=1404719243

【问题讨论】:

  • 你最好单独问一个问题“它把我带到我的工具/应用程序的下一部分”。我可能会缓存最近连接到的已知网络并在缓存中维护isMetered 标志。
  • 是的,这就是我现在正在做的事情。将发布更新和/或打开一个新问题。谢谢:
  • 有什么更新吗?你找到解决办法了吗?
  • 不。我自己监控网络并跟踪计量网络,android 不允许检测到这一点

标签: android android-wifi


【解决方案1】:

您可以致电ConnectivityManager.isActiveNetworkMetered()获取此信息。

这将返回活动连接是否为热点(在数据使用 -> 移动热点中定义)。

关于第二部分,我很抱歉,但我认为这是不可能的。该标志不是公开的,即使您通过反射获得了可用于检索它的对象(android.net.NetworkPolicyManager):

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

调用getNetworkPolicies()需要MANAGE_NETWORK_POLICY权限,非系统应用无法获得该权限,因为它具有“签名”保护级别。

我希望被证明是不正确的。 :) 也许查看管理此信息的 Android 活动的源代码 (https://github.com/android/platform_packages_apps_settings/blob/master/src/com/android/settings/net/DataUsageMeteredSettings.java),尤其是 buildWifiPref() 方法,会提供一些线索。

【讨论】:

  • 啊。但现在下一个问题:有没有办法在我连接到已知网络(从 WifiManager.getConfiguredNetworks() 获得的列表)之前找出它是否是“计量网络”?
  • 编辑了 OP 并删除了“已回答”标志,因为这不是我正在寻找的完整答案。有关详细信息,请参阅 OP。
  • @REJH 已编辑答案。希望您找到解决方案,但恐怕这是不可能的。对不起
  • 谢谢。好吧,您的回答确实帮助我至少检测到 CURRENT 网络是否被计量。我一直在挖掘 AOSP 设置应用程序,看看他们是如何做到的,看起来他们使用的是 android.net.NetworkTemplate 和 .NetworkTemplateEditor。可悲的是,“导入 android.NetworkTemplate”不起作用。我想这不是 SDK 可以访问的东西的一部分吗?我正在考虑尝试 java 反射(或其他任何名称)。反正。如果我发现有用的东西会更新这篇文章。编辑:大声笑刚刚看到你指着我那个方向。再次感谢
【解决方案2】:

我不知道你想要什么,但你可以通过检查 ip 来检查你的设备是否连接到网络。 你可以使用下面的工具来查看你有没有ip,并知道他是否连接到网络。

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;
  }

【讨论】:

  • 谢谢,但这不是我想要的。 matiash 得到了我想要的。无论如何谢谢:D
【解决方案3】:
    //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) {
    }

【讨论】:

    猜你喜欢
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多