SignalStrength - getSignalStrength() - getLevel() - android

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();
}
}

Related

How to detect Samsung S10 5G is running on 5G network?

Android Q added a new network type, NETWORK_TYPE_NR for 5G which is
not available for Android Pie. Recently released Samsung S10 fully supports 5G. It can show 5G icon on the status bar when it is on the 5G network.
Is it possible for a third-party app to know if Android Pie device on a 5G network or not?
Any help will be appreciated.
The following link is the definition for the new network type. It is not available on the Android Pie branch.
Source code for Pie release
https://android.googlesource.com/platform/frameworks/base/+/refs/heads/pie-release-2/telephony/java/android/telephony/TelephonyManager.java
The latest source code that has NETWORK_TYPE_NR
https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/telephony/java/android/telephony/TelephonyManager.java#2375
I believe they backported the code from Q to Pie as the logic for 5G was implemented at the end of last year in Q (alpha).
So when using
TelephonyManager.getNetworkType()
you will likely get
20 (5G)
EDIT
As per comment below: The network type will be 13 so it doesn't solve the thing.
EDIT
Try using reflection
static boolean isNRConnected(TelephonyManager telephonyManager) {
try {
Object obj = Class.forName(telephonyManager.getClass().getName())
.getDeclaredMethod("getServiceState", new Class[0]).invoke(telephonyManager, new Object[0]);
Method[] methods = Class.forName(obj.getClass().getName()).getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals("getNrStatus") || method.getName().equals("getNrState")) {
method.setAccessible(true);
return ((Integer) method.invoke(obj, new Object[0])).intValue() == 3;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
There is an official documentation to detect 5G on Android 11.
https://developer.android.com/about/versions/11/features/5g#detection
Call TelephonyManager.listen(), passing in LISTEN_DISPLAY_INFO_CHANGED, to determine if the user has a 5G network connection.
as #Hunter suggested you need to use "listen" from telephony manager but if it's api 30+ you need to have READ_PHONE permission granted and listen for LISTEN_DISPLAY_INFO_CHANGED and override onDisplayInfoChanged from PhoneStateListener
(context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager).listen(customPhoneStateListener,PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
The listener should be something like this:
private class CustomPhoneStateListener : PhoneStateListener() {
override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
super.onDisplayInfoChanged(telephonyDisplayInfo)
when (telephonyDisplayInfo.overrideNetworkType) {
//5G
OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO,
OVERRIDE_NETWORK_TYPE_NR_NSA,
OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> setNetworkChange(NETWORK_TYPE_NR)
OVERRIDE_NETWORK_TYPE_LTE_CA -> {
setNetworkChange(19) //LTE+
}
else -> setNetworkChange(telephonyDisplayInfo.networkType)
}
} else {
setNetworkChange(telephonyDisplayInfo.networkType)
}
}
}
Link: https://developer.android.com/about/versions/11/features/5g#detection
Couldn't add this as a comment, but as #Pavel Machala said, looking at the ServiceState class in the AOSP yields the following:
/**
* Get the NR 5G status of the mobile data network.
* #return the NR 5G status.
* #hide
*/
public #NRStatus int getNrStatus() {
final NetworkRegistrationState regState = getNetworkRegistrationState(
NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
if (regState == null) return NetworkRegistrationState.NR_STATUS_NONE;
return regState.getNrStatus();
}
I have extracted the ServiceState.java from SM-G977N firmware and it confirms that they have added
ServiceState.getNrStatus()
5G(NR) is active is if NetworkRegistrationState.NR_STATUS_CONNECTED = 3;

Youtube usage calculation using TrafficStats

Using TrafficStats i was checking the youtube app data usage.In some devices it is working fine but not with many other devices.
I found that from developer site, These statistics may not be available on all platforms. If the statistics are not supported by this device, UNSUPPORTED will be returned.
So in these case how can I get the device app usage ?
I was using
TrafficStats.getUidRxBytes(packageInfo.uid) + TrafficStats.getUidTxBytes(packageInfo.uid);
this is returning -1 everytime.
We can use NetworkStats.
https://developer.android.com/reference/android/app/usage/NetworkStats.html
Please see a sample repo which I got the clue.
https://github.com/RobertZagorski/NetworkStats
We can see a similar stackoverflow question as well.
Getting mobile data usage history using NetworkStatsManager
Then I needed to modify this logic for some particular devices. In these devices the normal method won't return proper usage values. So I modified is as
/*
getting youtube usage for both mobile and wifi.
*/
public long getYoutubeTotalusage(Context context) {
String subId = getSubscriberId(context, ConnectivityManager.TYPE_MOBILE);
//both mobile and wifi usage is calculating. For mobile usage we need subscriberid. For wifi we can give it as empty string value.
return getYoutubeUsage(ConnectivityManager.TYPE_MOBILE, subId) + getYoutubeUsage(ConnectivityManager.TYPE_WIFI, "");
}
private long getYoutubeUsage(int networkType, String subScriberId) {
NetworkStats networkStatsByApp;
long currentYoutubeUsage = 0L;
try {
networkStatsByApp = networkStatsManager.querySummary(networkType, subScriberId, 0, System.currentTimeMillis());
do {
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
networkStatsByApp.getNextBucket(bucket);
if (bucket.getUid() == packageUid) {
//rajeesh : in some devices this is immediately looping twice and the second iteration is returning correct value. So result returning is moved to the end.
currentYoutubeUsage = (bucket.getRxBytes() + bucket.getTxBytes());
}
} while (networkStatsByApp.hasNextBucket());
} catch (RemoteException e) {
e.printStackTrace();
}
return currentYoutubeUsage;
}
private String getSubscriberId(Context context, int networkType) {
if (ConnectivityManager.TYPE_MOBILE == networkType) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.getSubscriberId();
}
return "";
}

