How do I detect when the GSM signal strength is low and the cellular network is lost?
What about dual SIM devices?
Android: how to detect “no carrier” SIM card mode ?
The PhoneStateListener class is designed to serve this purpose. When using it, you can get callbacks when the GSM signal bound to your current provider is changing.
Make sure you have the following android.intent.action.PHONE_STATE set in your manifest file.
Next, you'll need to invoke the TelephonyManager and bind your PhoneStateListener to it :
TelephonyManager telManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
telManager.listen(this.phoneListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
You can implement your PhoneStateListener as such :
private final PhoneStateListener phoneListener = new PhoneStateListener() {
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
Log.d("onSignalStrengthsChanged", "The new singal strength is "
+ signalStrength.getGsmSignalStrength());
}
};
GSM signal strengths values are defined in TS 27.007 8.5. Basically a value of 0 is low, a value of 31 is good, and a value of 99 means not known or not detectable. Valid values are (0-31, 99) as stated in the Android Developers manual.
The above covers GSM signals, so if you are only interested in GSM signals, stick to my previous example. If you might be interested in stating whether a data network is available or not due to a lack of signal strength, you can also get other signal values for all the available data networks :
SignalStrength.getCdmaDbm() returns the RSSI value in dBm for CDMA networks.
SignalStrength.getEvdoDbm() returns the RSSI value in dBm for Evdo networks.
You can know what is the type of the current data network by calling the TelephonyManager.getNetworkType() method.
What about dual SIM devices ?
I don't know, never worked on them. However I don't see why the above may not be applicable to multi-SIM devices. It should be working as such.
Related
I want to detect if a phone has a slow internet connection or high-speed internet.
Now they have deprecated NetworkInfo and suggesting that we should use ConnectivityManager#getNetworkCapabilities using this I am able to get the signal strength but not able to figure out how to use integer value returned by networkCapabilities.getSignalStrength()
It is returning an Integer value I am getting these values (-39, -71, -31).
My question is how should we define that signal strength is good/poor.
Here is my code to get Signal Strength:
ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
Network activeNetwork = cm.getActiveNetwork();
NetworkCapabilities networkCapabilities = cm.getNetworkCapabilities(activeNetwork);
int signalStrength = networkCapabilities.getSignalStrength();
First this is a directive approach rather than being a direct answer to the question.
int signalStrength = networkCapabilities.getSignalStrength();
Doc:
This is a signed integer, with higher values indicating a stronger signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units reported by wifi code.
This means that signalStrength holds a value that is relevant to the signal bearer; for instance if the bearer is WiFi, then the signalStrength will reflect the same WiFi RSSI units.
RSSI, or “Received Signal Strength Indicator,” is a measurement of how well your device can hear a signal from an access point or router. It’s a value that is useful for determining if you have enough signal to get a good wireless connection.
So, you need to map those units to some quality gauge to know whether the signal is weak/strong. This is communication/signal dependent rather than a programming point of view... This thread and also this one may help you for that in case of WiFi bearer.
But you need to customize this quality level for other types of signal bearers the same-wise according to their RSSI units.
GSM signal for instance you may use CellSignalStrengthGsm which has getRssi()
CellSignalStrengthLte is for LTE and so on.
You may also get the level of signal strength from the android.telephony API's SignalStrength class... there is a getLevel() method which returns an integer from 0 to 4 representing the general signal quality. Here you can find a listener to that.
I simply want to check if my device is receiving GSM signals or not. I know about SignalStrength class and its getGsmSignalStrength(). I have worked with PhoneStateListener and onSignalStrengthsChanged().
But even where I am not receiving any signals, I still get greater than 0 GSM signals strength, as shown in the screenshot:
See the signals level, its not even low, its red crossed. And the getGsmSignalStrength() returned me 16. (Current is a different number, please ignore it.)
If you are only interested in the GSM signal from your operator then use getMnc() from CellIdentityGsm to establish if the signal you are measuring is valid.
If you want the GSM signal only when the device is in service (ie successfully connected to a network) then use the ServiceState checker to establish what state the device is in.
As per above comments, the symptoms indicate that you are measuring other operators' GSM signals.
What is the easiest way to check the network speed in android on both mobile and wifi connection? Is there a better solution than downloading a file from the network and doing some calculations manually on the basis of that.
You can check that whether internet connectivity is available on WiFi or not.
If it is unavailable on WiFi then you can ask user to disable WiFi or change WiFi settings.
Another approach is that you manually get signal strength for WiFi and Mobile Network:
To get WiFi's signal strength:
WifiManager wifiManager = (WifiManager) this
.getSystemService(Context.WIFI_SERVICE);
int wifiSpeed = wifiManager.getConnectionInfo().getRssi();
Log.d("SignalStrength", "wifi" + wifiSpeed);
To get Mobile's signal strength:
MyPhoneStateListener MyListener = new MyPhoneStateListener();
TelephonyManager Tel = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Tel.listen(MyListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
And make a listener for Signal strength change:
private class MyPhoneStateListener extends PhoneStateListener {
/*
* Get the Signal strength from the provider, each time there is an
* update
*/
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
Log.d("SignalStrength", "GSM" + String.valueOf(signalStrength
.getGsmSignalStrength());
}
};
You can get updated signal value and put it in Shared Preference then can compare it with WiFi signal value.
WiFi signal value range from -100 to 0.
0 means good strength and -100 means weak.
Mobile signal strength value is from (0-31,99).
0 means low and 31 means good.
99 not known or not detectable.
In my application, TelephonyManager has a PhoneStateListener set to listen to LISTEN_SIGNAL_STRENGTHS. I get a call to onSignalStrengthsChanged and get the SignalStrength. But since SignalStrength has multiple methods for getting the signal strength, (for cdma, evdo and gsm) I'm not sure which one to use.
How do I correctly determine which of cmda, evdo and gsm methods to use?
For GSM, the signal strength structure has a isGsm flag. If it's true, then you know it's GSM and can ignore the others.
When isGsm is false, apparently the use of cdma and evdo is carrier specific. Some carrier uses cmda for voice, evdo for data or vice versa. In short, there appears to be no way to determine programmatically which one is being used for data. As I'm not an expert on this, I could very well be wrong.
I know how to check if I have internet access (using the code from this post),but is it possible to check if a phone has telephone network access? For example someone might have access to the internet via Wifi but not have phone network access to send SMS or make calls.
In my case, while using a real device (Samsung Galaxy S), I am able to turn of my 3G network (then the phone will detect I am not connected to the internet), but I am still able to make phone calls and send SMS. I guess I must be using some other network...
How do I test whether the phone network is connected? Do I need the TelephonyManager?
Thankyou for your time.
Mel
Sure would you not just use this:
getNetworkType()
boolean hasNetwork = android.telephony.TelephonyManager.getNetworkType() != android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
// True if the phone is connected to some type of network i.e. has signal
The above answer did not work for one of my app users - he was connected to the Network but his NetworkType was unknown. Screenshot: http://dl.dropbox.com/u/5072192/SC20130317-161413.png
I am instead checking for the NetworkOperator field. (From the first answer here What is the correct way of checking for mobile network available (no data connection))
public static boolean isMobileAvailable(Context acontext) {
TelephonyManager tel = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return (tel.getNetworkOperator() != null && !tel.getNetworkOperator().equals(""));
}