Broadcast receiver for checking internet connection in android app

后端 未结 21 3184
温柔的废话
温柔的废话 2020-11-21 22:28

I am developing an android broadcast receiver for checking internet connection.

The problem is that my broadcast receiver is being called two times. I want it to get

相关标签:
21条回答
  • 2020-11-21 22:41

    First of all we will make a class that will check the connectivity of the network state. So lets create a class :

    public class AppStatus {
        private static AppStatus instance = new AppStatus();
        static Context context;
        ConnectivityManager connectivityManager;
        NetworkInfo wifiInfo, mobileInfo;
        boolean connected = false;
    
        public static AppStatus getInstance(Context ctx) {
            context = ctx.getApplicationContext();
            return instance;
        }
    
        public boolean isOnline() {
            try {
                connectivityManager = (ConnectivityManager) context
                        .getSystemService(Context.CONNECTIVITY_SERVICE);
    
                NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
                connected = networkInfo != null && networkInfo.isAvailable() &&
                        networkInfo.isConnected();
                return connected;
    
    
            } catch (Exception e) {
                System.out.println("CheckConnectivity Exception: " + e.getMessage());
                Log.v("connectivity", e.toString());
            }
            return connected;
        }
    }
    

    Now Make a new Broadcast receiver class :

    public class ConnectivityReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (AppStatus.getInstance(context).isOnline()) {
    
                Intent intent1=new Intent(context,DisplayAct.class);
                intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent1);
    
    
    
    
            } else {
    
                Toast.makeText(context, "Please !! Make your network ON", Toast.LENGTH_SHORT).show();
    
            }
        }
    }
    

    and Now register your broadcast receiver on manifest:

    <receiver android:name=".ConnectivityReceiver">
                <intent-filter>
                    <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
                </intent-filter>
            </receiver>
    
    0 讨论(0)
  • 2020-11-21 22:43

    Checking internet status every time using Broadcast Receiver:

    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>
    
    0 讨论(0)
  • 2020-11-21 22:44

    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;
    }
    
    0 讨论(0)
  • 2020-11-21 22:45

    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 receiver to call only one time if internet connection available):

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

    UPDATE

    You can use this method to check your connectivity if you want just to check whether mobile is connected with 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 null
        return (netInfo != null && netInfo.isConnected());
    }
    
    0 讨论(0)
  • 2020-11-21 22:45
    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.

    0 讨论(0)
  • 2020-11-21 22:46
    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();
        }
    }
    

    permissions:

     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.INTERNET" />
    
    0 讨论(0)
提交回复
热议问题