从ConnectivityManager NetworkCapabilities同步获取Wifi SSID

8
目前,获取Android设备连接的Wifi网络的SSID最流行的方法是使用WifiManager的getConnectionInfo()方法。然而,该方法在API级别31中已被弃用。根据文档,我们应该使用ConnectivityManager的getNetworkCapabilities()方法来获取Wifi信息。不幸的是,文档中指出:
“这将删除NetworkCapabilities#getTransportInfo()中嵌入的TransportInfo中的任何位置敏感数据。一些传输信息实例(如WifiInfo)包含位置敏感信息。检索此位置敏感信息(受应用程序位置权限限制)将被系统记录。要在TransportInfo中包含任何位置敏感数据,请使用带有NetworkCallback#FLAG_INCLUDE_LOCATION_INFO标志的NetworkCallback。”
现在似乎唯一的方法是通过注册一个带有FLAG_INCLUDE_LOCATION_INFO标志的NetworkCallback,并等待回调被调用来获取SSID。这并不是旧方法的合适替代品,因为旧方法是同步的,可以按需调用。目前是否有任何方法可以在不使用已弃用的getConnectionInfo()方法的情况下同步获取Wifi SSID?
3个回答

3
我也遇到了这个问题。您需要同步查询吗?您是否可以将最后一次来自onCapabilitiesChanged()的SSID输出存储在livedata对象中?这篇文章是一个非常好的资源,可以帮助您实现这一点。不幸的是,我的代码仍然在使用传输信息时为SSID信息提供null。您可以分享您的代码吗?

我想重构我的代码以实现异步,但这会引入额外的延迟和复杂性。我需要在应用程序启动时立即检查SSID,因此我基本上会注册侦听器,等待第一个响应,然后立即注销。 - kevdliu
关于获取SSID,我认为在实例化NetworkCallback对象时,需要向其构造函数传递FLAG_INCLUDE_LOCATION_INFO参数。 - kevdliu
我认为这对于Android版本31是正确的,但会在版本30上破坏代码。 - 958

1
在API 31或以上版本(撰写时),您需要具备以下两个权限:
  1. android.permission.ACCESS_FINE_LOCATION 保护级别危险
  2. android.permission.ACCESS_WIFI_STATE 保护级别普通
然后,您可以按照以下方式同步获取SSID:
ConnectivityManager cm =
      context.getSystemService(ConnectivityManager.class);
Network n = cm.getActiveNetwork();
NetworkCapabilities netCaps = cm.getNetworkCapabilities(n);
WifiInfo info = (WifiInfo) netCaps.getTransportInfo();
String ssid = wifiInfo.getSSID();

这是唯一同步获取结果的方法。请注意,即使您按照其他答案和官方文档建议使用异步回调,仍然需要列出的权限才能访问SSID。


对我来说不起作用(我使用的是Android 14)。我在清单中拥有所有必需的权限,我也正确地请求了它们,并且它们都被授予了。但是同步方式仍然返回"<unknown ssid>"。看起来唯一的选择是异步选项。 - undefined

0

尝试下面的示例,在线程内调用getWiFiSSID()方法

public static String getWiFiSSID() {
 final NetworkRequest request =
      new NetworkRequest.Builder()
      .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
      .build();
 List<String> ssidList = new ArrayList<>();
 final ConnectivityManager connectivityManager =
      context.getSystemService(ConnectivityManager.class);
 final NetworkCallback networkCallback = new NetworkCallback(ConnectivityManager.NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) {
      ...
      @Override
      void onAvailable(Network network) {}

      @Override
      void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
          WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
          ssidList.add(wifiInfo.getSSID());
          connectivityManager.unregisterNetworkCallback(this);
      }
      // etc.
 };
 connectivityManager.requestNetwork(request, networkCallback); // For request
 connectivityManager.registerNetworkCallback(request, networkCallback); // For listen
 int timer = 5000;
 while (ssidList.size() == 0 && timer >= 0) {
   try {
      Thread.sleep(250);
      timer -= 250;
   } catch (InterruptedException e) {
      break;
   }
 }
 if(ssidList.size()>0) {
   return ssidList.get(0);
 }else {
   connectivityManager.unregisterNetworkCallback(networkCallback);
   return null;
 }
}

这个解决方案适用于Android 13,但在Android 8设备上崩溃了。 - Vijayadhas Chandrasekaran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接