I have written an android app which listens to the phone signal strength using PhoneStateListener.SignalStrengthChanged(int asu). The app works perfectly with Android 1.6 and lower, but not with higher versions since onSignalStrengthChanged(int asu) has been deprecated and replaced with onSignalStrengthsChanged(SignalStrength signalStrength).
To make the app compatible with Android 2.0 and above, I have upgraded the app to use the 2.1 API and overridden PhoneStateListener.onSignalStrengthsChanged(SignalStrength signalStrength). I'm testing on a EVO with Android 2.1. The phone type (TelephonyManager.getPhoneType) is CDMA and TelephonyManager.getNetworkType returns "EVDO_A". On this setup, onSignalStrengthsChanged(SignalStrength signalStrength) is never called, but SignalStrengthChanged(int asu) is, but this always returns a signal strength of -1 asu because its been depecated. I need to get the onSignalStrengthsChanged(SignalStrength signalStrength) to work.... does anyone know what I'm doing wrong?
Here's the code:
mSignalListener = new PhoneStateListener(){
#Override
public void onSignalStrengthChanged(int asu){
Log.d(Utils.LOGTAG, "#1. " + String.valueOf(asu));
if (mStrength != asu){
mStrength = asu;
NotifyUI();
}
super.onSignalStrengthChanged(asu);
}
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
Log.d(Utils.LOGTAG, "#2.");
if (signalStrength.isGsm())
mStrength = signalStrength.getGsmSignalStrength();
else{
int strength = -1;
if (signalStrength.getEvdoDbm() < 0)
strength = signalStrength.getEvdoDbm();
else if (signalStrength.getCdmaDbm() < 0)
strength = signalStrength.getCdmaDbm();
if (strength < 0){
// convert to asu
mStrength = Math.round((strength + 113f) / 2f);
}
NotifyUI();
}
super.onSignalStrengthsChanged(signalStrength);
}
};
mTelManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
mTelManager.listen(mSignalListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
I suppose you just register the mSignalListener for PhoneStateListener.LISTEN_SIGNAL_STRENGTHS as well? ((:
Related
I can easily get the sigalStrength in Android via callback
onSignalStrengthsChanged(SignalStrength signalStrength)
and retrieve the signalStrength trough the passed object
int signal_strength = signalStrength.getGsmSignalStrength();
and according to the documentation the value varies between 0 and 39.99
Now I want to display this in my app in an indicator that updates as the signalStrenght varies - exactly what you can see in the statusbar on your phone.
So my question - how can I use the variable for this? If its linear its easy to just use intervalls from 1 - 10, 11 - 20 etc. But I guess its not that easy?
I know I can standardize this value just through a call to ..
int level = signalStrength.getLevel()
That is by calling getLevel then I gets a value between 0 - 4, just as RSSI does for WIFI. But the problem is that it requires api 23 and that means I can only reach approx 40% of the android market.
So - If I do not want to use getLevel, how could I use getGsmSignalStrength() accordingly?
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
int signal_strength = signalStrength.getGsmSignalStrength();
//int level = signalStrength.getLevel(); //api 23
Toast.makeText(context, "signalStrength: " + signal_strength, Toast.LENGTH_SHORT).show();
}
Try following code snippet in your onSignalStrengthsChanged. I achieved it using reflection. It works for all type of network classes. Hope it helps.
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
int level = 0;
try {
final Method m = SignalStrength.class.getDeclaredMethod("getLevel", (Class[]) null);
m.setAccessible(true);
level = (Integer) m.invoke(signalStrength, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
I'have an issue with the BLE scan of Android, I dont get the full name of the scanned devices found, I get only the first letter do you have any idea how to resolve this issue ?
I'm working with a 7.0 Nougat device which is supporting BLE
This is a part of my code :
mBluetoothScanner = mBluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
.build();
if (Build.VERSION.SDK_INT >= 21) {
mScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
messageLog.error("onScanResult");
BluetoothDevice btDevice = null;
if (Build.VERSION.SDK_INT >= 21) {
btDevice = result.getDevice();
messageLog.error("btDevice : " + btDevice.getName() + "|" + btDevice.getAddress() + "|" + Arrays.toString(btDevice.getUuids()));
}
if (btDevice != null && btDevice.getName() != null && !isInDeviceList(btDevice))
mDeviceList.add(btDevice);
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
}
#Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "Error Code: " + errorCode);
}
};
}
With btDevice.getName( ) I only get the first letter of a device scanned, is this my fault or is it coming from the Android BLE API ?
If the peripheral's name does not fit in the Advertising data since it needs to include other data therein, it will only send the prefix of the name over the air. It's nothing you can do about that other than change the advertisement data in the peripheral's firmware.
To get the exact advertisement data, you can investigate the "result.getScanRecord()" ScanRecord in onScanResult.
I am making an app that gets Wi-Fi and Mobile Data information. The Wi-Fi portion of the app is working fine, but I can't seem to get the data part working. I've heard of issues like this on Samsung phones (I'm testing on one), and I need a workaround without going above my API level of 15.
Here is my current code:
class myPhoneStateListener extends PhoneStateListener {
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
if (signalStrength.isGsm()) {
mobileStrength = signalStrength.getGsmSignalStrength();
mobileStrength = (2 * mobileStrength) - 113;
} else {
mobileStrength = signalStrength.getCdmaDbm();
}
}
}
But it returns null.
/**
* Gets the signal level from a <tt>SignalStrength</tt> as a value in the
* range 0-4. This info is hidden from the public API, so this method
* obtains it via reflection.
*
* #return the signal level, or 0 if Google has broken the hack
*/
public static int getSignalLevel(final SignalStrength signal) {
try {
final Method m = SignalStrength.class.getDeclaredMethod("getLevel", (Class[]) null);
m.setAccessible(true);
return (Integer) m.invoke(signal, (Object[]) null);
} catch (Exception e) {
Log.debug(TAG, "Google hates developers", e);
return 0;
}
}
Do you have set the permission in your AndroidManifest.xml file ?
If not, set this to read the phone state.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Yours sincerely,
Flemming
is there any way to handle poor signal problem in application hoe boost network signal? isee appp in playstore like https://play.google.com/store/apps/details?id=com.bosscellular.curtis and https://play.google.com/store/apps/details?id=com.alportela.apptoola.network_booster but dont know how they work how to boost signal progeamically any one know? below is my code which return only network strength but i want to Boost signal strength what do i do?
private static final int EXCELLENT_LEVEL = 51;
private static final int GOOD_LEVEL = 50;
ProgressBar progressBar;
TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
progressBar = (ProgressBar) findViewById(R.id.signalLevel);
textView = (TextView) findViewById(R.id.signalLevelInfo);
Toast.makeText(getApplication(), "Please try again \n Your Connection Signal are Low",
Toast.LENGTH_SHORT).show();
startSignalLevelListener();
}
private void setSignalLevel(int level) {
int progress = (int) ((((float) level) / 31.0) * 100);
String signalLevelString = getSignalLevelString(progress);
progressBar.setProgress(progress);
textView.setText(signalLevelString);
Log.i("signalLevel ", "" + progress);
}
private String getSignalLevelString(int level) {
String signalLevelString = "Weak";
if (level >= EXCELLENT_LEVEL)
{
signalLevelString = "High";
progressBar.getProgressDrawable().setColorFilter(Color.GREEN, Mode.OVERLAY );
}
else if (level <= GOOD_LEVEL)
{
signalLevelString = "Weak";
progressBar.getProgressDrawable().setColorFilter(Color.RED, Mode.OVERLAY );
}
return signalLevelString;
}
private void stopListening() {
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
tm.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}
private void startSignalLevelListener() {
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
int events = PhoneStateListener.LISTEN_SIGNAL_STRENGTH
| PhoneStateListener.LISTEN_DATA_ACTIVITY |
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
PhoneStateListener.LISTEN_SERVICE_STATE;
tm.listen(phoneStateListener, events);
}
private final PhoneStateListener phoneStateListener = new PhoneStateListener() {
#Override
public void onSignalStrengthChanged(int asu) {
setSignalLevel(asu);
super.onSignalStrengthChanged(asu);
}
};
You cannot truly boost your signal strength through software; it is dependent on many variables that are well beyond a software application--including radio firmware, device hardware, proximity to a wireless site, radio interference, and environmental factors.
The applications you referenced appear to just toggle airplane mode on and off, which would force a device to immediately rescan for a new connection. Any "signal boost" that results from these apps is because the device located a stronger signal (likely by connecting to a different wireless site) when the mobile radio was reactivated.
I have used the following code to get the signal strength,
SignalStrengthListener signalStrengthListener;
signalStrengthListener = new SignalStrengthListener();
((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).listen(
signalStrengthListener,
SignalStrengthListener.LISTEN_SIGNAL_STRENGTHS);
and then it is listening for the Signal strength,
private class SignalStrengthListener extends PhoneStateListener {
#Override
public void onSignalStrengthsChanged(
android.telephony.SignalStrength signalStrength) {
// get the signal strength (a value between 0 and 31)
int strengthAmplitude = signalStrength.getGsmSignalStrength();
// do something with it (in this case we update a text view)
// signalStrengthText.setText(String.valueOf(strengthAmplitude));
if (strengthAmplitude > 30) {
signalStrengthText.setText("Good");
// signalStrengthText.setTextColor(getResources().getColor(R.color.good));
} else if (strengthAmplitude > 20 && strengthAmplitude < 30) {
signalStrengthText.setText("Average");
// signalStrengthText.setTextColor(getResources().getColor(R.color.average));
} else if (strengthAmplitude < 20) {
signalStrengthText.setText("Weak");
// signalStrengthText.setTextColor(getResources().getColor(R.color.weak));
}
super.onSignalStrengthsChanged(signalStrength);
}
}
It works good if the sim is present in the device. But when I remove the sim from the device and then check for the signal strength, it still provides some value for the signal strength.
One possible solution, I can think of is to first check, if the sim is present in the device or not and then show the signal strength. But I would like to know an explanation for this weird behaviour and a possible solution for it.
no USIM is required for cell service - only for authentication. else emergency calls would fail.
it's not weird at all... that is common sense, since you do not remove the radio nor disable it.
a simple test: remove the USIM, call emergency services, pretend you were pocket dialing.
Before you're checking the Signal Strength, you could possibly check is the device having SIM card or not (if you're concerned about WIFI network then you need to handle that separately) then check for Signal Strength. you could try something like
public boolean isSimAvailable() {
boolean isAvailable = false;
TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
int simState = telMgr.getSimState();
switch (simState) {
case TelephonyManager.SIM_STATE_ABSENT: //SimState = “No Sim Found!”;
break;
case TelephonyManager.SIM_STATE_NETWORK_LOCKED: //SimState = “Network Locked!”;
break;
case TelephonyManager.SIM_STATE_PIN_REQUIRED: //SimState = “PIN Required to access SIM!”;
break;
case TelephonyManager.SIM_STATE_PUK_REQUIRED: //SimState = “PUK Required to access SIM!”; // Personal Unblocking Code
break;
case TelephonyManager.SIM_STATE_READY:
isAvailable = true;
break;
case TelephonyManager.SIM_STATE_UNKNOWN: //SimState = “Unknown SIM State!”;
break;
}
return isAvailable;
}
///When you get the signal strength, Check like
SignalStrengthListener signalStrengthListener;
if(isSimAvailable()){
signalStrengthListener = new SignalStrengthListener();
((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).listen(
signalStrengthListener,
SignalStrengthListener.LISTEN_SIGNAL_STRENGTHS);
} else {
//alert the user or do other stuff.
}