I'm currently working on an application that needs to know whether the phone has internet connection.
Using Connectivity Manager the app is able to generate an event when there is or there is no network connection. Problem is, I need to be connected to a WI-FI local hotspot for my app, and this WI-FI does not offer internet access. to summarise, ConnectivityManager tells me there is internet connection because i'm connected to this wi-fi, but this wi-fi does not offer a real connection.
Here is the code :
public void onReceive(Context context, Intent intent) {
if(intent == null || intent.getExtras() == null)
return;
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = manager.getActiveNetworkInfo();
if(ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
connected = true;
} else if(intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE)) {
connected = false;
}
notifyStateToAll();
}
Is there a way to specify ConnectivityManager that one special Wi-Fi does not offer internet access?
Related
I want to check if device in connected or not in broadcastReceiver.
below is my code :
public boolean isOnline(Context context) {
NetworkInfo info = (NetworkInfo) ((ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
if (info == null || !info.isConnected()) {
Log.e("UpdateDataReceiver","info: "+info);
return false;
}
return true;
}
Issue with my code:
above function returns me false (even when wifi connected) when BroadcastReceiver fires in background(when app is in background)
and it returns true when app is in foreground.
info: NetworkInfo: type: WIFI[], state: DISCONNECTED/BLOCKED, reason:
(unspecified), extra: (none), roaming: false, failover: false,
isAvailable: true, isConnectedToProvisioningNetwork: false, simId: 0
Device Info: Redmi Note
This is how I'm handling it as it turns out getActiveNetworkInfo will always return you DISCONNECTED/BLOCKED in a specific case even if there is network connection. This is the receive method in the BroadcastReceiver with intent filter ConnectivityManager.CONNECTIVITY_ACTION.
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager conn = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conn.getActiveNetworkInfo();
NetworkInfo intentNetworkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (intentNetworkInfo == null) {
intentNetworkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
}
if (networkInfo == null) {
networkInfo = intentNetworkInfo;
} else {
//when low battery get ActiveNetwork might receive DISCONNECTED/BLOCKED but the intent data is actually CONNECTED/CONNECTED
if (intentNetworkInfo != null && networkInfo.isConnectedOrConnecting() != intentNetworkInfo.isConnectedOrConnecting()) {
networkInfo = intentNetworkInfo;
}
}
//do something with networkInfo object
}
I've searched for better solution but no results. The case I've been able to reproduce 100% on my device (Pixel 7.1.2) is the following:
The device must be on low battery < 15% (other devices <20%)
Wifi is on, app is launched
Send app to background turnoff wifi and go to 3g (or vice versa)
Go back to the app
In that situation the app will report DISCONNECTED/BLOCKED from getActiveNetworkInfo.
If you change connectivity while in app it will be ok but if it is on background it wont. This won't happen while you are debugging because it will be charging the device even if the battery is low.
In the example above EXTRA_NETWORK_INFO in ConnectivityManager and WifiManager is actually same string "networkInfo" but I didn't wan't to risk it if in other Android versions they are different, so it is extra boilerplate.
You can directly use the networkInfo from the intent but I wanted to show here that there is a case where actualNetworkInfo is not the actual network info.
I believe the way you can do this is,
Register a Broadcast Receiver with an IntentFilter of ConnectivityManger.Connectivity_Action
private BroadcastReceiver receiverDataChange;
private void registerData(){
try {
receiverDataChange = new bcr_ToggleData();
IntentFilter filterData = new IntentFilter();
filterData.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(receiverDataChange, filterData);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}}
Then in your Broadcast receiver class
public class bcr_ToggleData extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
int state = telephonyManager.getDataState();
switch (state){
case TelephonyManager.DATA_DISCONNECTED: // off
Log.d("DavidJ", "DISCONNECTED");
break;
case TelephonyManager.DATA_CONNECTED: // on
Log.d("DavidJ", "CONNECTED");
break;
}
}
}
}
This fires off when you go into your settings and turn on/off mobile data.
Hope this helps! :)
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
I found this on this google tutorial: http://developer.android.com/intl/pt-br/training/monitoring-device-state/connectivity-monitoring.html. check it out.
I'm writing an Android application which should react if the phone connects or disconnects to a WIFI network. I registered a BroadcastReceiver for this and it works great. Now with this code I'm able to get the current WIFI ID if the phone is connected to a WIFI:
WifiManager mainWifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo currentWifi = mainWifi.getConnectionInfo();
int id = currentWifi.getNetworkId();
But what if the WIFI disconnects and I want to get the WIFI ID of the last connected WIFI? My problem is that all this is in an BroadcastReceiver. This is allways new created if a new Broadcast comes in so I can not really save some data there. Is there a method or something else with which I can get the last connected WIFI ID?
Forgive me if I'm missing something. You could getSharedPreferences to have a context to access from Broadcast receiver.
This BroadcastReceiver intercepts the android.net.ConnectivityManager.CONNECTIVITY_ACTION, which indicates a connection change. It checks whether the type is TYPE_WIFI. If it is, it checks whether Wi-Fi is connected and sets the wifiConnected flag in the main activity accordingly.
public class NetworkReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connMgr =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
// Checks the user prefs and the network connection. Based on the result, decides
// whether
// to refresh the display or keep the current display.
// If the userpref is Wi-Fi only, checks to see if the device has a Wi-Fi connection.
if (WIFI.equals(sPref) && networkInfo != null
&& networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
// If device has its Wi-Fi connection, sets refreshDisplay
// to true. This causes the display to be refreshed when the user
// returns to the app.
You can find here the sample app.
I am working over a project. In this, I am running a background service, in this their is connection between device and server. I want when device is connected to internet the service gets started and connection gets builtup between server and device and when internet disconnected the connection between server and device also gets disconnected
For this I have to send request to disconnect the connection, but that also requires internet connection that is currently not available.
So I want to disconnect the connection between server and device before internet gets disconnected. For this I need the stage i.e prior to internet disconnected that may be like Going to disconnect internet.
The code I tried is not sufficient for this work
public class NetworkChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
try{
if(netInfo.isConnected() && netInfo != null){
System.out.println("Connected to internet");
context.startService(new Intent(context,MessageService.class));
}
}catch(NullPointerException e){
System.out.println("Not Connected to internet");
context.stopService(new Intent(context,MessageService.class));
}
}
}
Can anyone tell any soln for this?
it is no problem to check if a valid WiFi connection exists. But how can I ensure only this WiFi connection is used for network access?
Assumed following scenario:
I check if a valid WiFi-connection exists (and may be I verify if a working Internet connection exists too)
now this WiFi connection is interrupted
I start transmitting data over network and now the mobile connection is used because WiFi died recently
How can I avoid that?
Check if WiFi connection exists:
ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWifi.isConnected()) {
// Do whatever
}
Source, or use this code snippet:
private static final String DEBUG_TAG = "NetworkStatusExample";
...
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
boolean isWifiConn = networkInfo.isConnected();
networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
boolean isMobileConn = networkInfo.isConnected();
Log.d(DEBUG_TAG, "Wifi connected: " + isWifiConn);
Log.d(DEBUG_TAG, "Mobile connected: " + isMobileConn);
Add a Listener to check if WiFi is still enabled:
public class NetworkReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager conn = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conn.getActiveNetworkInfo();
// Checks the user prefs and the network connection. Based on the result, decides whether
// to refresh the display or keep the current display.
// If the userpref is Wi-Fi only, checks to see if the device has a Wi-Fi connection.
if (WIFI.equals(sPref) && networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
// If device has its Wi-Fi connection, sets refreshDisplay
// to true. This causes the display to be refreshed when the user
// returns to the app.
refreshDisplay = true;
Toast.makeText(context, R.string.wifi_connected, Toast.LENGTH_SHORT).show();
// If the setting is ANY network and there is a network connection
// (which by process of elimination would be mobile), sets refreshDisplay to true.
} else if (ANY.equals(sPref) && networkInfo != null) {
refreshDisplay = true;
// Otherwise, the app can't download content--either because there is no network
// connection (mobile or Wi-Fi), or because the pref setting is WIFI, and there
// is no Wi-Fi connection.
// Sets refreshDisplay to false.
} else {
refreshDisplay = false;
Toast.makeText(context, R.string.lost_connection, Toast.LENGTH_SHORT).show();
}
}
Please read Managing Network Usage for a detailed solution
You can add broad cast receiver for network changes. So whenever wifi get interrupted you will get the notification and you can handle the situation as you wish. You can find more details in the following link http://developer.android.com/training/basics/network-ops/managing.html
You can check by this method that wifi is interrupted or not?
ConnectivityManager networkManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = networkManager.getActiveNetworkInfo();
NetworkInfo wifi = networkManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (wifi.isAvailable() && wifi.isConnected()) {
return true;
}else {
return false;
}
You can add broadcast receiver to lsten for network changes, you can add this method in onReceive() method, and check it, If network chanes, you will receive notification on onReceive() and then you can handle whatever you want as your wish
This is what I would like to do :
=> IF WiFi is enabled AND active, launch an intent (in fact it's a WebView that gets its content=>the instructions of my app on the web)
=> IF NOT, then I would launch another intent so that I don't show a WebView with "Web page not available ... The Web page at http://www.mywebsite.com might be temporarily down or it may have moved ..."
I tought initially to use
if(wifi.isWifiEnabled())
but that does not say if the Wifi connection is ACTIVE or not. It says only that the user has turned the switch on. The device may or may not be connected... Is this correct ?
Then I tried to use :
if (wifi.getConnectionInfo().getSSID()!= null)
but I noticed that it returns a string even if the connection has been lost or has been disabled ... ?
How should I do then ?
wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE);
Intent intent_instructions;
if (wifi.getConnectionInfo().getSSID()!= null){
Log.i("Hub", "WiFi is enabled AND active !");
Log.i("Hub", "SSID = "+wifi.getConnectionInfo().getSSID());
intent_instructions = new Intent(this, Instructions.class);
}else{
Log.i("Hub", "NO WiFi");
intent_instructions = new Intent(this, Instructions_No_WiFi.class);
}
this.startActivity(intent_instructions);
Is there a more general way to test if the device has the connectivity to the internet just before launching an intent ? be it through Wifi, 3G, etc ...
Thanks in advance for your help.
You can use the following code to check for connectivity:
private static boolean isConnected(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = null;
if (connectivityManager != null) {
networkInfo =
connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
}
return networkInfo == null ? false : networkInfo.isConnected();
}
Please make sure that you've registered the android.net.conn.CONNECTIVITY_CHANGE intent in your Manifest, or else, you'll never receive a notification that you're online.
I've been struggling with this issue for the last couple of days and I just now realized that I needed to register CONNECTIVITY_CHANGE and not only WIFI_STATE_CHANGED.
Try android.net.ConnectivityManager.getActiveNetworkInfo(): if it returns null you have no connection; if it returns a NetworkInfo object, you can check the connection's state with NetworkInfo.getState(), and if it's NetworkInfo.State.CONNECTED then you're connected, else you're not.
You can do it as follows:
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)){
Log.d("WIFI", "WIFI has changed");
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1);
Log.d("WIFI", "WIFI State = " + wifiState);
setCurrentWifiState(wifiState);
}
You will get 0,1,2,3 depending on which state the Wifi is in, so for example 2 is connecting, you can check the rest in the documents
In your BroadcastReceiver class:
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)){
boolean connected = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false);
if (connected){
// start your service here
}
}
}
And in your AndroidManifest.xml make sure you register for the android.net.wifi.supplicant.CONNECTION_CHANGE broadcast intent.
<intent-filter >
<action android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" />
</intent-filter>
isConnected() doesnt work fully ok, research something else
final ConnectivityManager connMgr = (ConnectivityManager)
this.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() && wifi.getDetailedState() == DetailedState.CONNECTED){
Toast.makeText(this, "Wifi" , Toast.LENGTH_LONG).show();
}
else if( mobile.isAvailable() && mobile.getDetailedState() == DetailedState.CONNECTED ){
Toast.makeText(this, "Mobile 3G " , Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(this, "No Network " , Toast.LENGTH_LONG).show();
}
this code check if you are with wifi or 3g or nothing , in the case of wifi on but not connected to a net or 3g have signal problem it detect this details, with DetailedStates