Скорость сетевого соединения с использованием TrafficStats

Я работаю над приложением для Android, которое использует подключение к Интернету для работы. Я хочу контролировать скорость сети, используя индикатор, который будет red for poor соединение, yellow for fair а также green for good силы, и покажите его в строке состояния, чтобы пользователь мог знать скорость сети все время при использовании приложения. Я наткнулся на библиотеку TrafficStats, в которой я получу нет. байтов, переданных с использованием TrafficStats.getMobileTxbytes() и нет. байтов, полученных с помощью TrafficStats.getMobileRxbytes() но теперь у меня есть вопрос для решения.

  • TrafficStats даст скорость сети, которая основана на текущей передаче данных. Таким образом, если ничего не будет передано, скажем, в последние 10 секунд, он вернет скорость 0 кбит / с, и наш индикатор будет красным, тогда как фактическая сеть была исправна и должна была быть зеленой.

Я новичок в Android и хочу кое-что понять.

Также есть какой-то другой хороший способ решить эту проблему?

1 ответ

К сожалению, такие данные можно оценить только. В Android нет API, который дает вам среднюю скорость за указанный промежуток времени.

Вот что я сделал для определения средней скорости на основе типа подключения к мобильной сети (и устройства во внешней функции):

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

Однако приведенный выше код будет работать только для мобильной связи. Когда WiFi включен, метод будет другим:

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;
}
Другие вопросы по тегам