276

I am developing an Android broadcast receiver for checking the internet connection.

The problem is that my broadcast receiver is being called two times. I want it to get called only when the network is available. If it is unavailable, I don't want to be notified.

This is the broadcast receiver

public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { final ConnectivityManager connMgr = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); final android.net.NetworkInfo wifi = connMgr .getNetworkInfo(ConnectivityManager.TYPE_WIFI); final android.net.NetworkInfo mobile = connMgr .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); if (wifi.isAvailable() || mobile.isAvailable()) { // Do something Log.d("Network Available ", "Flag No 1"); } } } 

This is the manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.broadcastreceiverforinternetconnection" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <receiver android:name=".NetworkChangeReceiver" > <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> <action android:name="android.net.wifi.WIFI_STATE_CHANGED" /> </intent-filter> </receiver> </application> </manifest> 
2

21 Answers 21

259

Answer to your first question: Your broadcast receiver is being called two times because

You have added two <intent-filter>

  1. Change in network connection :
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

  2. Change in WiFi state:
    <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />

Just use one:
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />.

It will respond to only one action instead of two. See here for more information.

Answer to your second question (you want the receiver to call only one time if an internet connection is available):

Your code is perfect; you notify only when the internet is available.

UPDATE

You can use this method to check your connectivity if you want just to check whether your mobile is connected to the internet or not.

public boolean isOnline(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); //should check null because in airplane mode it will be a null return (netInfo != null && netInfo.isConnected()); } 
Sign up to request clarification or add additional context in comments.

8 Comments

No my second Query is I want notification when only the network is available but if the phone is loosing the network then to it is notifying me.
same here. I just have <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> registered but my receiver still get called twice. It is not really big problem but I would like to know why.
I am familiar with all of this , but I have doubts. I did some tests and found out that these broadcast receivers detect if your wifi / phone radio goes ON or OFF, or simply, if your device has an IP address. The problem comes when for example my phone is connected to a WiFi access point but such access point has no Internet. The code/phone tell me it a data connection regardless if the access point is providing it with Internet or Not. Does anybody know how to create a real Data-Internet listener, not just a WiFI/On/Off Listener?
@JosueGalindo onReceiving, you can use this code to know if device is connected to internet pastebin.com/dV3pJjkm
Declaring a broadcastreceiver for android.net.conn.CONNECTIVITY_CHANGE is deprecated for apps targeting N and higher. In general, apps should not rely on this broadcast and instead use JobScheduler or GCMNetworkManager. now ????
|
90
+25
public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { if (checkInternet(context)) { Toast.makeText(context, "Network Available Do operations", Toast.LENGTH_LONG).show(); } } boolean checkInternet(Context context) { ServiceManager serviceManager = new ServiceManager(context); return serviceManager.isNetworkAvailable() } } 

ServiceManager.java

public class ServiceManager { Context context; public ServiceManager(Context base) { context = base; } public boolean isNetworkAvailable() { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = cm.getActiveNetworkInfo(); return networkInfo != null && networkInfo.isConnected(); } } 

permissions:

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> 

5 Comments

for me the problem was receiver gets called twice on network change?
why would you use a ContextWrapper? Want to understand
me also getting @manivannan problem... reciever calling twice on network change... is there any solution for that
No need to extend ServiceManager with ContextWrapper.
What the hell is this for? ServiceManager extends ContextWrapper? Why do you need to extend ContextWrapper? WHY!?
65

Checking internet status every time using Broadcast Receiver:

internet status implementation

Full source code available on Google Drive.

AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <receiver android:name=".receivers.NetworkChangeReceiver"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> 

BroadcastReciever

