26

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, when user connects to a network know if this network has connection to Internet.

The main thing also is know if the WiFi requires Browse Log in Example : Handling Network Sign-On documentation

What I've tried so far?

I've changed my BroadcastReceiver to this

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) {
    if (isNetworkOnline()) {
        Log.d(TAG, String.valueOf(tikis));
        NetTask TeInternet = new NetTask();
        TeInternet.execute("https://www.google.com");


    }
}

The problem is that when I try to connect to a WiFi without Internet Connection the input is this :

D/Network﹕ Internet YAY
D/Network﹕ Internet YAY
D/Network﹕ Internet YAY
D/RequiresLoginBroadcast﹕ 1 //this occurs sometimes

I've changed the Inner Class to this acording with the Handling Network Sign-On documentation

doInBackground() method:

protected Boolean doInBackground(String...params) {
boolean internetAccessExists = false;
String urlToBeAccessed = params[0];
final int TIMEOUT_VALUE_IN_MILLISECONDS = 15000;
URL url;
HttpURLConnection urlConnection = null;
try {
    url = new URL(urlToBeAccessed);
    urlConnection = (HttpURLConnection) url.openConnection();
    //set the respective timeouts for the connection
    urlConnection.setConnectTimeout(TIMEOUT_VALUE_IN_MILLISECONDS);
    urlConnection.setReadTimeout(TIMEOUT_VALUE_IN_MILLISECONDS);
    //the redirect check is valid only after the response headers have been received
    //this is triggered by the getInputStream() method
    InputStream in = new BufferedInputStream(urlConnection.getInputStream());
    if (!url.getHost().equals(urlConnection.getURL().getHost())) {
        internetAccessExists = true;
    }
}
//any sort of exception is considered as a redirect.
//more specific exceptions such as SocketTimeOutException and IOException can be handled as well
catch (Exception e) {
    Log.d(TAG, e.toString());
} finally {
    Log.d(TAG, "Finally");
    urlConnection.disconnect();
}
return internetAccessExists;

What I've looked for so far?

  1. How to detect when WIFI Connection has been established in Android?
  2. Android WIFI How To Detect When Specific WIFI Connection is Available
  3. BroadcastReceiver is not working (detect if wifi is connected)

And more... but saddly I didn't find the correct answer to me.

TL;DR

The thing that I'm trying to do is get the exact event that users connects to a network and then get a good method to detect if I can make a google ping or to check if is there connection to Internet (ONLY WITH WIFI, 3G CONNECTION IS NOT ALLOWED), because the code that I'm using at the moment is failing sometimes...

I think this is a good method to know if there is an Internet Connection since the thing that I want to know is detect if Wifi Requires Browser Login.

We are almost done... But I don't get why is entering on the BroadcastReceiver 4 times or even 5.... and sometimes saying that there's Internet connection when there is not...

Community
  • 1
  • 1
Skizo-ozᴉʞS
  • 18,460
  • 17
  • 76
  • 134
  • Have you read [Broadcast receiver for checking internet connection in android app](http://stackoverflow.com/questions/15698790/broadcast-receiver-for-checking-internet-connection-in-android-app)? – BNK Jul 29 '15 at 01:14
  • does it check if network is connected?..... – Skizo-ozᴉʞS Jul 29 '15 at 01:22
  • You could try to ping google then if it failed, no internet :) – Sheychan Jul 29 '15 at 01:31
  • I think he wanted so ("Secondly, I want to get it called only when network is available. If it is unavailable, I will not want to get notified....) – BNK Jul 29 '15 at 01:37
  • http://www.codeproject.com/Articles/818734/Article-Android-Connectivity – ecle Jul 29 '15 at 01:59
  • Do you want `wifi` connectivity or `internet` connectivity? – Darpan Jul 29 '15 at 03:30
  • @Darpan I want to get the moment when the user is connected to a network and then check if in there is Internet connectivity avaliable you get me? – Skizo-ozᴉʞS Jul 29 '15 at 09:31
  • @Skizo: will look at this today evening ... please send me a reminder :) – Y.S Jul 29 '15 at 11:45
  • @Y.S. Alright :) Did you understand my problem? or shall I explain with more details? (I've edited my question) :P – Skizo-ozᴉʞS Jul 29 '15 at 11:47
  • I understood :) ... more details would surely be helpful though ... – Y.S Jul 29 '15 at 13:15
  • If you need something just let me know i'll explain what you want if you dont understand something:) thanks – Skizo-ozᴉʞS Jul 29 '15 at 19:57
  • Follow http://stackoverflow.com/questions/15698790/broadcast-receiver-for-checking-internet-connection-in-android-app – Ajit Kumar Dubey Jul 30 '15 at 05:54
  • @ajit Didn't work :S – Skizo-ozᴉʞS Jul 30 '15 at 18:41
  • @Y.S. have you checked it? – Skizo-ozᴉʞS Jul 30 '15 at 18:41
  • @Skizo: Sorry for the delay, I've posted an answer, let me know how it goes ... :) – Y.S Jul 31 '15 at 05:22
  • @Y.S. I've edited my question ^^ – Skizo-ozᴉʞS Jul 31 '15 at 10:36
  • @Skizo: sorry for the delay ... please bear with me, I was extremely busy during the week, am looking at the question now. I will find the solution soon ... :) – Y.S Aug 01 '15 at 14:19
  • Can you please re-edit the question and add all your current code ? – Y.S Aug 03 '15 at 06:27
  • @Skizo: sorry for the delay, Skizo. I've been very busy the last few weeks and unfortunately I couldn't give enough attention to your questions. Where have you reached with this ? Any progress ? ... :) – Y.S Aug 07 '15 at 06:11
  • Still entering on the BroadcastReceiver 4 times... and sometimes it doesn't work because there are times that says there are Internet connection when there are not, so this method to know if have internet connection I don't know if it's a good approach.. – Skizo-ozᴉʞS Aug 07 '15 at 08:10
  • Np master do what you must do, when you have time if you want help me:P Also did you check my other [question](http://stackoverflow.com/questions/31761416/connect-to-bluetooth-programmatically)? – Skizo-ozᴉʞS Aug 07 '15 at 08:13

6 Answers6

23

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>
Moonbloom
  • 7,390
  • 3
  • 24
  • 38
10
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>
leo
  • 204
  • 2
  • 15
4

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.

Y.S
  • 29,283
  • 12
  • 91
  • 116
3

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>
Ketan Ramani
  • 3,976
  • 30
  • 39
  • This only detects when user moves from WiFi to data network, right? It doesn't check if it's actually internet connection. I mean you can be connected to a wifi but a Login is needed, will it fire like it's connected? – Skizo-ozᴉʞS Jan 29 '20 at 09:03
2

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);
}
nmirkov
  • 59
  • 6
0

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:

Kenneth Argo
  • 1,551
  • 11
  • 17