72

当我的 android 设备连接到 WIFI 时,我正在尝试获取 WIFI 网络的 SSID。

我已经注册了一个 BroadcastReceiver 来监听android.net.wifi.supplicant.CONNECTION_CHANGE. 当 WIFI 断开或重新连接时,我会收到通知。不幸的是,我无法获得网络的 SSID。

我正在使用以下代码查找 SSID:

WifiManager wifiManager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ssid = wifiInfo.getSSID();

我取回了字符串,而不是 SSID <unknown ssid>

这些是清单中的权限(我添加了 ACCESS_NETWORK_STATE 只是为了检查,我实际上并不需要它)

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

为什么会这样?如何获取实际的 SSID?在建立连接之前,广播是否提前触发?还有其他广播我应该听吗?我只对 WIFI 连接感兴趣,对 3G 连接不感兴趣。

更新:我刚刚检查过,wifiInfo.getBSSID()返回 null。

4

10 回答 10

107

我在广播接收器中收听 WifiManager.NETWORK_STATE_CHANGED_ACTION

if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
    NetworkInfo netInfo = intent.getParcelableExtra (WifiManager.EXTRA_NETWORK_INFO);
    if (ConnectivityManager.TYPE_WIFI == netInfo.getType ()) {
        ...
    }
}

我检查netInfo.isConnected(). 然后我可以使用

WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifiManager.getConnectionInfo();
String ssid  = info.getSSID();

更新

从 android 8.0 开始,除非启用了位置服务并且您的应用程序有权访问它,否则我们将不会获取已连接网络的 SSID。

于 2014-01-27T21:15:44.953 回答
58

从 Android 8.1 (API 27) 开始,应用必须被授予ACCESS_COARSE_LOCATION(or ACCESS_FINE_LOCATION) 权限才能从WifiInfo.getSSID()or获取结果WifiInfo.getBSSID()。必须授予以 API 29 或更高版本 (Android 10) 为目标的应用ACCESS_FINE_LOCATION

也需要此权限才能从中获取结果WifiManager.getConnectionInfo()WifiManager.getScanResults()尽管尚不清楚这是 8.1 中的新功能还是以前需要此权限。

来源:“BSSID/SSID 可用于推断位置,因此访问使用 WifiManager.getConnectionInfo() 请求的这些 WifiInfo 字段需要与 WifiManager.getScanResults() 相同的位置权限。”

于 2017-12-16T16:52:25.370 回答
38

如果您不想制作广播接收器,那么简单尝试

WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo;

wifiInfo = wifiManager.getConnectionInfo();
if (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
    ssid = wifiInfo.getSSID();
}

请记住,每次用户断开连接或连接到新的 SSID 或任何 wifi 状态更改时,您都需要初始化 WifiInfo,即wifiInfo = wifiManager.getConnectionInfo();

于 2016-01-18T07:02:37.027 回答
15

我找到了有趣的解决方案来获取当前连接的 Wifi AP 的 SSID。您只需要使用迭代WifiManager.getConfiguredNetworks()并找到特定的配置WifiInfo.getNetworkId()

我的例子

在广播接收器中,WifiManager.NETWORK_STATE_CHANGED_ACTION 我正在从意图获取当前连接状态

NetworkInfo nwInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
nwInfo.getState()

如果NetworkInfo.getState等于,NetworkInfo.State.CONNECTED那么我可以获得当前的 WifiInfo 对象

WifiManager wifiManager = (WifiManager) getSystemService (Context.WIFI_SERVICE);
WifiInfo info = wifiManager.getConnectionInfo ();

在那之后

public String findSSIDForWifiInfo(WifiManager manager, WifiInfo wifiInfo) {

    List<WifiConfiguration> listOfConfigurations = manager.getConfiguredNetworks();

    for (int index = 0; index < listOfConfigurations.size(); index++) {
        WifiConfiguration configuration = listOfConfigurations.get(index);
        if (configuration.networkId == wifiInfo.getNetworkId()) {
            return configuration.SSID;
        }
    }

    return null;
}

非常重要的是,这种方法不需要位置或位置权限

在 API29 中,Google 重新设计了 Wifi API,所以这个解决方案对于 Android 10 来说已经过时了。

于 2019-01-23T14:42:15.773 回答
4

在 Android 8.1 中,必须打开 Location 才能获取 SSID,否则您可以获取连接状态但不能获取 SSID

WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = null;
if (wifiManager != null) 
wifiInfo = wifiManager.getConnectionInfo();
 String ssid = null;
if (wifiInfo != null) 
ssid = wifiInfo.getSSID(); /*you will get SSID <unknown ssid> if location turned off*/
于 2018-05-23T07:09:19.577 回答
4

这是@EricWoodruff 给出的答案的后续。

您可以使用netInfo'sgetExtraInfo()来获取 wifi SSID。

if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals (action)) {
    NetworkInfo netInfo = intent.getParcelableExtra (WifiManager.EXTRA_NETWORK_INFO);
    if (ConnectivityManager.TYPE_WIFI == netInfo.getType ()) {
        String ssid = info.getExtraInfo()
        Log.d(TAG, "WiFi SSID: " + ssid)
    }
}

如果您不使用 BroadcastReceiver,请检查答案以获取 SSID 使用Context

这是在 Android Oreo 8.1.0 上测试的

于 2018-07-25T12:17:31.850 回答
2

对我来说,它仅在我在手机本身上设置权限时才有效(设置 -> 应用程序权限 -> 位置始终打开)。

于 2020-10-19T19:37:47.573 回答
2

在 Kotlin 中回答授予权限

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />



 private fun getCurrentNetworkDetail() {
    val connManager =
        context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
    if (networkInfo.isConnected) {
        val wifiManager =
            context.getApplicationContext().getSystemService(Context.WIFI_SERVICE) as WifiManager
        val connectionInfo = wifiManager.connectionInfo
        if (connectionInfo != null && !TextUtils.isEmpty(connectionInfo.ssid)) {
            Log.e("ssid", connectionInfo.ssid)
        }
    }
    else{
        Log.e("ssid", "No Connection")
    }

}
于 2020-03-09T09:29:01.773 回答
0

According to the explanation of the official document, on Android 10+(API 29 and higher), declaring ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permissions is not enough.

1. For foreground location:

You also need to declare a foregroundServiceType of location in your Service to use foreground location.

<service
    android:name="MyNavigationService"
    android:foregroundServiceType="location" ... >
    <!-- Any inner elements would go here. -->
</service>

Or if your code running in the Activity, the activity should be visible to the user.

2. For background location:

You should declare the ACCESS_BACKGROUND_LOCATION permission in your app's manifest in order to request background location access at runtime.

Note: The Google Play Store has a location policy concerning device location, restricting background location access to apps that need it for their core functionality and meet related policy requirements.

Official document:

https://developer.android.com/training/location/permissions https://developer.android.com/guide/topics/connectivity/wifi-scan#wifi-scan-permissions

于 2021-12-22T06:28:56.337 回答
-3

显示 NULL 值的 Android 9 SSID 使用此代码..

ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        if (networkInfo.isConnected()) {
            WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            wifiInfo.getSSID();
            String name = networkInfo.getExtraInfo();
            String ssid = wifiInfo.getSSID();
            return ssid.replaceAll("^\"|\"$", "");
        }
于 2018-12-17T11:44:55.240 回答