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");}
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 use getAllCellInfo api to get all the cell Information list , choose the biggest Signal Strength level from the list. And use reflect to set its isRegistered value is true. but the network signal level does not change in my phone.
the code:
List<CellInfo> infos = tel.getAllCellInfo();
if (infos != null) {
for (CellInfo info1 : infos) {
if (info1 instanceof CellInfoLte) {
CellSignalStrengthLte cellSignalStrengthLte = ((CellInfoLte) info1).getCellSignalStrength();
try {
Method setRegistered = ((CellInfoLte) info1).getClass().getMethod("setRegistered", Boolean.TYPE);
if (cellSignalStrengthLte.getLevel() == 4 && !isFirstTime) {
setRegistered.invoke(((CellInfoLte) info1), true);
isFirstTime = true;
} else {
setRegistered.invoke(((CellInfoLte) info1), false);
}
} catch (Exception e) {
}
}
}
}
Is there any way to let my phone use the cell that has biggest signal level ?
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?
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.