From 77832b23777cfff9f64b335ae7aca1cbea6b7ea7 Mon Sep 17 00:00:00 2001 From: Ashwin Nirmale Date: Thu, 16 Jan 2020 12:45:01 +0530 Subject: [PATCH] updated to receive internet speed-type --- README.md | 86 +++++++++++-------- app/build.gradle | 1 + .../networkstatelistener/MainActivity.kt | 17 +++- build.gradle | 12 ++- gradle.properties | 3 + networkhandler/build.gradle | 9 ++ .../networkhandler/ExampleInstrumentedTest.kt | 4 +- .../networkhandler/config/NetworkConfig.kt | 45 ++++++++-- .../listener/NetworkStateListener.kt | 2 + .../receivers/NetworkStateReceiver.kt | 2 + .../networkhandler/utils/NetworkConstant.kt | 13 +++ .../networkhandler/utils/NetworkUtil.kt | 43 ++++++++++ .../NetworkStateReceiverTest.kt | 48 +++++++++++ 13 files changed, 235 insertions(+), 50 deletions(-) create mode 100644 networkhandler/src/main/java/com/kknirmale/networkhandler/utils/NetworkConstant.kt create mode 100644 networkhandler/src/test/java/com/kknirmale/networkhandler/NetworkStateReceiverTest.kt diff --git a/README.md b/README.md index 07c92b5..05e2acd 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,50 @@ -## NetworkListener ![](https://jitpack.io/v/AshwinN796/networkListener.svg) +# NetworkListener ![](https://jitpack.io/v/AshwinN796/networkListener.svg) + NetworkLister is the library to check the internet connection status of device at runtime. -## SetUp -##### project level gradle -``` + +## New Features! + - Now detect runtime internet speed status + +### Installation +#### Project level gradle + +```Gradle allprojects { repositories { - ... maven { url 'https://jitpack.io' } } } - -``` - -#### module level gradle ``` -implementation 'com.github.AshwinN796:networkListener:1.0.4' +#### Module level gradle +```Gradle +implementation 'com.github.AshwinN796:networkListener:1.1.0' ``` -## How to use +##### Implementation +Application class : -#### In your application class -``` +```Kotlin class MyApplication : Application() { - override fun onCreate() { - super.onCreate() - //init network class here - NetworkConfig.initNetworkConfig(this) - } + override fun onCreate() { + super.onCreate() + //init NetworkConfig + NetworkConfig.initNetworkConfig(this) + } - override fun onLowMemory() { - super.onLowMemory() - //Remove all listeners while on low memory - NetworkConfig.getInstance().removeAllNetworkConnectivityListener() - - } - } + override fun onLowMemory() { + super.onLowMemory() + //Remove all listeners while on low memory + NetworkConfig.getInstance().removeAllNetworkConnectivityListener() + } + } ``` +Activity class : -#### In your activity class -``` +```Kotlin class MainActivity : AppCompatActivity(), NetworkStateListener { private var networkConfig : NetworkConfig? = null @@ -50,24 +52,38 @@ class MainActivity : AppCompatActivity(), NetworkStateListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - - //get instance of networkConfig class + + //Get instance of networkConfig class networkConfig = NetworkConfig.getInstance() - - //add listener for NetworkConfig + + //add connectivity listener networkConfig!!.addNetworkConnectivityListener(this) } override fun onDestroy() { super.onDestroy() - //remove listener from NetworkConfig + //remove connectivity listener networkConfig!!.removeNetworkConnectivityListener(this) } + /* + Do action on network status changed + Here you can perform any action for Network state listener depending on your requirement. + */ override fun onNetworkStatusChanged(isConnected: Boolean) { - when(isConnected){ - true -> Toast.makeText(this@MainActivity,"Internet Connected",Toast.LENGTH_LONG).show() - false -> Toast.makeText(this@MainActivity,"Internet Failed",Toast.LENGTH_LONG).show() + +// when(isConnected){ +// true -> {//make your action} +// false -> {} +// } + } + + override fun onNetworkSpeedChanged(speedType: Int) { + when(speedType) { + NetworkConstant.WIFI_CONNECTED -> {//make your action} + NetworkConstant.FULL_SPEED_CONNECTED -> {} + NetworkConstant.SLOW_CONNECTED -> {} + NetworkConstant.LOW_SPEED_CONNECTED -> {} } } } diff --git a/app/build.gradle b/app/build.gradle index 46f063c..61fdafb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,4 +38,5 @@ dependencies { testImplementation testLibraries.junit4 androidTestImplementation androidTestLibraries.testRunner androidTestImplementation androidTestLibraries.espressoCore + androidTestImplementation androidTestLibraries.androidXJUnit } diff --git a/app/src/main/java/com/kknirmale/networkstatelistener/MainActivity.kt b/app/src/main/java/com/kknirmale/networkstatelistener/MainActivity.kt index e3bed70..98003f8 100644 --- a/app/src/main/java/com/kknirmale/networkstatelistener/MainActivity.kt +++ b/app/src/main/java/com/kknirmale/networkstatelistener/MainActivity.kt @@ -5,6 +5,7 @@ import android.os.Bundle import android.widget.Toast import com.kknirmale.networkhandler.config.NetworkConfig import com.kknirmale.networkhandler.listener.NetworkStateListener +import com.kknirmale.networkhandler.utils.NetworkConstant class MainActivity : AppCompatActivity(), NetworkStateListener { @@ -32,9 +33,19 @@ class MainActivity : AppCompatActivity(), NetworkStateListener { Here you can perform any action for Network state listener depending on your requirement. */ override fun onNetworkStatusChanged(isConnected: Boolean) { - when(isConnected){ - true -> Toast.makeText(this@MainActivity,"Internet Connected",Toast.LENGTH_LONG).show() - false -> Toast.makeText(this@MainActivity,"Internet Failed",Toast.LENGTH_LONG).show() + +// when(isConnected){ +// true -> Toast.makeText(this@MainActivity,"Internet Connected",Toast.LENGTH_LONG).show() +// false -> Toast.makeText(this@MainActivity,"Internet Failed",Toast.LENGTH_LONG).show() +// } + } + + override fun onNetworkSpeedChanged(speedType: Int) { + when(speedType) { + NetworkConstant.WIFI_CONNECTED -> Toast.makeText(this@MainActivity,"Wifi Connected",Toast.LENGTH_LONG).show() + NetworkConstant.FULL_SPEED_CONNECTED -> Toast.makeText(this@MainActivity,"Full Speed Connected",Toast.LENGTH_LONG).show() + NetworkConstant.SLOW_CONNECTED -> Toast.makeText(this@MainActivity,"No internet",Toast.LENGTH_LONG).show() + NetworkConstant.LOW_SPEED_CONNECTED -> Toast.makeText(this@MainActivity,"Slow internet",Toast.LENGTH_LONG).show() } } } diff --git a/build.gradle b/build.gradle index 7f60e8b..86dfce4 100644 --- a/build.gradle +++ b/build.gradle @@ -5,19 +5,21 @@ buildscript { ext { kotlin_version = '1.3.41' - gradle_version = '3.5.0' + gradle_version = '3.5.2' appMinSdkVersion = 21 appTargetSdkVersion = 29 appCompileSdkVersion = 29 - currentVersionCode = 1 - currentVersionName = '1.0.0' + currentVersionCode = 2 + currentVersionName = '1.1.0' androidx_libs_version = '1.1.0' android_constraint_version = '1.1.3' junit4Version = '4.12' + roboElectricVersion = '4.3' + andoridxJUnitVersion = '1.1.1' testRunnerVersion = '1.1.0' testEspressoVersion = '3.1.0' @@ -29,10 +31,12 @@ buildscript { ] testLibraries = [ - junit4 : "junit:junit:" + junit4Version + junit4 : "junit:junit:" + junit4Version, + roboElectric : "org.robolectric:robolectric:" + roboElectricVersion ] androidTestLibraries = [ + androidXJUnit : "androidx.test.ext:junit:" + andoridxJUnitVersion, testRunner: "androidx.test:runner:" + testRunnerVersion, espressoCore : "androidx.test.espresso:espresso-core:" + testEspressoVersion ] diff --git a/gradle.properties b/gradle.properties index 23339e0..4730e06 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,3 +19,6 @@ android.useAndroidX=true android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official + +# Added for roboelectric test framework +android.enableUnitTestBinaryResources=true diff --git a/networkhandler/build.gradle b/networkhandler/build.gradle index 8d84b84..14f1241 100644 --- a/networkhandler/build.gradle +++ b/networkhandler/build.gradle @@ -23,6 +23,12 @@ android { } } + testOptions { + unitTests { + includeAndroidResources = true + } + } + } dependencies { @@ -33,6 +39,9 @@ dependencies { implementation androidxLibraries.kotlin_core testImplementation testLibraries.junit4 + testImplementation testLibraries.roboElectric androidTestImplementation androidTestLibraries.testRunner androidTestImplementation androidTestLibraries.espressoCore + androidTestImplementation androidTestLibraries.androidXJUnit + } diff --git a/networkhandler/src/androidTest/java/com/kknirmale/networkhandler/ExampleInstrumentedTest.kt b/networkhandler/src/androidTest/java/com/kknirmale/networkhandler/ExampleInstrumentedTest.kt index 93cd8ce..c93edfa 100644 --- a/networkhandler/src/androidTest/java/com/kknirmale/networkhandler/ExampleInstrumentedTest.kt +++ b/networkhandler/src/androidTest/java/com/kknirmale/networkhandler/ExampleInstrumentedTest.kt @@ -1,7 +1,7 @@ package com.kknirmale.networkhandler import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner import org.junit.Test import org.junit.runner.RunWith @@ -13,7 +13,7 @@ import org.junit.Assert.* * * See [testing documentation](http://d.android.com/tools/testing). */ -@RunWith(AndroidJUnit4::class) +@RunWith(AndroidJUnit4ClassRunner::class) class ExampleInstrumentedTest { @Test fun useAppContext() { diff --git a/networkhandler/src/main/java/com/kknirmale/networkhandler/config/NetworkConfig.kt b/networkhandler/src/main/java/com/kknirmale/networkhandler/config/NetworkConfig.kt index 86da4d7..b8c6fad 100644 --- a/networkhandler/src/main/java/com/kknirmale/networkhandler/config/NetworkConfig.kt +++ b/networkhandler/src/main/java/com/kknirmale/networkhandler/config/NetworkConfig.kt @@ -17,6 +17,10 @@ import java.lang.ref.WeakReference */ class NetworkConfig(context: Context) : NetworkStateReceiver.InternetCheckListener{ + override fun onInternetSpeed(speedType: Int) { + reportNetworkSpeedType(speedType) + } + override fun onComplete(connected: Boolean) { if (connected){ reportInternetAvailabilityStatus(connected) @@ -56,6 +60,7 @@ class NetworkConfig(context: Context) : NetworkStateReceiver.InternetCheckListen private var networkChangeReceiver : NetworkStateReceiver? = null private var isNetworkStatusRegistered = false private var isNetworkConnected = false + private var networkTypeValue = 0 init { val appContext = context.applicationContext @@ -127,7 +132,39 @@ class NetworkConfig(context: Context) : NetworkStateReceiver.InternetCheckListen } /* - Attach connectivity listener to listen network state from broadcast receiver + Get report of internet speed value from from listener + */ + private fun reportNetworkSpeedType(speedType : Int) { + networkTypeValue = speedType + if (networkStateListenerWeakReferenceList == null){ + return + } + + val listenerIterator : MutableIterator> = networkStateListenerWeakReferenceList!!.iterator() + while (listenerIterator.hasNext()){ + + val listenerReference : WeakReference = listenerIterator.next() + if (listenerReference == null){ + listenerIterator.remove() + continue + } + + val statusListener : NetworkStateListener = listenerReference.get()!! + if (statusListener == null){ + listenerIterator.remove() + continue + } + + statusListener.onNetworkSpeedChanged(speedType) + } + + if (networkStateListenerWeakReferenceList!!.isEmpty()){ + unregisterNetworkChangeReceiver() + } + } + + /* + Attach all connectivity listener to listen network state from broadcast receiver */ fun addNetworkConnectivityListener(statusListener: NetworkStateListener){ if (statusListener == null){ @@ -141,6 +178,7 @@ class NetworkConfig(context: Context) : NetworkStateReceiver.InternetCheckListen } reportInternetAvailabilityStatus(isNetworkConnected) + reportNetworkSpeedType(networkTypeValue) } @@ -205,9 +243,4 @@ class NetworkConfig(context: Context) : NetworkStateReceiver.InternetCheckListen unregisterNetworkChangeReceiver() } - -// companion object{ -// var lock : Objec -// } - } \ No newline at end of file diff --git a/networkhandler/src/main/java/com/kknirmale/networkhandler/listener/NetworkStateListener.kt b/networkhandler/src/main/java/com/kknirmale/networkhandler/listener/NetworkStateListener.kt index 456721b..ce63030 100644 --- a/networkhandler/src/main/java/com/kknirmale/networkhandler/listener/NetworkStateListener.kt +++ b/networkhandler/src/main/java/com/kknirmale/networkhandler/listener/NetworkStateListener.kt @@ -9,4 +9,6 @@ Created by Ashwin Nirmale on 17 October,2019 interface NetworkStateListener { fun onNetworkStatusChanged(isConnected : Boolean) + + fun onNetworkSpeedChanged(speedType : Int) } \ No newline at end of file diff --git a/networkhandler/src/main/java/com/kknirmale/networkhandler/receivers/NetworkStateReceiver.kt b/networkhandler/src/main/java/com/kknirmale/networkhandler/receivers/NetworkStateReceiver.kt index 606b79c..20bc49e 100644 --- a/networkhandler/src/main/java/com/kknirmale/networkhandler/receivers/NetworkStateReceiver.kt +++ b/networkhandler/src/main/java/com/kknirmale/networkhandler/receivers/NetworkStateReceiver.kt @@ -21,6 +21,7 @@ class NetworkStateReceiver : BroadcastReceiver() { val internetChangeListener : InternetCheckListener = internetListenerReference!!.get()!! internetChangeListener.onComplete(NetworkUtil(context!!).isConnectedToMobileOrWifi()) + internetChangeListener.onInternetSpeed(NetworkUtil(context).isInternetHasSpeed()) } /* @@ -42,6 +43,7 @@ class NetworkStateReceiver : BroadcastReceiver() { interface InternetCheckListener { fun onComplete(connected: Boolean) + fun onInternetSpeed(speedType : Int) } diff --git a/networkhandler/src/main/java/com/kknirmale/networkhandler/utils/NetworkConstant.kt b/networkhandler/src/main/java/com/kknirmale/networkhandler/utils/NetworkConstant.kt new file mode 100644 index 0000000..d6de722 --- /dev/null +++ b/networkhandler/src/main/java/com/kknirmale/networkhandler/utils/NetworkConstant.kt @@ -0,0 +1,13 @@ +package com.kknirmale.networkhandler.utils + +/** + * Created by Ashwin Nirmale on 2020-01-16. + */ +object NetworkConstant { + + const val SLOW_CONNECTED = 0 + const val LOW_SPEED_CONNECTED = 1 + const val WIFI_CONNECTED = 2 + const val FULL_SPEED_CONNECTED =3 + +} \ No newline at end of file diff --git a/networkhandler/src/main/java/com/kknirmale/networkhandler/utils/NetworkUtil.kt b/networkhandler/src/main/java/com/kknirmale/networkhandler/utils/NetworkUtil.kt index fea00c5..f2b4cde 100644 --- a/networkhandler/src/main/java/com/kknirmale/networkhandler/utils/NetworkUtil.kt +++ b/networkhandler/src/main/java/com/kknirmale/networkhandler/utils/NetworkUtil.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.content.Context import android.net.ConnectivityManager import android.net.NetworkCapabilities +import android.net.NetworkInfo import android.os.Build import android.telephony.TelephonyManager @@ -62,6 +63,48 @@ class NetworkUtil() { } + fun isInternetHasSpeed() : Int { + val info = NetworkUtil(context).networkInfo.activeNetworkInfo + return if (isConnectedToMobileOrWifi()) { + return when (info?.type) { + ConnectivityManager.TYPE_WIFI -> NetworkConstant.WIFI_CONNECTED + ConnectivityManager.TYPE_MOBILE -> when (info.subtype) { + TelephonyManager.NETWORK_TYPE_1xRTT -> NetworkConstant.SLOW_CONNECTED // ~ 50-100 kbps + TelephonyManager.NETWORK_TYPE_CDMA -> NetworkConstant.SLOW_CONNECTED // ~ 14-64 kbps + TelephonyManager.NETWORK_TYPE_EDGE -> NetworkConstant.SLOW_CONNECTED // ~ 50-100 kbps + TelephonyManager.NETWORK_TYPE_EVDO_0 -> NetworkConstant.LOW_SPEED_CONNECTED // ~ 400-1000 kbps + TelephonyManager.NETWORK_TYPE_EVDO_A -> NetworkConstant.LOW_SPEED_CONNECTED // ~ 600-1400 kbps + TelephonyManager.NETWORK_TYPE_GPRS -> NetworkConstant.SLOW_CONNECTED // ~ 100 kbps + TelephonyManager.NETWORK_TYPE_HSDPA -> NetworkConstant.FULL_SPEED_CONNECTED // ~ 2-14 Mbps + TelephonyManager.NETWORK_TYPE_HSPA -> NetworkConstant.LOW_SPEED_CONNECTED // ~ 700-1700 kbps + TelephonyManager.NETWORK_TYPE_HSUPA -> NetworkConstant.FULL_SPEED_CONNECTED // ~ 1-23 Mbps + TelephonyManager.NETWORK_TYPE_UMTS -> NetworkConstant.LOW_SPEED_CONNECTED // ~ 400-7000 kbps + /* + * Above API level 7, make sure to set android:targetSdkVersion + * to appropriate level to use these + * Here the Minimum API Level is 22 so no need + */ + TelephonyManager.NETWORK_TYPE_EHRPD // API level 11 + -> NetworkConstant.FULL_SPEED_CONNECTED // ~ 1-2 Mbps + TelephonyManager.NETWORK_TYPE_EVDO_B // API level 9 + -> NetworkConstant.FULL_SPEED_CONNECTED // ~ 5 Mbps + TelephonyManager.NETWORK_TYPE_HSPAP // API level 13 + -> NetworkConstant.FULL_SPEED_CONNECTED // ~ 10-20 Mbps + TelephonyManager.NETWORK_TYPE_IDEN // API level 8 + -> NetworkConstant.SLOW_CONNECTED // ~25 kbps + TelephonyManager.NETWORK_TYPE_LTE // API level 11 + -> NetworkConstant.FULL_SPEED_CONNECTED // ~ 10+ Mbps + // Unknown + TelephonyManager.NETWORK_TYPE_UNKNOWN -> NetworkConstant.SLOW_CONNECTED + else -> NetworkConstant.SLOW_CONNECTED + } + else -> NetworkConstant.SLOW_CONNECTED + } + } else { + NetworkConstant.SLOW_CONNECTED + } + } + private fun isInternetFast(type: Int, subType: Int): Boolean { return when (type) { ConnectivityManager.TYPE_WIFI -> true diff --git a/networkhandler/src/test/java/com/kknirmale/networkhandler/NetworkStateReceiverTest.kt b/networkhandler/src/test/java/com/kknirmale/networkhandler/NetworkStateReceiverTest.kt new file mode 100644 index 0000000..c39f746 --- /dev/null +++ b/networkhandler/src/test/java/com/kknirmale/networkhandler/NetworkStateReceiverTest.kt @@ -0,0 +1,48 @@ +package com.kknirmale.networkhandler + +import android.app.Application +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.net.ConnectivityManager +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.Robolectric +import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment +import org.robolectric.Shadows +import org.robolectric.shadows.ShadowApplication + +/** + * Created by Ashwin Nirmale on 2019-12-10. + */ + +@RunWith(RobolectricTestRunner::class) +class NetworkStateReceiverTest { + + private lateinit var context : Context + + @Before + fun setup(){ + context = RuntimeEnvironment.systemContext + + } + + //test broadcast receiver with intent value + @Test + fun validateIntentHandlingToBroadcast(){ + val intentValue = Intent("android.net.conn.CONNECTIVITY_CHANGE") + +// val shadowApplication = ShadowApplication.getInstance(). +// val context : Context = RuntimeEnvironment.systemContext +// Assert.assertTrue(context.rece) + + val shadowApplication = ShadowApplication() +// val shadowApplication : ShadowApplication = Shadows.shadowOf((Application) ApplicationProvider!!.getApplicationContext()) + + Assert.assertTrue(shadowApplication.hasReceiverForIntent(intentValue)) + + } +} \ No newline at end of file