WifiInfo returning null
Asked Answered
M

1

7

I have been working on this for a few days after following this guide online. I am using target API 30 (building on a device using Android 11). Trying to get the Wifi SSID using networkCapabilities this keeps returning null whereas the depreciated wifiManager.connectionInfo.ssid returns the correct SSID. Any ideas what I am doing wrong? I know this will need to change for API 31 to include the FLAG_INCLUDE_LOCATION_INFO but I believe this should be working for API 30. Any ideas?

import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.util.Log
import androidx.lifecycle.LiveData

private const val TAG = "NetworkStatus"

enum class NetworkStatus {
    UNAVAILABLE,
    CONNECTED_TO_XXXX,
    CONNECTED_TO_OTHER,
    CONNECTION_LOST
}

 class NetworkStatusHelper(private val context: Context) : LiveData<Pair<NetworkStatus, String>>() {

private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback
var connectivityManager: ConnectivityManager =
    context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

val wifiManager =
    context.getSystemService(Context.WIFI_SERVICE) as WifiManager

private fun getConnectivityManagerCallback() = object : ConnectivityManager.NetworkCallback() {

    override fun onUnavailable() {
        super.onUnavailable()
        announceStatus(Pair(NetworkStatus.UNAVAILABLE, ""))
    }

    override fun onAvailable(network: Network) {
        super.onAvailable(network)

    }

    override fun onCapabilitiesChanged(
        network: Network,
        networkCapabilities: NetworkCapabilities
    ) {
        super.onCapabilitiesChanged(network, networkCapabilities)

        Log.d(TAG, "onCapabilitiesChanged: transport info = ${connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)?.transportInfo}")
        try {
            val wifiInfo = networkCapabilities.transportInfo as WifiInfo
            
            Log.d(TAG, "onCapabilitiesChanged: wifi SSID ${wifiInfo}")

            if (wifiInfo.ssid.contains("XXXX-")) {
                announceStatus(Pair(NetworkStatus.CONNECTED_TO_XXXX, wifiInfo.ssid))
            } else {
                announceStatus(Pair(NetworkStatus.CONNECTED_TO_OTHER, wifiInfo.ssid))
            }

        }
        catch (e: Exception) {
            Log.d(TAG, "onCapabilitiesChanged: exception = $e")
        }

        try {
            Log.d(TAG, "onCapabilitiesChanged: ${wifiManager.connectionInfo.ssid}")
        } catch (e: Exception) {
            Log.d(TAG, "onAvailable: exception = $e")
        }

    }

    override fun onLost(network: Network) {
        super.onLost(network)
        announceStatus(Pair(NetworkStatus.CONNECTION_LOST, ""))
    }

}

fun announceStatus(networkResposePair: Pair<NetworkStatus, String>) {
    postValue(networkResposePair)
}

override fun onActive() {
    super.onActive()
    connectivityManagerCallback = getConnectivityManagerCallback()
    val networkRequest = NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
        .build()
    connectivityManager.registerNetworkCallback(networkRequest, connectivityManagerCallback)
}

override fun onInactive() {
    super.onInactive()
    connectivityManager.unregisterNetworkCallback(connectivityManagerCallback)
}
}

Permissions in Gradle:

    <uses-permission android:name="android.permission.INTERNET"/>
    <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_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

SDK versions

    compileSdkVersion 31
    buildToolsVersion "30.0.3"
    minSdkVersion 30
    targetSdkVersion 31

Mcmasters answered 23/2, 2022 at 8:32 Comment(0)
P
-1

When creating your NetworkCallback object, try pass to the constructor FLAG_INCLUDE_LOCATION_INFO like so:

object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) { /* your code */ }

This way we are telling that we want to receive some sensitive data about the network, but it will work only with API level 31 and higher sadly.

More info here

Polygamous answered 2/3, 2022 at 8:57 Comment(2)
Thanks, my intention if I ever plan to move up to Android 12 is include requires=api version. This statement seems to return null "val wifiInfo = networkCapabilities.transportInfo as WifiInfo" maybe I am doing something wrong here. I have also just seen that I need to include a foreground service type so will attempt that.Mcmasters
@Mcmasters For API level less than 31 you try to use WifiManager from systemService of your app context. And from this manager retrieve WifiInfo. For that your would need to add build versions check of the device.Polygamous

© 2022 - 2024 — McMap. All rights reserved.