package com.keshav.networkchangereceiverexample.receivers; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.util.Log; import static com.keshav.networkchangereceiverexample.MainActivity.dialog; public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { try { if (isOnline(context)) { dialog(true); Log.e("keshav", "Online Connect Intenet "); } else { dialog(false); Log.e("keshav", "Conectivity Failure !!! "); } } catch (NullPointerException e) { e.printStackTrace(); } } private boolean isOnline(Context context) { try { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); //should check null because in airplane mode it will be null return (netInfo != null && netInfo.isConnected()); } catch (NullPointerException e) { e.printStackTrace(); return false; } } } 

MainActivity.java

package com.keshav.networkchangereceiverexample; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Color; import android.net.ConnectivityManager; import android.os.Build; import android.os.Handler; import android.os.Looper; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.TextView; import com.keshav.networkchangereceiverexample.receivers.NetworkChangeReceiver; public class MainActivity extends AppCompatActivity { private BroadcastReceiver mNetworkReceiver; static TextView tv_check_connection; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_check_connection=(TextView) findViewById(R.id.tv_check_connection); mNetworkReceiver = new NetworkChangeReceiver(); registerNetworkBroadcastForNougat(); } public static void dialog(boolean value){ if(value){ tv_check_connection.setText("We are back !!!"); tv_check_connection.setBackgroundColor(Color.GREEN); tv_check_connection.setTextColor(Color.WHITE); Handler handler = new Handler(); Runnable delayrunnable = new Runnable() { @Override public void run() { tv_check_connection.setVisibility(View.GONE); } }; handler.postDelayed(delayrunnable, 3000); }else { tv_check_connection.setVisibility(View.VISIBLE); tv_check_connection.setText("Could not Connect to internet"); tv_check_connection.setBackgroundColor(Color.RED); tv_check_connection.setTextColor(Color.WHITE); } } private void registerNetworkBroadcastForNougat() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } } protected void unregisterNetworkChanges() { try { unregisterReceiver(mNetworkReceiver); } catch (IllegalArgumentException e) { e.printStackTrace(); } } @Override public void onDestroy() { super.onDestroy(); unregisterNetworkChanges(); } } 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.keshav.networkchangereceiverexample.MainActivity"> <TextView android:id="@+id/tv_check_connection" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Connection establised !" android:padding="25dp" app:layout_constraintBottom_toBottomOf="parent" android:gravity="center" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </LinearLayout> 

6 Comments

Its Very usefull same as youtube every time check online ,offline
Thanks for your great post. Why did you add this: Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) in registerNetworkBroadcastForNougat? The manifest is not working in android N and Up and M shoud be fine
duplicate code at registerNetworkBroadcastForNougat()
shouldnt there be a else in this code segment ? 'if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); }'
This will not work if device connected internet, but there is no bandwidth.
|
26

Use this method to check the network state:

private void checkInternetConnection() { if (br == null) { br = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Bundle extras = intent.getExtras(); NetworkInfo info = (NetworkInfo) extras .getParcelable("networkInfo"); State state = info.getState(); Log.d("TEST Internet", info.toString() + " " + state.toString()); if (state == State.CONNECTED) { Toast.makeText(getApplicationContext(), "Internet connection is on", Toast.LENGTH_LONG).show(); } else { Toast.makeText(getApplicationContext(), "Internet connection is Off", Toast.LENGTH_LONG).show(); } } }; final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver((BroadcastReceiver) br, intentFilter); } } 

remember to unregister service in onDestroy.

Cheers!!

Comments

15

Warning: Declaring a broadcastreceiver for android.net.conn.CONNECTIVITY_CHANGE is deprecated for apps targeting N and higher. In general, apps should not rely on this broadcast and instead use JobScheduler or GCMNetworkManager.

As CONNECTIVITY_CHANGE is deprecated then we should use another way of doing the same stuff

Following NetworkConnectionLiveData will handle all the OS Version till now and also if target SDK is less than Build.VERSION_CODES.LOLLIPOP then only we can use broadcastReceiver

Best Part is this class uses LiveData so no need to register any receiver use LiveData and it will handle all the things

