Skip to content

Instantly share code, notes, and snippets.

@timtsj
Created May 11, 2020 06:22
Show Gist options
  • Save timtsj/95c90a1222b3999161bf19fec449d0fc to your computer and use it in GitHub Desktop.
Save timtsj/95c90a1222b3999161bf19fec449d0fc to your computer and use it in GitHub Desktop.
Android utility class for checking device's network connectivity and speed.
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.NetworkInfo
import android.os.Build
import android.telephony.TelephonyManager
object NetworkUtils {
enum class ConnectivityMode {
NONE,
WIFI,
MOBILE,
OTHER,
MAYBE
}
enum class ConnectionQuality {
/**
* Bandwidth under 150 kbps.
*/
POOR,
/**
* Bandwidth between 150 and 550 kbps.
*/
MODERATE,
/**
* Bandwidth between 550 and 2000 kbps.
*/
GOOD,
/**
* EXCELLENT - Bandwidth over 2000 kbps.
*/
EXCELLENT,
/**
* Placeholder for unknown bandwidth. This is the initial value and will stay at this value
* if a bandwidth cannot be accurately found.
*/
UNKNOWN
}
fun getConnectivityMode(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
}
fun getConnectionQuality(context: Context): ConnectionQuality {
val info = getNetworkInfo(context)
return when (getConnectivityMode(context)) {
ConnectivityMode.WIFI -> ConnectionQuality.EXCELLENT
ConnectivityMode.MOBILE -> when (info?.subtype) {
TelephonyManager.NETWORK_TYPE_1xRTT -> ConnectionQuality.POOR // ~ 50-100 kbps
TelephonyManager.NETWORK_TYPE_CDMA -> ConnectionQuality.POOR // ~ 14-64 kbps
TelephonyManager.NETWORK_TYPE_EDGE -> ConnectionQuality.POOR // ~ 50-100 kbps
TelephonyManager.NETWORK_TYPE_EVDO_0 -> ConnectionQuality.MODERATE // ~ 400-1000 kbps
TelephonyManager.NETWORK_TYPE_EVDO_A -> ConnectionQuality.GOOD // ~ 600-1400 kbps
TelephonyManager.NETWORK_TYPE_GPRS -> ConnectionQuality.POOR // ~ 100 kbps
TelephonyManager.NETWORK_TYPE_HSDPA -> ConnectionQuality.EXCELLENT // ~ 2-14 Mbps
TelephonyManager.NETWORK_TYPE_HSPA -> ConnectionQuality.GOOD // ~ 700-1700 kbps
TelephonyManager.NETWORK_TYPE_HSUPA -> ConnectionQuality.GOOD // ~ 1-23 Mbps
TelephonyManager.NETWORK_TYPE_UMTS -> ConnectionQuality.MODERATE // ~ 400-7000 kbps
TelephonyManager.NETWORK_TYPE_EHRPD -> ConnectionQuality.GOOD // ~ 1-2 Mbps
TelephonyManager.NETWORK_TYPE_EVDO_B -> ConnectionQuality.EXCELLENT // ~ 5 Mbps
TelephonyManager.NETWORK_TYPE_HSPAP -> ConnectionQuality.EXCELLENT // ~ 10-20 Mbps
TelephonyManager.NETWORK_TYPE_IDEN -> ConnectionQuality.POOR // ~25 kbps
TelephonyManager.NETWORK_TYPE_LTE -> ConnectionQuality.EXCELLENT // ~ 10+ Mbps
TelephonyManager.NETWORK_TYPE_UNKNOWN -> ConnectionQuality.UNKNOWN
else -> ConnectionQuality.UNKNOWN
}
else -> ConnectionQuality.UNKNOWN
}
}
fun getNetworkInfo(context: Context): NetworkInfo? {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return cm.activeNetworkInfo
}
fun isConnected(context: Context): Boolean {
val info = getNetworkInfo(context)
return info != null && info.isConnected
}
fun isInternetAvailable(context: Context): Boolean {
return isConnectedWifi(context) && isConnectedMobile(context)
}
fun isConnectedWifi(context: Context): Boolean {
return isConnected(context) && getConnectivityMode(context) == ConnectivityMode.WIFI
}
fun isConnectedMobile(context: Context): Boolean {
return isConnected(context) && getConnectivityMode(context) == ConnectivityMode.MOBILE
}
fun isConnectedFast(context: Context): Boolean {
val info = getNetworkInfo(context)
return info != null && info.isConnected && isConnectionFast(getConnectivityMode(context), info.subtype)
}
fun isConnectionFast(type: ConnectivityMode, subType: Int): Boolean {
return when (type) {
ConnectivityMode.WIFI -> true
ConnectivityMode.MOBILE -> when (subType) {
TelephonyManager.NETWORK_TYPE_1xRTT -> false // ~ 50-100 kbps
TelephonyManager.NETWORK_TYPE_CDMA -> false // ~ 14-64 kbps
TelephonyManager.NETWORK_TYPE_EDGE -> false // ~ 50-100 kbps
TelephonyManager.NETWORK_TYPE_EVDO_0 -> true // ~ 400-1000 kbps
TelephonyManager.NETWORK_TYPE_EVDO_A -> true // ~ 600-1400 kbps
TelephonyManager.NETWORK_TYPE_GPRS -> false // ~ 100 kbps
TelephonyManager.NETWORK_TYPE_HSDPA -> true // ~ 2-14 Mbps
TelephonyManager.NETWORK_TYPE_HSPA -> true // ~ 700-1700 kbps
TelephonyManager.NETWORK_TYPE_HSUPA -> true // ~ 1-23 Mbps
TelephonyManager.NETWORK_TYPE_UMTS -> true // ~ 400-7000 kbps
TelephonyManager.NETWORK_TYPE_EHRPD -> true // ~ 1-2 Mbps
TelephonyManager.NETWORK_TYPE_EVDO_B -> true // ~ 5 Mbps
TelephonyManager.NETWORK_TYPE_HSPAP -> true // ~ 10-20 Mbps
TelephonyManager.NETWORK_TYPE_IDEN -> false // ~25 kbps
TelephonyManager.NETWORK_TYPE_LTE -> true // ~ 10+ Mbps
TelephonyManager.NETWORK_TYPE_UNKNOWN -> false
else -> false
}
else -> false
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment