1

I am working on an android app that uses internet connectivity to work.I want to monitor the network speed using an indicator which will be red for poor connection, yellow for fair and green for good strength, and show it on the status bar so that the user may know the network speed all the time while using the app.I came across TrafficStats library in which I will get the no. of bytes transmitted using TrafficStats.getMobileTxbytes() and no. of bytes received using TrafficStats.getMobileRxbytes() but now I have a query to deal with.

  • TrafficStats would give network speed which is based on current data transfer. So if nothing is transferred in say last 10 seconds, it would return 0kbps speed and our indicator would be red, whereas actual network was good and it should have been green.

I am just a newbie in Android, and want some insights here.

Also is there some other good way to solve this problem?

Tim
  • 41,901
  • 18
  • 127
  • 145
the_unknown_spirit
  • 2,518
  • 7
  • 34
  • 56
  • i would recommend you to go through this: https://github.com/eolwral/OSMonitor once. – Amritpal Singh Jul 04 '16 at 11:14
  • 1
    Most of the libraries do not provide the speed of the network you are connected to. It provides the data transfer speed between your device and the server you are connected to. So it doesn't make sense to display the network status if you are not transferring the data. One thing that you do that is, if your data transfer rate is 0 but network is connected, then display the green bar. – Mohammed Atif Jul 04 '16 at 11:15
  • @the_unknown_spirit have you got any solution i am looking to implement same feature into my app. please guide me if you can thanks – Khizar Hayat Jul 26 '17 at 13:47

1 Answers1

0

Unfortunately, such data can only be estimated. There is no API in Android, that gives you an average speed in a specified amount of time.

Here is, what I made for specifying the average speed, based on the mobile network connection type (and the unit in external function):

public float mobileNetSpeed(Context context) {
    TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    int networkType = tm.getNetworkType();
    float netSpeed = getMobileNetworkSpeed(networkType);
    return netSpeed;
}

private Network.NetworkSpeedUnits getMobileNetworkSpeedUnit(int networkType) {
    switch (networkType) {
        case TelephonyManager.NETWORK_TYPE_GPRS:
        case 16: // TelephonyManager.NETWORK_TYPE_GSM:
        case TelephonyManager.NETWORK_TYPE_EDGE:
        case TelephonyManager.NETWORK_TYPE_CDMA:
        case TelephonyManager.NETWORK_TYPE_1xRTT:
        case TelephonyManager.NETWORK_TYPE_IDEN:
        case TelephonyManager.NETWORK_TYPE_UMTS:
            return Network.NetworkSpeedUnits.KBps;
        case TelephonyManager.NETWORK_TYPE_EVDO_0:
        case TelephonyManager.NETWORK_TYPE_EVDO_A:
        case TelephonyManager.NETWORK_TYPE_HSDPA:
        case TelephonyManager.NETWORK_TYPE_HSUPA:
        case TelephonyManager.NETWORK_TYPE_HSPA:
        case TelephonyManager.NETWORK_TYPE_EVDO_B:
        case TelephonyManager.NETWORK_TYPE_EHRPD:
        case TelephonyManager.NETWORK_TYPE_HSPAP:
        case 17: // TelephonyManager.NETWORK_TYPE_TD_SCDMA:
        case TelephonyManager.NETWORK_TYPE_LTE:
        case 18: // TelephonyManager.NETWORK_TYPE_IWLAN:
            return Network.NetworkSpeedUnits.MBps;
        default:
            return Network.NetworkSpeedUnits.KBps;
    }
}

/**
 * Return hypothetical speed of mobile network. This method is an equivalent
 * of {@link TelephonyManager#getNetworkClass()}
 *
 * @param networkType
 * @return network speed by one of the XG type
 */
private float getMobileNetworkSpeed(int networkType) {
    switch (networkType) {
        case TelephonyManager.NETWORK_TYPE_GPRS:
            return 114;
        case 16: // TelephonyManager.NETWORK_TYPE_GSM:
            return 0;
        case TelephonyManager.NETWORK_TYPE_EDGE:
            return 296;
        case TelephonyManager.NETWORK_TYPE_CDMA:
            return 115;
        case TelephonyManager.NETWORK_TYPE_1xRTT:
            return 153;
        case TelephonyManager.NETWORK_TYPE_IDEN:
            return 60;
        case TelephonyManager.NETWORK_TYPE_UMTS:
            return 384;
        case TelephonyManager.NETWORK_TYPE_EVDO_0:
            return 2.46F;
        case TelephonyManager.NETWORK_TYPE_EVDO_A:
            return 3.1F;
        case TelephonyManager.NETWORK_TYPE_HSDPA:
            return 21.6F;
        case TelephonyManager.NETWORK_TYPE_HSUPA:
            return 5.76F;
        case TelephonyManager.NETWORK_TYPE_HSPA:
            return 14;
        case TelephonyManager.NETWORK_TYPE_EVDO_B:
            return 4.9F;
        case TelephonyManager.NETWORK_TYPE_EHRPD:
            return 1.285F;
        case TelephonyManager.NETWORK_TYPE_HSPAP:
            return 42;
        case 17: // TelephonyManager.NETWORK_TYPE_TD_SCDMA:
            return 0;
        case TelephonyManager.NETWORK_TYPE_LTE:
            return 100;
        case 18: // TelephonyManager.NETWORK_TYPE_IWLAN:
            return 0;
        default:
            return 0;
    }
}

However, the code above will only work for mobile connection. When the WiFi is on, the method would be different:

public float getWiFiSpeed(Context context) {
    WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    return getWifiNetworkSpeed(wifiInfo);
}

/**
 * Return general class of wifi network type. Unfortunately, there is no Android API method
 * to do this, link speed in {@link WifiInfo#LINK_SPEED_UNITS "Mbps"} must be used
 * and a maximum speed of wifi class must be compared with the value returned from
 * {@link WifiInfo#getLinkSpeed()}.
 *
 * @param wifiInfo
 * @return network speed by one of the WIFI_DRAFT_X type
 */
private float getWifiNetworkSpeed(WifiInfo wifiInfo) {
    if (wifiInfo == null) {
        return 0;
    }
    int linkSpeed = wifiInfo.getLinkSpeed(); //measured using WifiInfo.LINK_SPEED_UNITS
    return linkSpeed;
}
R. Zagórski
  • 20,020
  • 5
  • 65
  • 90
  • 1
    wifiInfo.getLinkSpeed() returns the protocol's max speed, not the current or average speed, so you will get the same value each time you call it. – Mark Brown Oct 16 '19 at 21:31