class NetworkConnectionLiveData(val context: Context) : LiveData<Boolean>() { private var connectivityManager: ConnectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback override fun onActive() { super.onActive() updateConnection() when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(getConnectivityManagerCallback()) 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")) } } } } 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() { val builder = NetworkRequest.Builder() .addTransportType(android.net.NetworkCapabilities.TRANSPORT_CELLULAR) .addTransportType(android.net.NetworkCapabilities.TRANSPORT_WIFI) connectivityManager.registerNetworkCallback(builder.build(), getConnectivityManagerCallback()) } private fun getConnectivityManagerCallback(): 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("Should not happened") } } 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) } } 

Use of the LiveData into any class:

NetworkConnectionLiveData(context ?: return) .observe(viewLifecycleOwner, Observer { isConnected -> if (!isConnected) { // Internet Not Available return@Observer } // Internet Available }) 

2 Comments

Is there a Java version of this?
@Sumit Jain How can we use this approach when our application is not active and is closed ? Basically I want to get to know internet availability when my application is not open.
10
public static boolean isNetworkAvailable(Context context) { boolean isMobile = false, isWifi = false; NetworkInfo[] infoAvailableNetworks = getConnectivityManagerInstance( context).getAllNetworkInfo(); if (infoAvailableNetworks != null) { for (NetworkInfo network : infoAvailableNetworks) { if (network.getType() == ConnectivityManager.TYPE_WIFI) { if (network.isConnected() && network.isAvailable()) isWifi = true; } if (network.getType() == ConnectivityManager.TYPE_MOBILE) { if (network.isConnected() && network.isAvailable()) isMobile = true; } } } return isMobile || isWifi; } /* You can write such method somewhere in utility class and call it NetworkChangeReceiver like below */ public class NetworkChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (isNetworkAvailable(context)) { Toast.makeText(context, "Network Available Do operations",Toast.LENGTH_LONG).show(); } } } 

This above broadcast receiver will be called only when Network state change to connected and not on disconnected.

Comments

10

just for someone else who wanna register a broadcast dynamicly:

BroadcastReceiver mWifiReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (checkWifiConnect()) { Log.d(TAG, "wifi has connected"); // TODO } } }; private void registerWifiReceiver() { IntentFilter filter = new IntentFilter(); filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mContext.registerReceiver(mWifiReceiver, filter); } private void unregisterWifiReceiver() { mContext.unregisterReceiver(mWifiReceiver); } private boolean checkWifiConnect() { ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = manager.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI && networkInfo.isConnected()) { return true; } return false; } 

Comments

8

CONNECTIVITY_ACTION docs:

Apps targeting Android 7.0 (API level 24) and higher do not receive this broadcast if they declare the broadcast receiver in their manifest. Apps will still receive broadcasts if they register their BroadcastReceiver with Context.registerReceiver() and that context is still valid.

Comments

8

Here's a comfortable way to do it for activity, fragment or context. It will also auto-unregister if you do it for activity/fragment (in onDestroy), if you wish:

abstract class ConnectionBroadcastReceiver : BroadcastReceiver() { companion object { @JvmStatic fun registerWithoutAutoUnregister(context: Context, connectionBroadcastReceiver: ConnectionBroadcastReceiver) { context.registerReceiver(connectionBroadcastReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)) } @JvmStatic fun registerToFragmentAndAutoUnregister(context: Context, fragment: Fragment, connectionBroadcastReceiver: ConnectionBroadcastReceiver) { val applicationContext = context.applicationContext registerWithoutAutoUnregister(applicationContext, connectionBroadcastReceiver) fragment.lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun onDestroy() { applicationContext.unregisterReceiver(connectionBroadcastReceiver) } }) } @JvmStatic fun registerToActivityAndAutoUnregister(activity: AppCompatActivity, connectionBroadcastReceiver: ConnectionBroadcastReceiver) { registerWithoutAutoUnregister(activity, connectionBroadcastReceiver) activity.lifecycle.addObserver(object : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun onDestroy() { activity.unregisterReceiver(connectionBroadcastReceiver) } }) } @JvmStatic fun hasInternetConnection(context: Context): Boolean { val info = (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo return !(info == null || !info.isConnectedOrConnecting) } } override fun onReceive(context: Context, intent: Intent) { val hasConnection = !intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false) // Log.d("AppLog", "conenctivity changed. hasConnection? $hasConnection") onConnectionChanged(hasConnection) } abstract fun onConnectionChanged(hasConnection: Boolean) } 

Usage in fragment:

