Скорость сетевого соединения с использованием 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;
}