activeNetworkInfo.type is deprecated in API level 28
UPDATE
The connectivityManager.activeNetworkInfo
is also deprecated in API level 29
Now we need to use ConnectivityManager.NetworkCallback API
or ConnectivityManager#getNetworkCapabilities or ConnectivityManager#getLinkProperties
SAMPLE CODE USING
ConnectivityManager#getNetworkCapabilities
private fun isInternetAvailable(context: Context): Boolean {
var result = false
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val networkCapabilities = connectivityManager.activeNetwork ?: return false
val actNw =
connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
result = when {
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
else -> false
}
} else {
connectivityManager.run {
connectivityManager.activeNetworkInfo?.run {
result = when (type) {
ConnectivityManager.TYPE_WIFI -> true
ConnectivityManager.TYPE_MOBILE -> true
ConnectivityManager.TYPE_ETHERNET -> true
else -> false
}
}
}
}
return result
}
OLD ANSWER
Yes getType()
is deprecated in API level 28
Now we need to use Callers should switch to checking NetworkCapabilities.hasTransport(int)
Also getAllNetworkInfo()
is deprecated in API level 29
Now we need to use getAllNetworks()
instead of getNetworkInfo(android.net.Network)
.
getNetworkInfo()
- Returns connection status information about a particular Network.
getAllNetworks()
- Returns an array of all Network currently tracked by the framework.
SAMPLE CODE
fun isWiFiConnected(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
val network = connectivityManager.activeNetwork
val capabilities = connectivityManager.getNetworkCapabilities(network)
capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
} else {
connectivityManager.activeNetworkInfo.type == ConnectivityManager.TYPE_WIFI
}
}
COMPLETE CODE
@Suppress("DEPRECATION")
fun isInternetAvailable(context: Context): Boolean {
var result = false
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
cm?.run {
cm.getNetworkCapabilities(cm.activeNetwork)?.run {
result = when {
hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
else -> false
}
}
}
} else {
cm?.run {
cm.activeNetworkInfo?.run {
if (type == ConnectivityManager.TYPE_WIFI) {
result = true
} else if (type == ConnectivityManager.TYPE_MOBILE) {
result = true
}
}
}
}
return result
}
Slightly simpler version (minSdkVersion 23+)
fun isNetworkAvailable(context: Context) =
(context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).run {
getNetworkCapabilities(activeNetwork)?.run {
hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|| hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|| hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
} ?: false
}
I just wanted to know, if the device is connected to the internet, regardless of the type of connection:
@Suppress("DEPRECATION")
fun isOnline(context: Context?): Boolean {
var connected = false
@Suppress("LiftReturnOrAssignment")
context?.let {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val networkCapabilities = cm.activeNetwork ?: return false
val actNw = cm.getNetworkCapabilities(networkCapabilities) ?: return false
connected = actNw.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
} else {
val netInfo = cm.activeNetworkInfo
connected = netInfo?.isConnectedOrConnecting == true
}
}
return connected
}
Here is my solution for SDK 29: A class called NetworkWatcher
which observes the changes of the network. It offers primitive variables such as isWifiOn
and the option to observe network changes over time via Flow and LiveData.
@ExperimentalCoroutinesApi
class NetworkWatcher
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
private constructor(
application: Application
) {
private val connectivityManager =
application.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE)
as ConnectivityManager
// general availability of Internet over any type
var isOnline = false
get() {
updateFields()
return field
}
var isOverWifi = false
get() {
updateFields()
return field
}
var isOverCellular = false
get() {
updateFields()
return field
}
var isOverEthernet = false
get() {
updateFields()
return field
}
companion object {
@Volatile
private var INSTANCE: NetworkWatcher? = null
fun getInstance(application: Application): NetworkWatcher {
synchronized(this) {
if (INSTANCE == null) {
INSTANCE = NetworkWatcher(application)
}
return INSTANCE!!
}
}
}
@Suppress("DEPRECATION")
private fun updateFields() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val networkAvailability =
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
if (networkAvailability != null &&
networkAvailability.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
networkAvailability.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
) {
//has network
isOnline = true
// wifi
isOverWifi =
networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
// cellular
isOverCellular =
networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
// ethernet
isOverEthernet =
networkAvailability.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
} else {
isOnline = false
isOverWifi = false
isOverCellular = false
isOverEthernet = false
}
} else {
val info = connectivityManager.activeNetworkInfo
if (info != null && info.isConnected) {
isOnline = true
val wifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
isOverWifi = wifi != null && wifi.isConnected
val cellular = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
isOverCellular = cellular != null && cellular.isConnected
val ethernet = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET)
isOverEthernet = ethernet != null && ethernet.isConnected
} else {
isOnline = false
isOverWifi = false
isOverCellular = false
isOverEthernet = false
}
}
}
fun watchNetwork(): Flow<Boolean> = watchWifi()
.combine(watchCellular()) { wifi, cellular -> wifi || cellular }
.combine(watchEthernet()) { wifiAndCellular, ethernet -> wifiAndCellular || ethernet }
fun watchNetworkAsLiveData(): LiveData<Boolean> = watchNetwork().asLiveData()
fun watchWifi(): Flow<Boolean> = callbackFlowForType(NetworkCapabilities.TRANSPORT_WIFI)
fun watchWifiAsLiveData() = watchWifi().asLiveData()
fun watchCellular(): Flow<Boolean> = callbackFlowForType(NetworkCapabilities.TRANSPORT_CELLULAR)
fun watchCellularAsLiveData() = watchCellular().asLiveData()
fun watchEthernet(): Flow<Boolean> = callbackFlowForType(NetworkCapabilities.TRANSPORT_ETHERNET)
fun watchEthernetAsLiveData() = watchEthernet().asLiveData()
private fun callbackFlowForType(@IntRange(from = 0, to = 7) type: Int) = callbackFlow {
offer(false)
val networkRequest = NetworkRequest.Builder()
.addTransportType(type)
.build()
val callback = object : ConnectivityManager.NetworkCallback() {
override fun onLost(network: Network?) {
offer(false)
}
override fun onUnavailable() {
offer(false)
}
override fun onLosing(network: Network?, maxMsToLive: Int) {
// do nothing
}
override fun onAvailable(network: Network?) {
offer(true)
}
}
connectivityManager.registerNetworkCallback(networkRequest, callback)
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
}
}
For instance, you could subscribe to updates about the network state of the phone in your Application such as:
GlobalScope.launch {
NetworkWatcher.getInstance(this@MyApplication).watchNetwork().collect { connected ->
Log.d("TAG", "Network In App: $connected")
}
}
Or to answer your question, simply read the Wifi value such as:
if (NetworkWatcher.getInstance(this@BaseApp).isOverWifi) {
// do stuff
}
Side note: Rather than using getInstance()
all the time, I use a DI framework such as Koin to inject the NetworkWatcher where I need it.