 ConnectionBroadcastReceiver.registerToFragmentAndAutoUnregister(activity!!, this, object : ConnectionBroadcastReceiver() { override fun onConnectionChanged(hasConnection: Boolean) { // Log.d("AppLog", "onConnectionChanged:" + hasConnection) } }) 

Also, in case you want to check Internet connection right now, you could use this:

fun isInternetOn(context: Context): Boolean { val connectivityManager: ConnectivityManager = context.getSystemServiceCompat() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val allNetworks = connectivityManager.allNetworks for (network in allNetworks) { val networkCapabilities = connectivityManager.getNetworkCapabilities(network) ?: continue if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) return true } return false } else { @Suppress("DEPRECATION") val allNetworkInfo = connectivityManager.allNetworkInfo for (networkInfo in allNetworkInfo) { @Suppress("DEPRECATION") if (networkInfo.isConnected) return true } } return false } 

1 Comment

7

I know this thread is old and fully answered but I feel that the following might help some people.

The code in the body of the question contains a bug which no one here addressed. @Nikhil is checking whether the wifi/mobile is available and not if it's connected.

The fix is here:

@Override public void onReceive(final Context context, final Intent intent) { final ConnectivityManager connMgr = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); final android.net.NetworkInfo wifi = connMgr .getNetworkInfo(ConnectivityManager.TYPE_WIFI); final android.net.NetworkInfo mobile = connMgr .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); if (wifi.isConnected() || mobile.isConnected()) { // do stuff } } 

1 Comment

Yes, I just want to suggest the same, wifi.isConnected() fix
7

manifest:

<receiver android:name=".your.namepackage.here.ConnectivityReceiver"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> </receiver> 

class for receiver:

public class ConnectivityReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); switch (action) { case ConnectivityManager.CONNECTIVITY_ACTION: DebugUtils.logDebug("BROADCAST", "network change"); if(NetworkUtils.isConnect()){ //do action here } break; } } } 

and classs utils like example:

public class NetworkUtils { public static boolean isConnect() { ConnectivityManager connectivityManager = (ConnectivityManager) Application.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Network[] netArray = connectivityManager.getAllNetworks(); NetworkInfo netInfo; for (Network net : netArray) { netInfo = connectivityManager.getNetworkInfo(net); if ((netInfo.getTypeName().equalsIgnoreCase("WIFI") || netInfo.getTypeName().equalsIgnoreCase("MOBILE")) && netInfo.isConnected() && netInfo.isAvailable()) { //if (netInfo.getState().equals(NetworkInfo.State.CONNECTED)) { Log.d("Network", "NETWORKNAME: " + netInfo.getTypeName()); return true; } } } else { if (connectivityManager != null) { @SuppressWarnings("deprecation") NetworkInfo[] netInfoArray = connectivityManager.getAllNetworkInfo(); if (netInfoArray != null) { for (NetworkInfo netInfo : netInfoArray) { if ((netInfo.getTypeName().equalsIgnoreCase("WIFI") || netInfo.getTypeName().equalsIgnoreCase("MOBILE")) && netInfo.isConnected() && netInfo.isAvailable()) { //if (netInfo.getState() == NetworkInfo.State.CONNECTED) { Log.d("Network", "NETWORKNAME: " + netInfo.getTypeName()); return true; } } } } } return false; } } 

Comments

7

Try with this

public class ConnectionBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (<Check internet connection available >) { Toast.makeText(context, "connect to the internet", Toast.LENGTH_LONG).show(); /*upload background upload service*/ Intent serviceIntent = new Intent(context,<your service class>); context.startService(serviceIntent); }else{ Toast.makeText(context, "Connection failed", Toast.LENGTH_LONG).show(); } } } 

As soon as internet connection trigger, this (BroadcastReciever) will be loaded

1 Comment

And how do you register this receiver? What intent filter?
4

As of 2022 none of the above BroadcastReceiver approaches will work. The BroadcastReceiver method will not work anymore due to the restrictions imposed on Android 7.0. The latest and easiest way of checking whether the internet is available or not is using the following code. (Working on Android 12 tested)

val networkRequest = NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .build() private val networkCallback = object : ConnectivityManager.NetworkCallback() { // network is available for use override fun onAvailable(network: Network) { super.onAvailable(network) } // Network capabilities have changed for the network override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { super.onCapabilitiesChanged(network, networkCapabilities) val unmetered = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) } // lost network connection override fun onLost(network: Network) { super.onLost(network) } } val connectivityManager = getSystemService(ConnectivityManager::class.java) as ConnectivityManager connectivityManager.requestNetwork(networkRequest, networkCallback 

Place this piece of code in a function and call this in onCreate() of your activity/fragment. You will be notified everytime when internet is connected or disconnected in onAvailable() and onLost() functions. Along with this, you can use liveData or whatever you like to broadcast these updates in other activities/fragments. The official docs link: https://developer.android.com/training/monitoring-device-state/connectivity-status-type

2 Comments

can we use this approach when our application is closed ?
I don't think so and haven't tested it for that kind of scenario. You might have to find a workaround solution with WorkManager. As of now, WorkManager is the recommended solution for all kinds of background tasks.
3
public class AsyncCheckInternet extends AsyncTask<String, Void, Boolean> { public static final int TIME_OUT = 10 * 1000; private OnCallBack listener; public interface OnCallBack { public void onBack(Boolean value); } public AsyncCheckInternet(OnCallBack listener) { this.listener = listener; } @Override protected void onPreExecute() { } @Override protected Boolean doInBackground(String... params) { ConnectivityManager connectivityManager = (ConnectivityManager) General.context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if ((networkInfo != null && networkInfo.isConnected()) && ((networkInfo.getType() == ConnectivityManager.TYPE_WIFI) || (networkInfo .getType() == ConnectivityManager.TYPE_MOBILE))) { HttpURLConnection urlc; try { urlc = (HttpURLConnection) (new URL("http://www.google.com") .openConnection()); urlc.setConnectTimeout(TIME_OUT); urlc.connect(); if (urlc.getResponseCode() == HttpURLConnection.HTTP_OK) { return true; } else { return false; } } catch (MalformedURLException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } } else { return false; } } @Override protected void onPostExecute(Boolean result) { if (listener != null) { listener.onBack(result); } } 

}

1 Comment

AsynTasks should be used for something really small. You should use Service instead.
3

Add a broadcast receiver which can listen to network connectivity change. Then check wether device is connected to internet or not using ConnectivityManager. Refer to this post or video for detailed understanding. Below is the code:

public class NetworkStateChangeReceiver extends BroadcastReceiver { public static final String NETWORK_AVAILABLE_ACTION = "com.ajit.singh.NetworkAvailable"; public static final String IS_NETWORK_AVAILABLE = "isNetworkAvailable"; @Override public void onReceive(Context context, Intent intent) { Intent networkStateIntent = new Intent(NETWORK_AVAILABLE_ACTION); networkStateIntent.putExtra(IS_NETWORK_AVAILABLE, isConnectedToInternet(context)); LocalBroadcastManager.getInstance(context).sendBroadcast(networkStateIntent); } private boolean isConnectedToInternet(Context context) { try { if (context != null) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); return networkInfo != null && networkInfo.isConnected(); } return false; } catch (Exception e) { Log.e(NetworkStateChangeReceiver.class.getName(), e.getMessage()); return false; } } } 

I wrote this receiver to show a notification on the Screen, that's why you see a local broadcast with the network status. Here is the code to show the notification.

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); IntentFilter intentFilter = new IntentFilter(NetworkStateChangeReceiver.NETWORK_AVAILABLE_ACTION); LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { boolean isNetworkAvailable = intent.getBooleanExtra(IS_NETWORK_AVAILABLE, false); String networkStatus = isNetworkAvailable ? "connected" : "disconnected"; Snackbar.make(findViewById(R.id.activity_main), "Network Status: " + networkStatus, Snackbar.LENGTH_LONG).show(); } }, intentFilter); } } 

