流量消耗采集(方案:2G/3G/4G/wifi,兼容Android版本)

发现流量统计主流上有两种方式

1.使用系统统计类TrafficStats获取

A. 缺少获取某个app接受和发送的2G/3G/4G流量,不包含wifi,这些API无法满足该需求。

2.通过系统文件解析读取

A. /proc/net/xt_qtaguid/iface_stat_fmt:该文件中已经按照类型统计出了不同类型网络数据的总数,因此获取当前设备的总接受字节数等设备级统计信息,直接分析该文件,能最快获取结果
B. /proc/net/xt_qtaguid/stats:该文件中则是按照uid进行了分类,适合于做更细力度(应用级/线程级)的分析
C. 缺点 Android9.0已经不支持了;

当前我们采用TrafficStats方式

一、TrafficStats方法介绍

static long getMobileRxBytes() //获取通过Mobile连接收到的字节总数,不包含WiFi
static long getMobileRxPackets() //获取Mobile连接收到的数据包总数
static long getMobileTxBytes() //Mobile发送的总字节数
static long getMobileTxPackets() //Mobile发送的总数据包数
static long getTotalRxBytes() //获取总的接受字节数,包含Mobile和WiFi等
static long getTotalRxPackets() //总的接受数据包数,包含Mobile和WiFi等
static long getTotalTxBytes() //总的发送字节数,包含Mobile和WiFi等
static long getTotalTxPackets() //发送的总数据包数,包含Mobile和WiFi等
static long getUidRxBytes(int uid) //获取某个网络UID的接受字节数
static long getUidTxBytes(int uid) //获取某个网络UID的发送字节数

二、解决获取某个app接受和发送的2G/3G/4G流量,不包含wifi

方案:

通过判断当前网络处于2G/3G/4G/wifi来记录;

判断2G/3G/4G网络

相关类ConnectivityManager 、 NetworkInfo 、TelephonyManager
int networkType = NetworkInfo .getSubtype();
TelephonyManager.getNetworkClass(int networkType) ;
由于 TelephonyManager部分方法和常量是隐藏,需要我们自己去更加该类处理

 /**
     * 获取手机网络类型;
     * @param context
     * @return
     */
    public static int getMoblieNetWorkType(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mMobileNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
            if (mMobileNetworkInfo != null && mMobileNetworkInfo.isConnected()) {
                return getNetworkClass(mMobileNetworkInfo.getSubtype());
            }
        }
        return VideoConstants.NETWORK_CLASS.NETWORK_CLASS_UNKNOWN;
    }


    /**
     *
     * 获取手机网络类型;2G/3G/4G
     * @param networkType
     * @return
     */
    public static int getNetworkClass(int networkType) {
        switch (networkType) {
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_GPRS:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_GSM:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_EDGE:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_CDMA:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_1xRTT:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_IDEN:
                return VideoConstants.NETWORK_CLASS.NETWORK_CLASS_2_G;
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_UMTS:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_EVDO_0:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_EVDO_A:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_HSDPA:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_HSUPA:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_HSPA:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_EVDO_B:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_EHRPD:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_HSPAP:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_TD_SCDMA:
                return VideoConstants.NETWORK_CLASS.NETWORK_CLASS_3_G;
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_LTE:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_IWLAN:
            case VideoConstants.NETWORK_TYPE.NETWORK_TYPE_LTE_CA:
                return VideoConstants.NETWORK_CLASS.NETWORK_CLASS_4_G;
            default:
                return VideoConstants.NETWORK_CLASS.NETWORK_CLASS_UNKNOWN;
        }
    }

TelephonyManager常量(自己定义)

public interface VideoConstants {

    public interface VideoCustomStatus {
        int BUFFERING_TIMEOUT = 1;//缓冲超时
    }

    public interface VideoWhat {
        int WHAT_BUFFERING = 1;//缓冲超时消息
    }

    public interface NETWORK_CLASS {
        /**
         * Network Class Definitions.
         * Do not change this order, it is used for sorting during emergency calling in
         * {@link TelephonyConnectionService#getFirstPhoneForEmergencyCall()}. Any newer technologies
         * should be added after the current definitions.
         */
        /**
         * Unknown network class. {@hide}
         */
        public static final int NETWORK_CLASS_UNKNOWN = 0;
        /**
         * Class of broadly defined "2G" networks. {@hide}
         */
        public static final int NETWORK_CLASS_2_G = 1;
        /**
         * Class of broadly defined "3G" networks. {@hide}
         */
        public static final int NETWORK_CLASS_3_G = 2;
        /**
         * Class of broadly defined "4G" networks. {@hide}
         */
        public static final int NETWORK_CLASS_4_G = 3;
    }



