In Android N, it is mentioned on the official website that "Apps targeting Android N do not receive CONNECTIVITY_ACTION broadcasts". And it is also mentioned that JobScheduler
can be used as an alternative. But the JobScheduler
doesn't provide exactly the same behavior as CONNECTIVITY_ACTION
broadcast.
In my Android application, I was using this broadcast to know the network state of the device. I wanted to know if this state was CONNECTING
or CONNECTED
with the help of CONNECTIVITY_ACTION
broadcast and it was best suited for my requirement.
Now that it is deprecated, can any one suggest me the alternative approach to get current network state?
android.net.ConnectivityManager. Class that answers queries about the state of network connectivity. It also notifies applications when network connectivity changes. The primary responsibilities of this class are to: Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)
Checking Network Connection getSystemService(Context. CONNECTIVITY_SERVICE); Once you instantiate the object of ConnectivityManager class, you can use getAllNetworkInfo method to get the information of all the networks. This method returns an array of NetworkInfo.
Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml. In the above code, we have taken text view to show connection type.
As of Android 9, SDK 28 this is now deprecated. @CheeseBread That's the same code that I posted. The whole point of this question is that getNetworkInfo is deprecated :) The accepted answer is deprecated again in 28 (Android P), but its replacement method only works on 23 (Android M).
activeNetwork.getType () is deprecated also. You can use activeNetwork.isConnected ();
Class that answers queries about the state of network connectivity. It also notifies applications when network connectivity changes. Get an instance of this class by calling Context.getSystemService (Context.CONNECTIVITY_SERVICE) .
Class that answers queries about the state of network connectivity. It also notifies applications when network connectivity changes. Get an instance of this class by calling Context.getSystemService (Context.CONNECTIVITY_SERVICE) . This constant was deprecated in API level 16.
What will be deprecated is the ability for a backgrounded application to receive network connection state changes.
As David Wasser said you can still get notified of connectivity changes if the app component is instantiated (not destroyed) and you have registered your receiver programmatically with its context, instead of doing it in the manifest.
Or you can use NetworkCallback instead. In particular, you will need to override onAvailable for connected state changes.
Let me draft a snippet quickly:
public class ConnectionStateMonitor extends NetworkCallback { final NetworkRequest networkRequest; public ConnectionStateMonitor() { networkRequest = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .build(); } public void enable(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); connectivityManager.registerNetworkCallback(networkRequest, this); } // Likewise, you can have a disable method that simply calls ConnectivityManager.unregisterNetworkCallback(NetworkCallback) too. @Override public void onAvailable(Network network) { // Do what you need to do here } }
I will update Sayem's
answer for fix lint issues its showing to me.
class ConnectionLiveData(val context: Context) : LiveData<Boolean>() { private var connectivityManager: ConnectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback private val networkRequestBuilder: NetworkRequest.Builder = NetworkRequest.Builder() .addTransportType(android.net.NetworkCapabilities.TRANSPORT_CELLULAR) .addTransportType(android.net.NetworkCapabilities.TRANSPORT_WIFI) override fun onActive() { super.onActive() updateConnection() when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(getConnectivityMarshmallowManagerCallback()) Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> marshmallowNetworkAvailableRequest() Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> lollipopNetworkAvailableRequest() else -> { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { context.registerReceiver(networkReceiver, IntentFilter("android.net.conn.CONNECTIVITY_CHANGE")) // android.net.ConnectivityManager.CONNECTIVITY_ACTION } } } } override fun onInactive() { super.onInactive() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { connectivityManager.unregisterNetworkCallback(connectivityManagerCallback) } else { context.unregisterReceiver(networkReceiver) } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private fun lollipopNetworkAvailableRequest() { connectivityManager.registerNetworkCallback(networkRequestBuilder.build(), getConnectivityLollipopManagerCallback()) } @TargetApi(Build.VERSION_CODES.M) private fun marshmallowNetworkAvailableRequest() { connectivityManager.registerNetworkCallback(networkRequestBuilder.build(), getConnectivityMarshmallowManagerCallback()) } private fun getConnectivityLollipopManagerCallback(): ConnectivityManager.NetworkCallback { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network?) { postValue(true) } override fun onLost(network: Network?) { postValue(false) } } return connectivityManagerCallback } else { throw IllegalAccessError("Accessing wrong API version") } } private fun getConnectivityMarshmallowManagerCallback(): ConnectivityManager.NetworkCallback { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() { override fun onCapabilitiesChanged(network: Network?, networkCapabilities: NetworkCapabilities?) { networkCapabilities?.let { capabilities -> if (capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) { postValue(true) } } } override fun onLost(network: Network?) { postValue(false) } } return connectivityManagerCallback } else { throw IllegalAccessError("Accessing wrong API version") } } private val networkReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { updateConnection() } } private fun updateConnection() { val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo postValue(activeNetwork?.isConnected == true) } }
And same usage:
val connectionLiveData = ConnectionLiveData(context) connectionLiveData.observe(this, Observer { isConnected -> isConnected?.let { // do job } })
Btw thanks sayem for your solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With