Activity listens to the intent broadcasted by the network receiver and shows the notification on the screen.

Comments

1

Broadcast receiver code to check internet connectivity change:

public class BroadCastDetecter extends BroadcastReceiver { public static boolean internet_status = false; public static void checkInternetConenction(Context context) { internet_status = false; ConnectivityManager check = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (check != null) { NetworkInfo[] info = check.getAllNetworkInfo(); if (info != null) for (int i = 0; i < info.length; i++) { if (info[i].getState() == NetworkInfo.State.CONNECTED) { internet_status = true; } } if(internet_status) { //do what you want to if internet connection is available } } } @Override public void onReceive(Context context, Intent intent) { try { checkInternetConenction(context); }catch(Exception e){ } } } 

add this in manifest file:

 <receiver android:name=".BroadCastDetecter"> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> 

Comments

1

This only checks if the network interface is available, doesn't guarantee a particular network service is available, for example, there could be low signal or server downtime

 private boolean isNetworkInterfaceAvailable(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); } 

if you want to make a real connection to make sure your connection can gather data from a server or any url:

 private boolean isAbleToConnect(String url, int timeout) { try { URL myUrl = new URL(url); URLConnection connection = myUrl.openConnection(); connection.setConnectTimeout(timeout); connection.connect(); return true; } catch (Exception e) { Log.i("exception", "" + e.getMessage()); return false; } } 

This function needs to be wrapped in a background thread :

final String action = intent.getAction(); if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { checkConnectivity(context); } } private void checkConnectivity(final Context context) { if (!isNetworkInterfaceAvailable(context)) { Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show(); return; } final Handler handler = new Handler(); new Thread(new Runnable() { @Override public void run() { final boolean isConnected = isAbleToConnect("http://www.google.com", 1000); handler.post(new Runnable() { @Override public void run() { if (isConnected) Toast.makeText(context, "You are ONLINE!", Toast.LENGTH_SHORT).show(); else Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show(); } }); } }).start(); } 

Add required permissions:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET"/> 

Add this line under application in manifest file:

android:usesCleartextTraffic="true" 

Add receiver to manifest file:

<receiver android:name=".ConnectivityChangeReceiver" > <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> 

Register/Unregister the BR in you Activity:

@Override protected void onStart() { super.onStart(); IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"); registerReceiver(connectivityChangeReceiver, filter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(connectivityChangeReceiver); } 

this is the entire Broadcast class :

import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Handler; import android.util.Log; import android.widget.Toast; import java.net.URL; import java.net.URLConnection; public class ConnectivityChangeReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { final String action = intent.getAction(); if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { checkConnectivity(context); } } private void checkConnectivity(final Context context) { if (!isNetworkInterfaceAvailable(context)) { Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show(); return; } final Handler handler = new Handler(); new Thread(new Runnable() { @Override public void run() { final boolean isConnected = isAbleToConnect("http://www.google.com", 1000); handler.post(new Runnable() { @Override public void run() { if (isConnected) Toast.makeText(context, "You are ONLINE!", Toast.LENGTH_SHORT).show(); else Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show(); } }); } }).start(); } //This only checks if the network interface is available, doesn't guarantee a particular network service is available, for example, there could be low signal or server downtime private boolean isNetworkInterfaceAvailable(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); } //This makes a real connection to an url and checks if you can connect to this url, this needs to be wrapped in a background thread private boolean isAbleToConnect(String url, int timeout) { try { URL myUrl = new URL(url); URLConnection connection = myUrl.openConnection(); connection.setConnectTimeout(timeout); connection.connect(); return true; } catch (Exception e) { Log.i("exception", "" + e.getMessage()); return false; } } } 

Comments

1

1) In manifest : - call receiver like below code

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.safal.checkinternet"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" tools:ignore="AllowBackup,GoogleAppIndexingWarning"> <receiver android:name=".NetworkChangeReceiver" > <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

2) Make one Broad Cast Receiver Class: - In This class add code of Network Check

package com.safal.checkinternet; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.util.Log; import android.widget.Toast; public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { if (isOnline(context)){ Toast.makeText(context, "Available", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(context, "Not Available", Toast.LENGTH_SHORT).show(); } } public boolean isOnline(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); assert cm != null; NetworkInfo netInfo = cm.getActiveNetworkInfo(); return (netInfo != null && netInfo.isConnected()); } } 

