Broadcastreceiver to detect network is connected

前端 未结 6 1668
情书的邮戳
情书的邮戳 2020-12-05 02:36

I\'m trying to get the moment where user connects to a network, then I thought a BroadcastReceiver is a good approach... The thing that I would like to do is, w

相关标签:
6条回答
  • 2020-12-05 03:25

    I tried this approach (below) and it worked. Not yet fully tested, but I use similar for receiving battery status. This way there is less code and it does the job.

    private BroadcastReceiver networkReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
                if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
                    Log.d(LOG_TAG, "We have internet connection. Good to go.");
                } else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
                    Log.d(LOG_TAG, "We have lost internet connection");
                }
            }
        }
    };
    
    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(networkReceiver, intentFilter);
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        if (networkReceiver != null)
            unregisterReceiver(networkReceiver);
    }
    
    0 讨论(0)
  • 2020-12-05 03:26
    public abstract class NetworkReceiver extends BroadcastReceiver {
    
    @Override
    public void onReceive(Context context, Intent intent) {
        if (null != intent) {
            State wifiState = null;  
            State mobileState = null;  
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);  
            wifiState = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();  
            mobileState = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();  
            if (wifiState != null && mobileState != null  
                    && State.CONNECTED != wifiState  
                    && State.CONNECTED == mobileState) {  
                // phone network connect success
                gNetwork();
            } else if (wifiState != null && mobileState != null  
                    && State.CONNECTED != wifiState  
                    && State.CONNECTED != mobileState) {  
                // no network
                noNetwork();
            } else if (wifiState != null && State.CONNECTED == wifiState) {  
                // wift connect success
                WIFINetwork();
            }
        }
    }
    

    }

    manifest set

     <receiver android:name=".receiver.AssistantReceiver" >
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>
    
    0 讨论(0)
  • 2020-12-05 03:28

    This is what i'm currently using, and it's working perfectly. I get notified when the internet as connected (not just turned on, when there's an actual connection to the internet).
    It also works for any kind of data connection, but can easily be modified to only accept WiFi, 3G, 4G, etc.

    Code:

    public class NetworkReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
                if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
                    Log.d("Network", "Internet YAY");
                } else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
                    Log.d("Network", "No internet :(");
                }
            }
        }
    }
    

    Manifest:

    <receiver
        android:name=".receivers.NetworkReceiver">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
    </receiver>
    
    0 讨论(0)
  • NetworkChangeReceiver.java

    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.util.Log;
    
    public class NetworkChangeReceiver extends BroadcastReceiver {
    
        private NetworkChangeCallback callback;
    
        public NetworkChangeReceiver(NetworkChangeCallback callback) {
            this.callback = callback;
        }                                               
    
        @Override
        public void onReceive(Context context, Intent intent) {
            boolean status = isNetworkAvailable(context);
            showLog("" + status);
            if (callback != null) {
                callback.onNetworkChanged(status);
            }
        }
    
        private boolean isNetworkAvailable(Context context) {
            try {
                ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
                return (activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting());
            } catch (NullPointerException e) {
                showLog(e.getLocalizedMessage());
                return false;
            }
        }
    
        private void showLog(String message) {
            Log.e("NetworkChangeReceiver", "" + message);
        }
    }
    

    MainActivity.java

    public class MainActivity extends AppCompatActivity implements NetworkChangeCallback { 
    
        private NetworkChangeReceiver networkChangeReceiver;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            networkChangeReceiver = new NetworkChangeReceiver(this);
        }   
    
        @Override
        protected void onPause() {
            super.onPause();
            if (networkChangeReceiver != null) {
                unregisterReceiver(networkChangeReceiver);
            }
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
            registerReceiver(networkChangeReceiver, intentFilter);
        }
    
        @Override
        public void onNetworkChanged(boolean status) {
            Log.e("MainActivity","Status: " + status);
        }
    }
    

    NetworkChangeCallback.java

    public interface NetworkChangeCallback {
        void onNetworkChanged(boolean status);
    }
    

    AndroidManifest.xml

        <receiver android:name=".NetworkChangeReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>
    
    0 讨论(0)
  • 2020-12-05 03:36

    I know this is a bit late but for future readers, the new and suggested method appears to say you should use WorkManager. Part of Android X and supported back to API level 14 it makes detecting and running code on connection change a simple task.

    val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build()
    
    val myWorkRequest =
        OneTimeWorkRequestBuilder<MyWorker>()
            .setConstraints(constraints)
            .build()
    
    WorkManager.getInstance(MyApplication.context).enqueue(myWorkRequest)
    

    And the class that will be executed when the connection is detected:

    class MyWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
        override fun doWork(): Result {
            doThis()
            return Result.success()
        }
    
        private fun doThis() {
            Log.d("ASDF", "::onReceive")
        }
    }
    

    Additional resources:

    • Current library

      Google documentation

    0 讨论(0)
  • 2020-12-05 03:42

    Everything you need is covered in this document: Determining and Monitoring the Connectivity Status. Also have a look at this class: Connectivity.java.

    Briefly, the steps should be as follows:

    1. Intercept the CONNECTIVITY_CHANGE broadcast.

    2. In the onReceive() method, check whether internet connectivity is present, and whether it is Wifi or GPRS.

    This should be easy to implement, and it should work without any problems. In some cases, as with HTC and some Samsung devices, the behavior can vary if the core OS has been modified.

    0 讨论(0)
提交回复
热议问题