Reputation: 1977
I want to use the Connectivity manager which provide the method activeNetworkInfo.type for checking the type of network in Android. This method was deprecated in API level 28. so what is the solution to check network type in API 28. my code is :
/**
* Check Wi Fi connectivity
*/
fun isWiFiConnected(context: Context): Boolean {
val connManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return connManager.activeNetworkInfo.type == ConnectivityManager.TYPE_WIFI
}
My Gradle is like :
compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
}
Upvotes: 97
Views: 56832
Reputation: 19
In kotlin
i use this:
private fun isConnected(): Boolean {
val connectivityManager = applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = connectivityManager.activeNetwork
val capabilities = connectivityManager.getNetworkCapabilities(network)
return (capabilities != null &&
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) &&
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) &&
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) &&
capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET))
}
Upvotes: 0
Reputation: 4631
Due to Android Developers >Docs >Guides this way can be useful
Java
boolean enabled;
ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
assert connectivityManager != null;
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
ConnectivityManager cm = getSystemService(ConnectivityManager.class);
if ((info == null || !cm.getActiveNetworkInfo().isConnectedOrConnecting() || !info.isAvailable())) {
enabled = false;
} else enabled = true;
for this getActiveNetworkInfo()
you need permission ACCESS_NETWORK_STATE
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Upvotes: 0
Reputation: 1
this is what I do. In the first part of "if statement" I check whether the user is making use of the new verison of android, in second part I make use of AciveNetworkInfo for old Android SDK.
fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
//return depending on the version in the last version of API
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val network = connectivityManager.activeNetwork ?: return false
val activeNetwork =
connectivityManager.getNetworkCapabilities(network) ?: return false
return when {
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) ->true
else -> false
}
} else {
//for the old version of android sdk we use follow code
val networkInfo = connectivityManager.activeNetworkInfo
return networkInfo != null && networkInfo.isConnectedOrConnecting
}
}
Upvotes: 0
Reputation: 6723
In Kotlin you can check the Android version and as per the version check the connectivity manager.
fun Context.isInternetAvailable(): Boolean {
val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
val cap = cm.getNetworkCapabilities(cm.activeNetwork) ?: return false
return cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
val networks = cm.allNetworks
for (n in networks) {
val nInfo = cm.getNetworkInfo(n)
if (nInfo != null && nInfo.isConnected) return true
}
}
else -> {
val networks = cm.allNetworkInfo
for (nInfo in networks) {
if (nInfo != null && nInfo.isConnected) return true
}
}
}
return false
}
Call the extension function in your activity
if (applicationContext.isInternetAvailable()) { }
Upvotes: 1
Reputation: 1234
For versions >= Build.VERSION_CODES.M
:
private fun isConnected(context: Context): Boolean {
val manager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
val capabilities = manager?.getNetworkCapabilities(manager.activeNetwork) ?: return false
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
}
Upvotes: 0
Reputation: 11457
Complete solution Create these class in a package lets say connectivity
import android.content.Context import android.content.Context.CONNECTIVITY_SERVICE import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
import android.net.NetworkInfo
import android.os.Build
import androidx.annotation.RequiresApi
interface ConnectivityProvider {
interface ConnectivityStateListener {
fun onStateChange(state: NetworkState)
}
fun addListener(listener: ConnectivityStateListener)
fun removeListener(listener: ConnectivityStateListener)
fun getNetworkState(): NetworkState
@Suppress("MemberVisibilityCanBePrivate", "CanBeParameter")
sealed class NetworkState {
object NotConnectedState : NetworkState()
sealed class ConnectedState(val hasInternet: Boolean) : NetworkState() {
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
data class Connected(val capabilities: NetworkCapabilities) : ConnectedState(
capabilities.hasCapability(NET_CAPABILITY_INTERNET)
)
@Suppress("DEPRECATION")
data class ConnectedLegacy(val networkInfo: NetworkInfo) : ConnectedState(
networkInfo.isConnectedOrConnecting
)
}
}
companion object {
fun createProvider(context: Context): ConnectivityProvider {
val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ConnectivityProviderImpl(cm)
} else {
ConnectivityProviderLegacyImpl(context, cm)
}
}
}
}
abstract class ConnectivityProviderBaseImpl
abstract class ConnectivityProviderBaseImpl : ConnectivityProvider {
private val handler = Handler(Looper.getMainLooper())
private val listeners = mutableSetOf<ConnectivityStateListener>()
private var subscribed = false
override fun addListener(listener: ConnectivityStateListener) {
listeners.add(listener)
listener.onStateChange(getNetworkState()) // propagate an initial state
verifySubscription()
}
override fun removeListener(listener: ConnectivityStateListener) {
listeners.remove(listener)
verifySubscription()
}
private fun verifySubscription() {
if (!subscribed && listeners.isNotEmpty()) {
subscribe()
subscribed = true
} else if (subscribed && listeners.isEmpty()) {
unsubscribe()
subscribed = false
}
}
protected fun dispatchChange(state: NetworkState) {
handler.post {
for (listener in listeners) {
listener.onStateChange(state)
}
}
}
protected abstract fun subscribe()
protected abstract fun unsubscribe()
}
class ConnectivityProviderImpl
@RequiresApi(Build.VERSION_CODES.N)
class ConnectivityProviderImpl(private val cm: ConnectivityManager) :
ConnectivityProviderBaseImpl() {
private val networkCallback = ConnectivityCallback()
override fun subscribe() {
cm.registerDefaultNetworkCallback(networkCallback)
}
override fun unsubscribe() {
cm.unregisterNetworkCallback(networkCallback)
}
override fun getNetworkState(): NetworkState {
val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
return if (capabilities != null) {
Connected(capabilities)
} else {
NotConnectedState
}
}
private inner class ConnectivityCallback : NetworkCallback() {
override fun onCapabilitiesChanged(network: Network, capabilities: NetworkCapabilities) {
dispatchChange(Connected(capabilities))
}
override fun onLost(network: Network) {
dispatchChange(NotConnectedState)
}
}
}
@Suppress("DEPRECATION")
class ConnectivityProviderLegacyImpl(
private val context: Context,
private val cm: ConnectivityManager
) : ConnectivityProviderBaseImpl() {
private val receiver = ConnectivityReceiver()
override fun subscribe() {
context.registerReceiver(receiver, IntentFilter(CONNECTIVITY_ACTION))
}
override fun unsubscribe() {
context.unregisterReceiver(receiver)
}
override fun getNetworkState(): NetworkState {
val activeNetworkInfo = cm.activeNetworkInfo
return if (activeNetworkInfo != null) {
ConnectedLegacy(activeNetworkInfo)
} else {
NotConnectedState
}
}
private inner class ConnectivityReceiver : BroadcastReceiver() {
override fun onReceive(c: Context, intent: Intent) {
// on some devices ConnectivityManager.getActiveNetworkInfo() does not provide the correct network state
// https://issuetracker.google.com/issues/37137911
val networkInfo = cm.activeNetworkInfo
val fallbackNetworkInfo: NetworkInfo? = intent.getParcelableExtra(EXTRA_NETWORK_INFO)
// a set of dirty workarounds
val state: NetworkState =
if (networkInfo?.isConnectedOrConnecting == true) {
ConnectedLegacy(networkInfo)
} else if (networkInfo != null && fallbackNetworkInfo != null &&
networkInfo.isConnectedOrConnecting != fallbackNetworkInfo.isConnectedOrConnecting
) {
ConnectedLegacy(fallbackNetworkInfo)
} else {
val state = networkInfo ?: fallbackNetworkInfo
if (state != null) ConnectedLegacy(state) else NotConnectedState
}
dispatchChange(state)
}
}
}
Usage:- Home Activity
class HomeActivity : BaseActivity(), ConnectivityProvider.ConnectivityStateListener {
val provider: ConnectivityProvider by lazy { ConnectivityProvider.createProvider(this@HomeActivity) }
override fun onStart() {
super.onStart()
provider.addListener(this)
}
override fun onStop() {
super.onStop()
provider.removeListener(this)
}
override fun onStateChange(state: ConnectivityProvider.NetworkState) {
val hasInternet = state.hasInternet()
}
companion object {
fun ConnectivityProvider.NetworkState.hasInternet(): Boolean {
return (this as? ConnectivityProvider.NetworkState.ConnectedState)?.hasInternet == true
}
}
on button click or any api call
if(provider.getNetworkState().hasInternet()){
// do work
}
}
if you want to use check internet in fragments of home activities
if ((activity as HomeActivity).provider.getNetworkState().hasInternet()) {
// api call
}
Upvotes: 0
Reputation: 163
Here is Kotlin implementation for two methods old/new api:
@Suppress("DEPRECATION")
fun isConnectedOld(context: Context): Boolean {
val connManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
val networkInfo = connManager.activeNetworkInfo
return networkInfo.isConnected
}
@RequiresApi(Build.VERSION_CODES.M)
fun isConnectedNewApi(context: Context): Boolean {
val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
return capabilities?.hasCapability(NET_CAPABILITY_INTERNET) == true
}
and common method:
fun isConnected(context: Context): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
isConnectedNewApi(context)
} else{
isConnectedOld(context)
}
}
Upvotes: 7
Reputation: 25
I hope this would work for you! this code work in api 21 onwards
// create a new class and add following
public class CheckNetwork {
public static boolean isNetworkConnected;
private Context context;
public CheckNetwork(Context context) {
this.context = context;
}
public boolean isOnline(){
isNetworkConnected = false;
ConnectivityManager connectivityMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network[] allNetworks = connectivityMgr.getAllNetworks(); // added in API 21 (Lollipop)
for (Network network : allNetworks) {
NetworkCapabilities networkCapabilities = connectivityMgr.getNetworkCapabilities(network);
if (networkCapabilities != null) {
if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|| networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|| networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET))
isNetworkConnected = true;
}
}
return isNetworkConnected;
}
}
// in MainActivity
CheckNetwork myNetwork = new CheckNetwork(this);
//in OnCreateMethod
myNetwork.isOnline();
if (myNetwork.isNetworkConnected){
Toast.makeText(this, "Please check your Internet Connection", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "Your Internet Connction is Ok", Toast.LENGTH_SHORT).show();
}
Upvotes: 2
Reputation: 1971
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
}
Upvotes: 15
Reputation: 69689
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
}
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()
getAllNetworks()
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
}
Upvotes: 184
Reputation: 7468
I am using this Kotlin func to check internet connection:
Be careful about version checking (Version >= M)
private fun isInternetConnected():Boolean{
val connectivityManager = this.getSystemService(android.content.Context.CONNECTIVITY_SERVICE)
as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val networkCapabilities = connectivityManager.activeNetwork ?: return false
val activeNetwork = connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
return when {
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) ||
activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
else -> false
}
}
else {
return connectivityManager.activeNetworkInfo != null &&
connectivityManager.activeNetworkInfo!!.isConnectedOrConnecting
}
}
Upvotes: 4
Reputation: 6222
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
}
Upvotes: 9
Reputation: 1277
Java Code:
public static boolean isConnectingToInternet(Context mContext) {
if (mContext == null) return false;
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final Network network = connectivityManager.getActiveNetwork();
if (network != null) {
final NetworkCapabilities nc = connectivityManager.getNetworkCapabilities(network);
return (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
}
} else {
NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();
for (NetworkInfo tempNetworkInfo : networkInfos) {
if (tempNetworkInfo.isConnected()) {
return true;
}
}
}
}
return false;
}
Upvotes: 5
Reputation: 5770
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.
Upvotes: 12
Reputation: 1966
Recently I had to write a small function for checking the network connectivity inside my singular WebView. I've also noticed that the API much evolved and especially when Kotlin came in so to find valid reference took some minutes.
Here is my small NetworkConnectivityManager
class with a simple function for checking network availability.
import android.content.Context
import android.content.Context.CONNECTIVITY_SERVICE
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
class NetworkConnectivityManager(context: Context) {
private val connectivityManager =
context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
@Suppress("DEPRECATION")
fun isNetworkAvailable(): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val nc = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
nc != null
&& nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
&& nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}
val networkInfo = connectivityManager.activeNetworkInfo
return networkInfo != null && networkInfo.isConnected
}
}
Upvotes: 0
Reputation: 1054
If you use min API level 23, you can use this shortened Kotlin version.
fun isNetworkAvailable(context: Context): Boolean {
(context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).apply {
return getNetworkCapabilities(activeNetwork)?.run {
when {
hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
else -> false
}
} ?: false
}
}
Upvotes: 0
Reputation: 1168
I have adapted Nilesh Rathod's answer for my needs:
enum class ConnectivityMode {
NONE,
WIFI,
MOBILE,
OTHER,
MAYBE
}
var connectivityMode = ConnectivityMode.NONE
private fun checkConnectivity(context: Context): ConnectivityMode {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
cm?.run {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
getNetworkCapabilities(activeNetwork)?.run {
return when {
hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> ConnectivityMode.WIFI
hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> ConnectivityMode.MOBILE
hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> ConnectivityMode.OTHER
hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> ConnectivityMode.MAYBE
else -> ConnectivityMode.NONE
}
}
} else {
@Suppress("DEPRECATION")
activeNetworkInfo?.run {
return when (type) {
ConnectivityManager.TYPE_WIFI -> ConnectivityMode.WIFI
ConnectivityManager.TYPE_MOBILE -> ConnectivityMode.MOBILE
ConnectivityManager.TYPE_ETHERNET -> ConnectivityMode.OTHER
ConnectivityManager.TYPE_BLUETOOTH -> ConnectivityMode.MAYBE
else -> ConnectivityMode.NONE
}
}
}
}
return ConnectivityMode.NONE
}
Then I check the connection with okhttp:
fun updateData(manual: Boolean, windowContext: Context) = runBlocking {
connectivityMode = checkConnectivity(MyApplication.context)
if (connectivityMode != ConnectivityMode.NONE) {
val conn : Boolean = GlobalScope.async {
var retval = false
try {
val request = Request.Builder().url(WORK_URL).build()
val response = client.newCall(request).execute()
Log.i(TAG, "code = ${response?.code}")
if (response?.code == 200) {
// I use the response body since it is a small file and already downloaded
val input = response.body?.byteStream()
if (input != null) {
// do stuff
response.body?.close()
retval = true
}
}
}
catch(exception: Exception) {
Log.e(TAG, "error ${exception.message ?: ""}")
}
retval
}.await()
if (!conn) {
connectivityMode = ConnectivityMode.NONE
}
}
....
Upvotes: 3
Reputation: 12583
No, as seen from here: https://developer.android.com/reference/android/net/ConnectivityManager.html#getActiveNetworkInfo()
getActiveNetworkInfo()
is still available in Android API 28, and nowhere says it is deprecated.
But the one deprecated is getType()
of NetworkInfo class.
https://developer.android.com/reference/android/net/NetworkInfo#getType()
This method was deprecated in API level 28.
Callers should switch to checking
NetworkCapabilities.hasTransport(int)
instead with one of theNetworkCapabilities#TRANSPORT_* constants : getType()
andgetTypeName()
cannot account for networks using multiple transports. Note that generally apps should not care about transport;NetworkCapabilities.NET_CAPABILITY_NOT_METERED
andNetworkCapabilities.getLinkDownstreamBandwidthKbps()
are calls that apps concerned with meteredness or bandwidth should be looking at, as they offer this information with much better accuracy.
Upvotes: 4