I'm trying to read the actual cell signal strength from my Samsung S6, but getDbm() always returns -51b (type is WCDMA).
(I call that function in a loop and every time it is -51.)
TelephonyManager telephonyManager = (TelephonyManager) APIDispatcher.getActivity().getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
for (final CellInfo info : telephonyManager.getAllCellInfo()) {
if (info instanceof CellInfoGsm) {
CellSignalStrengthGsm gsm = ((CellInfoGsm) info).getCellSignalStrength();
result = gsm.getDbm();
Log.i("CellSignalStrengthGsm", "strength:"+result);
} else if (info instanceof CellInfoCdma) {
CellSignalStrengthCdma cdma = ((CellInfoCdma) info).getCellSignalStrength();
result = cdma.getDbm();
Log.i("CellSignalStrengthCdma", "strength:"+result);
} else if (info instanceof CellInfoWcdma) {
CellSignalStrengthWcdma wcdma = ((CellInfoWcdma) info).getCellSignalStrength();
result = wcdma.getDbm();
Log.i("CellSignalStrengthWcdma", "strength:"+result);
} else if (info instanceof CellInfoLte) {
CellSignalStrengthLte lte = ((CellInfoLte) info).getCellSignalStrength();
result = lte.getDbm();
Log.i("CellSignalStrengthLte", "strength:"+result);
}
}
The "SIM Card Status" of my mobile reports -103 dBm (+/- 2 dBm).
I never get a different value other than -51.
I also tried to install a listener with:
telephonyManager.listen(new SignalStrengthListener(), PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
but the callbak is never being called.
I have no idea anymore. Maybe you?
Related
I am developing an Android App to be used in Android OS mobile Point of Sale (POS) terminals (Android 7) that has two SIM Slots. I need the App, upon app start, to first test the signal strength in both SIMs and automatically select to work using the SIM with the best signal strength. Afterwards, to periodically (every 15/30/60 mins according to the chosen settings) check the signal strength again for both SIMS, and automatically switch default SIM for Data to the SIM with the best signal strength.
So far I am able to make the App measure the signal strength in both SIMs, and display them to the user, so as to select the SIM to work with. This is achieved using Cellinfo in telephonyManager function and the following code which I found here:
private static String getSignalStrength (Context context) throws SecurityException {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String strength = "";
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return "";
}
List<CellInfo> cellInfos = telephonyManager.getAllCellInfo(); //This will give info of all sims present inside your mobile
if(cellInfos != null) {
for (int i = 0 ; i < cellInfos.size() ; i++) {
if (cellInfos.get(i).isRegistered()) {
if (cellInfos.get(i) instanceof CellInfoWcdma) {
CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) cellInfos.get(i);
CellSignalStrengthWcdma cellSignalStrengthWcdma = cellInfoWcdma.getCellSignalStrength();
strength += String.valueOf(cellSignalStrengthWcdma.getDbm());
} else if (cellInfos.get(i) instanceof CellInfoGsm) {
CellInfoGsm cellInfogsm = (CellInfoGsm) cellInfos.get(i);
CellSignalStrengthGsm cellSignalStrengthGsm = cellInfogsm.getCellSignalStrength();
strength += String.valueOf(cellSignalStrengthGsm.getDbm());
} else if (cellInfos.get(i) instanceof CellInfoLte) {
CellInfoLte cellInfoLte = (CellInfoLte) cellInfos.get(i);
CellSignalStrengthLte cellSignalStrengthLte = cellInfoLte.getCellSignalStrength();
strength += String.valueOf(cellSignalStrengthLte.getDbm());
} else if (cellInfos.get(i) instanceof CellInfoCdma) {
CellInfoCdma cellInfoCdma = (CellInfoCdma) cellInfos.get(i);
CellSignalStrengthCdma cellSignalStrengthCdma = cellInfoCdma.getCellSignalStrength();
strength += String.valueOf(cellSignalStrengthCdma.getDbm());
}
strength+=";";
}
}
}
return strength;
}
I am now stuck at how to switch the default SIM for data automatically, and without the need for user intervention.
Currently I wanted to check the strength of the signal before starting to upload the data to server on both android and iOS no matter is wifi or cellular connection.
I came across with this code on android:
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
List<CellInfo> cellInfos = telephonyManager.getAllCellInfo(); //This will give info of all sims present inside your mobile
if(cellInfos!=null){
for (int i = 0 ; i<cellInfos.size(); i++){
if (cellInfos.get(i).isRegistered()){
if(cellInfos.get(i) instanceof CellInfoWcdma){
CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) telephonyManager.getAllCellInfo().get(0);
CellSignalStrengthWcdma cellSignalStrengthWcdma = cellInfoWcdma.getCellSignalStrength();
strength = String.valueOf(cellSignalStrengthWcdma.getDbm());
}else if(cellInfos.get(i) instanceof CellInfoGsm){
CellInfoGsm cellInfogsm = (CellInfoGsm) telephonyManager.getAllCellInfo().get(0);
CellSignalStrengthGsm cellSignalStrengthGsm = cellInfogsm.getCellSignalStrength();
strength = String.valueOf(cellSignalStrengthGsm.getDbm());
}else if(cellInfos.get(i) instanceof CellInfoLte){
CellInfoLte cellInfoLte = (CellInfoLte) telephonyManager.getAllCellInfo().get(0);
CellSignalStrengthLte cellSignalStrengthLte = cellInfoLte.getCellSignalStrength();
strength = String.valueOf(cellSignalStrengthLte.getDbm());
}
}
}
return strength;
}
Is this only check for the cellular connection not the wifi connection, how to classify into low, medium, and high strength
I need to get the Network operator names if the phone is dual sim or the whole list of neighbouring Network operator names. when I googled what I found for Network Operator name is this
TelephonyManager tManager = (TelephonyManager) getBaseContext()
.getSystemService(Context.TELEPHONY_SERVICE);
// Get carrier name (Network Operator Name)
String carrierName = tManager.getNetworkOperatorName();
But this wont work for me. How can I achieve this. If not suggest me some solutions. thanks
Fortunately there are several native solutions.
For API >=17:
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
// Get information about all radio modules on device board
// and check what you need by calling #getCellIdentity.
final List<CellInfo> allCellInfo = manager.getAllCellInfo();
for (CellInfo cellInfo : allCellInfo) {
if (cellInfo instanceof CellInfoGsm) {
CellIdentityGsm cellIdentity = ((CellInfoGsm) cellInfo).getCellIdentity();
//TODO Use cellIdentity to check MCC/MNC code, for instance.
} else if (cellInfo instanceof CellInfoWcdma) {
CellIdentityWcdma cellIdentity = ((CellInfoWcdma) cellInfo).getCellIdentity();
} else if (cellInfo instanceof CellInfoLte) {
CellIdentityLte cellIdentity = ((CellInfoLte) cellInfo).getCellIdentity();
} else if (cellInfo instanceof CellInfoCdma) {
CellIdentityCdma cellIdentity = ((CellInfoCdma) cellInfo).getCellIdentity();
}
}
In AndroidManifest add permission:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>
To get network operator you can check mcc and mnc codes:
https://en.wikipedia.org/wiki/Mobile_country_code (general information).
https://clients.txtnation.com/hc/en-us/articles/218719768-MCCMNC-mobile-country-code-and-mobile-network-code-list- (quite full and quite latest list of operators).
For API >=22:
final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
final List<SubscriptionInfo> activeSubscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();
for (SubscriptionInfo subscriptionInfo : activeSubscriptionInfoList) {
final CharSequence carrierName = subscriptionInfo.getCarrierName();
final CharSequence displayName = subscriptionInfo.getDisplayName();
final int mcc = subscriptionInfo.getMcc();
final int mnc = subscriptionInfo.getMnc();
final String subscriptionInfoNumber = subscriptionInfo.getNumber();
}
For API >=23. To just check if phone is dual/triple/many sim:
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if (manager.getPhoneCount() == 2) {
// Dual sim
}
I have a method which returns cell id for LTE device, but on some devices it is returning -1. Here is the method:
public int getCellId() {
int cellId = Integer.MAX_VALUE;
CellInfo cellInfo = null;
List<CellInfo> allCellInfo = telephonyManager.getAllCellInfo();
if(allCellInfo!= null && allCellInfo.size()>0)
cellInfo = allCellInfo.get(0);
if (cellInfo instanceof CellInfoLte) {
CellInfoLte cellInfoLte = (CellInfoLte) cellInfo;
if (cellInfoLte != null) {
cellId = cellInfoLte.getCellIdentity().getCi();
}
}
return cellId;
}
You have it implemented correctly, unfortunately not all manufacturers implement all the Android APIs correctly, especially around the telephony area. Sometimes all the LTE values will be -1 also, sometimes just the CI.
I am building an android app that should send sms. When sending SMS I want to check if signal strength is enough to send sms. When not then the app should build a listener that listens for signal strength and send sms as soon as signal is enough.
I think that I only need to check if there is any signal because I believe that only a very low signal is enough to send SMS. Should I use android.telephony.SignalStrength getGsmSignalStrength() at begining to check what is the signal strength. If returned value is 0 then I should create a listener LISTEN_SIGNAL_STRENGTHS? Or is there any better way?
Thanks in forward
Use this:
int dBmlevel = 0;
int asulevel = 0;
List<CellInfo> cellInfoList = tm.getAllCellInfo();
//Checking if list values are not null
if (cellInfoList != null) {
for (final CellInfo info : cellInfoList) {
if (info instanceof CellInfoGsm) {
//GSM Network
CellSignalStrengthGsm cellSignalStrength = ((CellInfoGsm)info).getCellSignalStrength();
dBmlevel = cellSignalStrength.getDbm();
asulevel = cellSignalStrength.getAsuLevel();
}
else if (info instanceof CellInfoCdma) {
//CDMA Network
CellSignalStrengthCdma cellSignalStrength = ((CellInfoCdma)info).getCellSignalStrength();
dBmlevel = cellSignalStrength.getDbm();
asulevel = cellSignalStrength.getAsuLevel();
}
else if (info instanceof CellInfoLte) {
//LTE Network
CellSignalStrengthLte cellSignalStrength = ((CellInfoLte)info).getCellSignalStrength();
dBmlevel = cellSignalStrength.getDbm();
asulevel = cellSignalStrength.getAsuLevel();
}
else if (info instanceof CellInfoWcdma) {
//WCDMA Network
CellSignalStrengthWcdma cellSignalStrength = ((CellInfoWcdma)info).getCellSignalStrength();
dBmlevel = cellSignalStrength.getDbm();
asulevel = cellSignalStrength.getAsuLevel();
}
else{
//Developed as a Cordova plugin, that's why I'm using callbackContext
callbackContext.error("Unknown type of cell signal.");
}
}
}
To get signal strength (in dBm and asu) for all networks (LTE, GSM, CDMA and WCDMA). And then create an if() to limit signal level. Ex.:
if (dBmlevel <= x){ print("You can't sent messages with this current signal");}