скорость сетевого соединения с помощью TrafficStats

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

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

Я просто новичок в Android и хочу получить некоторые идеи здесь.

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


person the_unknown_spirit    schedule 04.07.2016    source источник
comment
я бы рекомендовал вам пройти через это: github.com/eolwral/OSMonitor один раз.   -  person Amritpal Singh    schedule 04.07.2016
comment
Большинство библиотек не обеспечивают скорость сети, к которой вы подключены. Он обеспечивает скорость передачи данных между вашим устройством и сервером, к которому вы подключены. Поэтому нет смысла отображать состояние сети, если вы не передаете данные. Одна вещь, которую вы делаете, это то, что если ваша скорость передачи данных равна 0, но сеть подключена, отобразите зеленую полосу.   -  person Mohammed Atif    schedule 04.07.2016
comment
@the_unknown_spirit у вас есть какое-нибудь решение, которое я хочу реализовать в своем приложении. пожалуйста, направьте меня, если вы можете спасибо   -  person Khizar Hayat    schedule 26.07.2017


Ответы (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;
    }
}

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

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;
}
person R. Zagórski    schedule 04.07.2016
comment
wifiInfo.getLinkSpeed() возвращает максимальную скорость протокола, а не текущую или среднюю скорость, поэтому вы будете получать одно и то же значение при каждом вызове. - person Mark Brown; 17.10.2019