1

我正在开发一个使用互联网连接来工作的 android 应用程序。我想使用一个red for poor连接yellow for fairgreen for good强度指示器来监控网络速度,并将其显示在状态栏上,以便用户可以知道所有的网络速度使用该应用程序的时间。我遇到了TrafficStats库,我将在其中获得否。使用TrafficStats.getMobileTxbytes()和没有传输的字节数。接收到的字节数,TrafficStats.getMobileRxbytes()但现在我有一个查询要处理。

  • TrafficStats 将提供基于当前数据传输的网络速度。因此,如果在过去 10 秒内没有传输任何内容,它将返回 0kbps 速度,并且我们的指示灯将是红色的,而实际网络很好,它应该是绿色的。

我只是 Android 的新手,在这里想要一些见解。

还有其他解决这个问题的好方法吗?

4

1 回答 1

0

不幸的是,这些数据只能估计。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;
}
于 2016-07-04T11:14:28.837 回答