Android Get Mobile Data Signal Strength (API <17)

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

How many satellite are used in my every time gps fix?

In my application how can i know how many satellites are used/no. of satellite used for gps fix.
I try below code but it's return zero every time.
public void onGpsStatusChanged(int event)
{
//Log.e("Gps_Status", "From on gps status changed");
if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS)
{
GpsStatus status = m_locationManager._myLocationManager.getGpsStatus(null);
Iterable<GpsSatellite> sats = status.getSatellites();
// Check number of satellites in list to determine fix state
if (sats.iterator().hasNext())
{
GpsSatellite gpsSatellite=(GpsSatellite)sats.iterator().next();
if(gpsSatellite.usedInFix())
{
NO_OF_SATELLITE++;
}
Toast.makeText(this, String.valueOf(NO_OF_SATELLITE), Toast.LENGTH_LONG);
}
//Log.e("Used In FIx", String.valueOf(NO_OF_SATELLITE));
}
Log.v("Used In FIx", String.valueOf(NO_OF_SATELLITE));
// Toast.makeText(this, String.valueOf(NO_OF_SATELLITE), Toast.LENGTH_LONG);
}
Any help on this is highly appreciated .
Thanks
Jalp.
To get the no. of satellites the GPS sees I use this code:
/**
* Set the no. of available satellites.
*/
public void updateSats() {
final GpsStatus gs = this.locationManager.getGpsStatus(null);
int i = 0;
final Iterator<GpsSatellite> it = gs.getSatellites().iterator();
while( it.hasNext() ) {
it.next();
i += 1;
}
this.gpsSatsAvailable = i;
}
and in the GpsStatusListener:
#Override
public void onGpsStatusChanged(final int event) {
switch( event ) {
// ...
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
updateSats();
break;
}
}
I do not check if the sats have been used in the last fix.
Hey finally I found my solution for get no. of satellite used in gps.
For that you have to use MNEA listener which is provided in android.location package which communicate with satellite and return response in their NMEA standard sentence like $GPGSA.
After getting the response you have to parse the sentence and finally your job is done .
Thanks all for your reviews on that.
Jalp.
Answer is simply 3.... How GPS Phones Work

Problem with PhoneStateListener.onSignalStrengthsChanged

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? ((:

Categories

Resources