Shahrear Bin Amin
Shahrear Bin Amin

Reputation: 1115

How to show alert dialog when there is no internet?

My app is internet-based. I need to show an alert dialog when there is no internet while my app is running. So I've created a BroadcastReceiver and registered it in MainActivity. I can show no internet with toast properly on top of every activity or fragment, but the alert dialog is only shown in MainActivity. When I'm in another activity or fragment and the network is disconnected it doesn't show an alert dialog in my current activity but shows an alert dialog in MainActivity, it seems like context it's getting is the context of MainActivity. My code is here NetworkUtil.java as utility class.

//NetworkUtil.java
public class NetworkUtil {
    public static final int TYPE_WIFI = 1;
    public static final int TYPE_MOBILE = 2;
    public static final int TYPE_NOT_CONNECTED = 0;
    public static final int NETWORK_STATUS_NOT_CONNECTED = 0;
    public static final int NETWORK_STATUS_WIFI = 1;
    public static final int NETWORK_STATUS_MOBILE = 2;

    public static int getConnectivityStatus(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (null != activeNetwork) {
            if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
                return TYPE_WIFI;

            if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
                return TYPE_MOBILE;
        }
        return TYPE_NOT_CONNECTED;
    }

    public static int getConnectivityStatusString(Context context) {
        int conn = NetworkUtil.getConnectivityStatus(context);
        int status = 0;
        if (conn == NetworkUtil.TYPE_WIFI) {
            status = NETWORK_STATUS_WIFI;
        } else if (conn == NetworkUtil.TYPE_MOBILE) {
            status = NETWORK_STATUS_MOBILE;
        } else if (conn == NetworkUtil.TYPE_NOT_CONNECTED) {
            status = NETWORK_STATUS_NOT_CONNECTED;
        }
        return status;
    }
}

My BroadcastReceiver CheckConnectivity

public class CheckConnectivity extends BroadcastReceiver{
@Override
    public void onReceive(final Context context, final Intent intent) {

        int status = NetworkUtil.getConnectivityStatusString(context);
        if ("android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction())) {
            if (status == NetworkUtil.NETWORK_STATUS_NOT_CONNECTED) {
                new SweetAlertDialog(context, SweetAlertDialog.ERROR_TYPE)
                        .setTitleText("Oops...")
                        .setContentText("No internet! Check your network connection")
                        .show();
            Toast.makeText(context, "Internet Connection Lost", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(context, "Internet Connected", Toast.LENGTH_LONG).show();
            }
        }
    }
}

MainActivity where BroadcastReceiver is registered.

public class MainActivity extends AppCompatActivity {

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BroadcastReceiver networkChangeReceiver=new CheckConnectivity();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(networkChangeReceiver, intentFilter);
   }
}

Upvotes: 0

Views: 1784

Answers (3)

Rishabh Jain
Rishabh Jain

Reputation: 155

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

So, below is the full solution for all the devices.

Create a common class to check whether device is connected to network state or not.

class ConnectivityHelper() {
    companion object {
        fun isConnectedToNetwork(): Boolean {
            val connectivityManager: ConnectivityManager =
                CenceApplication.cenceAppContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val networkInfo = connectivityManager.activeNetworkInfo
            if (networkInfo != null) {
                return networkInfo.isConnected
            }
            return false
        }
    }
}

Now to check for devices below than Nougat: 1. You need to setup broadcast receiver in manifest 2. Listen to changes 3. Notify to your base activity.

Note: Base activity is common activity, which is extended by all other activities in the app, and base activity is extended by AppCompatActivity()

In Manifest:

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

Broadcast receiver class:

class NetworkChangeReceiver : BroadcastReceiver() {

    companion object {
        lateinit var networkChangeListener: NetworkChangeListener
    }

    override fun onReceive(context: Context?, intent: Intent?) {
        networkChangeListener.networkStateChanged(ConnectivityHelper.isConnectedToNetwork())
    }
}

Create an interface to notify in base activity:

interface NetworkChangeListener {
    fun networkStateChanged(boolean: Boolean)
}

Initialise interface in Application:

class YourApplication:Application() {

    companion object {
        lateinit var appContext: Context
    }

    override fun onCreate() {
        super.onCreate()
        appContext = this
    }


    fun initializeNetworkListener(listener:NetworkChangeListener){
        NetworkChangeReceiver.networkChangeListener = listener
    }
}

BasActivity, which implements interface and with the help of MutableLivedata notifies any activity/fragment if network goes off:

class BaseActivity : AppCompatActivity(), NetworkChangeListener {


    private var networkLiveData: MutableLiveData<Boolean> = MutableLiveData()
    private lateinit var snackbar: Snackbar

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setupNetworkState()
    }

    private fun setupNetworkState() {
        networkLiveData.postValue(checkNetworkState())

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

            val connectivityManager: ConnectivityManager =
                this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

            connectivityManager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network?) {
                    super.onAvailable(network)
                    networkLiveData.postValue(checkNetworkState())
                }

                override fun onLost(network: Network?) {
                    super.onLost(network)
                    networkLiveData.postValue(checkNetworkState())
                }
            })


        } else {
            (application as YourApplication).initializeNetworkListener(this@BaseActivity)
        }
    }

    override fun networkStateChanged(boolean: Boolean) {
        networkLiveData.postValue(boolean)
    }


    fun getNetworkStateUpdate(): MutableLiveData<Boolean> {
        return networkLiveData
    }

    fun checkNetworkState(): Boolean {
        return ConnectivityHelper.isConnectedToNetwork()
    }

Now final step in **your any activity/fragment****: In **onCreate() method,

getNetworkStateUpdate().observe(this, object : Observer<Boolean> {
            val snackbar = Snackbar
                .make(
                    mIndMainParentLayout, "You're Offline",
                    Snackbar.LENGTH_INDEFINITE
                )

            override fun onChanged(t: Boolean?) {
                if (!t!!) {
                    snackbar.show()
                } else {
                    snackbar.dismiss()
                }
            }

        })

Upvotes: 1

K-dari
K-dari

Reputation: 216

Register the BroadcastReceiver in onResume method of each of your activities, and unregister in onPause. Now you only register in MainActivity, but MainActivity can't show an AlertDialog if it is in the background.

Upvotes: 0

Gautham Nadar
Gautham Nadar

Reputation: 55

Try this code:

public static boolean isConnectedToInternet(Context context){
    ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null){
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        if (info != null){
            if (info.getType() == ConnectivityManager.TYPE_WIFI){
                return true;
            }else if (info.getType() == ConnectivityManager.TYPE_MOBILE){
                return true;
            }
        }
    }
    return false;
}

if (isConnectedToInternet() {
        Toast.makeText(context, "Internet Connected", Toast.LENGTH_LONG).show();
    }else {
        new SweetAlertDialog(MainActivity.this, SweetAlertDialog.ERROR_TYPE)
                .setTitleText("Oops...")
                .setContentText("No internet! Check your network connection")
                .show();
        Toast.makeText(context, "Internet Connection Lost", Toast.LENGTH_LONG).show();
    }

Upvotes: 0

Related Questions