    public interface NETWORK_TYPE {
        /*
         * When adding a network type to the list below, make sure to add the correct icon to
         * MobileSignalController.mapIconSets().
         * Do not add negative types.
         */
        /**
         * Network type is unknown
         */
        public static final int NETWORK_TYPE_UNKNOWN = 0;// TelephonyProtoEnums.NETWORK_TYPE_UNKNOWN; // = 0.
        /**
         * Current network is GPRS
         */
        public static final int NETWORK_TYPE_GPRS = 1;//TelephonyProtoEnums.NETWORK_TYPE_GPRS; // = 1.
        /**
         * Current network is EDGE
         */
        public static final int NETWORK_TYPE_EDGE = 2;// TelephonyProtoEnums.NETWORK_TYPE_EDGE; // = 2.
        /**
         * Current network is UMTS
         */
        public static final int NETWORK_TYPE_UMTS = 3;// TelephonyProtoEnums.NETWORK_TYPE_UMTS; // = 3.
        /**
         * Current network is CDMA: Either IS95A or IS95B
         */
        public static final int NETWORK_TYPE_CDMA = 4;// TelephonyProtoEnums.NETWORK_TYPE_CDMA; // = 4.
        /**
         * Current network is EVDO revision 0
         */
        public static final int NETWORK_TYPE_EVDO_0 = 5;// TelephonyProtoEnums.NETWORK_TYPE_EVDO_0; // = 5.
        /**
         * Current network is EVDO revision A
         */
        public static final int NETWORK_TYPE_EVDO_A = 6;// TelephonyProtoEnums.NETWORK_TYPE_EVDO_A; // = 6.
        /**
         * Current network is 1xRTT
         */
        public static final int NETWORK_TYPE_1xRTT = 7;//TelephonyProtoEnums.NETWORK_TYPE_1XRTT; // = 7.
        /**
         * Current network is HSDPA
         */
        public static final int NETWORK_TYPE_HSDPA = 8;//TelephonyProtoEnums.NETWORK_TYPE_HSDPA; // = 8.
        /**
         * Current network is HSUPA
         */
        public static final int NETWORK_TYPE_HSUPA = 9;//TelephonyProtoEnums.NETWORK_TYPE_HSUPA; // = 9.
        /**
         * Current network is HSPA
         */
        public static final int NETWORK_TYPE_HSPA = 10;// TelephonyProtoEnums.NETWORK_TYPE_HSPA; // = 10.
        /**
         * Current network is iDen
         */
        public static final int NETWORK_TYPE_IDEN = 11;//TelephonyProtoEnums.NETWORK_TYPE_IDEN; // = 11.
        /**
         * Current network is EVDO revision B
         */
        public static final int NETWORK_TYPE_EVDO_B = 12;//TelephonyProtoEnums.NETWORK_TYPE_EVDO_B; // = 12.
        /**
         * Current network is LTE
         */
        public static final int NETWORK_TYPE_LTE = 13;// TelephonyProtoEnums.NETWORK_TYPE_LTE; // = 13.
        /**
         * Current network is eHRPD
         */
        public static final int NETWORK_TYPE_EHRPD = 14;// TelephonyProtoEnums.NETWORK_TYPE_EHRPD; // = 14.
        /**
         * Current network is HSPA+
         */
        public static final int NETWORK_TYPE_HSPAP = 15;// TelephonyProtoEnums.NETWORK_TYPE_HSPAP; // = 15.
        /**
         * Current network is GSM
         */
        public static final int NETWORK_TYPE_GSM = 16;// TelephonyProtoEnums.NETWORK_TYPE_GSM; // = 16.
        /**
         * Current network is TD_SCDMA
         */
        public static final int NETWORK_TYPE_TD_SCDMA = 17;//TelephonyProtoEnums.NETWORK_TYPE_TD_SCDMA; // = 17.
        /**
         * Current network is IWLAN
         */
        public static final int NETWORK_TYPE_IWLAN = 18;// TelephonyProtoEnums.NETWORK_TYPE_IWLAN; // = 18.
        /**
         * Current network is LTE_CA {@hide}
         */
        public static final int NETWORK_TYPE_LTE_CA = 19;//TelephonyProtoEnums.NETWORK_TYPE_LTE_CA; // = 19.

        /**
         * Max network type number. Update as new types are added. Don't add negative types. {@hide}
         */
        public static final int MAX_NETWORK_TYPE = NETWORK_TYPE_LTE_CA;
    }
}

参考:

1. Android流量统计
2. https://github.com/facebook/network-connection-class
3. Android性能测试之网络流量(一)

你可能感兴趣的:(流量消耗采集(方案:2G/3G/4G/wifi,兼容Android版本))