How to check mobile network state? - android

I'd like to be able to identify an unactivated/disconnected SIM card, i.e,
About phone>SIM status>Mobile Network State>"Disconnected"
Here are some of the things I've tried so far.
telephonyManager.simState == TelephonyManager.SIM_STATE_READY
returns true even in the disconnected scenario.
telephonyManager.dataState != TelephonyManager.DATA_DISCONNECTED
returns false even when mobile data is turned off in an active device.
Can any of the network capabilities (https://developer.android.com/reference/android/net/NetworkCapabilities#constants_1) used for this? Some indicate the connection between the carrier, but I'm unsure which one applies to this scenario.

Related

Android TRANSPORT_CELLULAR network not available if wifi is connected. How do we make it available?

The moment I get on a wifi connection, the cellular network is completely lost even though the cellular network indicator is definitely on.
This is my network request
val request = NetworkRequest.Builder().run {
addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
build()
}
connectivityManager.registerNetworkCallback(request, callback)
I've tried looking in the connectivityManager.allNetworks list and it's no where to be found. Only the wifi network is in there.
What's even weirder is there is one other cellular network that is always there. It does not have the same ID as my cellular network. There's no connection that can be made with it. It never shows up with registerNetworkCallback. The capabilities on it always include "valid" and "internet"
What am I seeing here? Why is my cellular network lost? What is this phantom cellular network?
targetSdkVersion: 29
Device: Galaxy S10 - Android 12
I figured this out.
If you call registerNetworkCallback the above will happen, but if you call requestNetwork with TRANSPORT_CELLULAR,
connectivityManager.requestNetwork(request, callback)
Android will keep the cellular network around. I was so confused because the documentation was so lacking. Once you do that, it will ask you to add the CHANGE_NETWORK_STATE permission.
After this step, the network is available, but you won't be able to make any request with it. You have to call
connectivityManager.bindProcessToNetwork(theCellularNetwork)
to get any connection.
After this is done, the cellular network can be used in tandem with the wifi network. You can even send some traffic to one and some to the other. If you use OkHttp like I do, you just bind the client with the network's socketFactory
val client = OkHttpClient().newBuilder().run {
socketFactory(network.socketFactory)
build()
}
client.newCall(
Request.Builder().url("https://example.com").build()
).execute().let {
Log.i(TAG, "Fetched ${it.body!!.string()}")
}
The cellular network isn't lost, but your app isn't allowed to use it. Once WiFi is connected, everything is forced to use that connection. The only exception to this rule is if your phone has a feature called "Dual Acceleration", which allows the cellular connection to stay active (and obviously, the user would have to enable that feature). Alternatively, you may have a setting in your phone's Developer Options called "Cellular Data Always Active", which will do the same thing.
But needless to say, you can't rely on either of those 2 features being enabled in a production environment. So, just assume that when WiFi is connected, that's the only connection that your app can use

WifiManager.getScanResults() - clarifications (automatic scans, sleep etc)

I would like some clarifications on the behavior of WifiManager.getScanResults(), namely :
When wireless is enabled
Does android scan for access points on a fixed interval ? Can one query/change the interval ? Can one query the time of the last scan ? For a discussion see this answer
What happens when the wireless radio is turned off (sleeps) - while wifi is still enabled - will getScanResults() go on returning the last scan results ? How would one know if it's time for startScan()?
When wireless is disabled
getScanResults() would return the last scan results ? Or an empty List ? Or null (it does return null at times and this is not handled by 90% of the snippets posted in SO) ?
The answer to 1 would be true even after a reboot (the phone booting with wifi off) ?
The reason I ask is I need to get the list of the available access points periodically and I'd rather call getScanResults() at once, than WifiManager.startScan() and then getScanResults() if I really do not have to - as this involves acquiring wifi locks and the like and is rather subtle. I am not also sure how much do the API level and phone hardware come into play.
For a good discussion of difficulties see this answer
When wireless is disabled
getScanResults() will return null...
...even after a reboot (that's to be expected - this would be disputed if it did not return null in the first place)
When wireless is enabled
2.Surprisingly enough getScanResults() will return null after some time (on a Nexus One, Android 2.3.7, Cyanogen mod - but I suspect this is not really relevant). So yes, apparently one has to initiate a scan irrespective of the wireless status
I guess this is true also if the state is WIFI_STATE_DISABLING
I am still interested in the answer in the case wireless is enabled - in particular question 2, if the device is asleep. Google groups won't let me post (hint)
public List getScanResults ()
Added in API LEVEL 1
Return the results of the latest access point scan.
Returns
the list of access points found in the most recent scan. An app must hold ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission in order to get valid results.

Android - no connectivity for my App. How to debug?

I have check for internet connectivity that goes like this:
public static boolean isInternetAvailable(Context ctx)
{
NetworkInfo info = ((ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
if (info == null || !info.isConnected()) return false;
if (info.isRoaming())
{
return Preferences.getIsRoamingAllowed(ctx);
}
return true;
}
It's been working good for all installations so far. Today user came in with a phone where everything worked (browser, email, etc) and it wasn't roaming. But my app due to this check was giving "No connection" error.
Phone is HTC Droid ERIS with 2.1
Anyone saw this issue? Any pointers why?
Ok I have written a test application that gets the activenetwork and all networks and lets me see what is happening, I am about to go out and test this since the anomalies I am seeing happen when switching from one network to the other (as in when you go out of wifi range and into cdma etc)
Couple of things that might help regardless first you can change info.isConnected to the following
if (info == null || !info.isConnectedOrConnecting()) return false;
This makes it a little more robust in that if you are in the middle of switch over you still let the user logon
Second thing is that you said that your app denied login if roaming because your apps allow roaming preference was set to false
return Preferences.getIsRoamingAllowed(ctx);
I think you need to follow a different pattern (just my opinion) first because If the user has disallowed roaming via their settings (phone not your app) and they are on a roaming network then the .getActiveNetwork() will return null, or not connected or not available (in which case the .getReason returns "noroaming")
Personally I would let the phone decide, but if you need to restrict it then he pattern I would follow would be
Set the default to true, but note that it's the first time your activity has started and the user has had no chance to set anything (since no pref's are set this should be easy enough to detect) Detect your network connection, if you have one then also note if they are roaming
Prompt them with an alert dialog which warns them they are currently roaming and Ask them if they want to login now or wait until later
OR
Normal Login if they are not roaming
But in either case offer them the ability to set the "roaming" option the first time instead of having them figure it out themselves.
That would address your catch 22 situation and save you some phone calls, anyway that's a design decision but I think it would work out better for you than your current pattern.
Also I think instead of just telling them there is no connection you might want to tell them why, return an enum instead of a boolean and then format dependent on that.
Finally I am going to test a bit more before my final answer because I am seeing some oddity's in the network state but want to confirm my findings before giving you the results, I need this as well so it was a good time for me to dig into this.

Android detect no data connection

I know there are a few threads on this topic but non of them seem to answer my question. I want to be able to detect when the device has no data connection. I have tried the NetworkInfo route checking if its null, isConnected(), isAvailable() etc. The problem im having is that these work fine (return false or null) when wifi or mobile network are disabled however when they are enabled but there is no signal they return true. Is there any way to detect no data connection due to no signal?
build reciver and catch broadcast
Intent action for network events in android sdk
You could try pinging google.com. If there's no response, you can be fairly sure that there's no connection (unless the user is in a country where it is blocked).
I use ConnectivityManager.getActiveNetworkInfo.isConnectedOrConnecting()
I just tested it 5 minutes ago to make sure, and if everything is working and I then walk away from my house until my router is no longer within range and the network strength indicator on the status bar shows no network, a call to isConnectedOrConnecting() from within an app returns false.
I take it that's not the behavior you are seeing?

Wifi reports as "enabled" even though it's not

I'm not sure if this is a Galaxy Tab specific issue or if I'm not utilizing some relevant method of the WifiManager library, but my application correctly reports that the Wifi is disabled at launch, but then as soon as I enable it, it deems itself as enabled, even though it's still in the process of connecting.
So, I have a thread in which I'm waiting for the enabled state
//at THIS line it claims to be WIFI_STATE_DISABLED so I turn it on with...
wifiManager.setEnabled(true);
//and at this line it reports as 3 (which according to the doc is WIFI_STATE_ENABLED, even though it clearly isn't
while(wifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED || wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING){
but it never never enters the loop, it just jumps right past even though it is NOT enabled
I'm hoping there's some other mechanism that I'm missing, or maybe I'm misunderstanding what "enabled" means?
The WifiManager.WIFI_STATE_ENABLED only tells you, that the wifi device has been turned on. It does not tell you if a connection to a wireless network has been established.
Take a look at the android.net.ConnectivityManager.getActiveNetworkInfo(). This function will return a NetworkState. With the NetworkState.getState() function you can check if a connection is really available.

Categories

Resources