3) In your Activity call to Broad Cast Receiver : -

package com.safal.checkinternet; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Call Broad cast Receiver IntentFilter filter = new IntentFilter(); filter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); registerReceiver(new NetworkChangeReceiver(), filter); } } 

Comments

1
  • Now you don't need a broadcast receiver to observe the network changes
  • We can achieve this using the flow

Here is a better working solution with source code and demo implemented in my github

Comments

0

It's easier to use https://github.com/JobGetabu/DroidNet

 @Override public void onInternetConnectivityChanged(boolean isConnected) { if (isConnected) { //do Stuff with internet netIsOn(); } else { //no internet netIsOff(); } } private void netIsOn(){...} private void netIsOff(){...} 

Comments

0

Add permissions:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> 

Create Receiver to check for connection

public class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { if(checkInternet(context)) { Toast.makeText(context, "Network Available Do operations",Toast.LENGTH_LONG).show(); } } boolean checkInternet(Context context) { ServiceManager serviceManager = new ServiceManager(context); if (serviceManager.isNetworkAvailable()) { return true; } else { return false; } } } 

ServiceManager.java

public class ServiceManager { Context context; public ServiceManager(Context base) { context = base; } public boolean isNetworkAvailable() { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = cm.getActiveNetworkInfo(); return networkInfo != null && networkInfo.isConnected(); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.