发现流量统计主流上有两种方式
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性能测试之网络流量(一)