TrafficStats Api android和每日数据使用量的计算

对Android的TrafficStats的两个方法有一个困惑: getUidTxBytes(int uid)和getUidRxBytes(int uid) ,这两个方法返回通过networking传输和接收的这个UID的字节数。但是它的时间单位是多less,是每秒? 如果我想计算每个应用每天传输和接收的数据,我该怎么做。 我有一种方法,将数据存储在SQL中,并不断向数据表中添加数据,这是正确的方法。

这些是计数器“自接口上升”或“自从具有此UID的应用程序开始”以来。 所以说如果你的手机进入“飞行模式”,然后返回,计数器可能会再次从零开始。 如果您需要每秒的值,则需要每秒调用这些函数,然后使用上次调用的增量。 如果增量为负值,则按原样使用该值,即表示计数器再次从零开始。

还有一件事:据我所知,这些计数器只计算TCP / IP。 不是UDP。 所以如果你需要一个非常精确的会计,并且有问题的应用程序使用UDP / IP,或者除了TCP之外的其他任何协议,这些计数器都是错误的。

为了洞察这个function是如何工作的,请看Android的来源,免费提供。 有问题的文件是./frameworks/base/core/jni/android_net_TrafficStats.cpp

这个函数从/proc/uid_stat/[uid]/tcp_snd获取数据。 如果你需要更多的信息,你需要深入Linux内核。

这些计数器包含自上次重新启动以来的字节数。 一些电话这些计数器可能会定期重置,但大多数情况下,他们只能重新启动后重置。 进入飞行模式或在移动和Wi-Fi之间切换不会重置这些计数器。

重要的一点是这些计数器不包括数据包开销,只包括有效负载大小。 所以通常这意味着3-4%的数据可能会被忽略。 但是,如果是数据包有效载荷很小的stream媒体,洪stream或VoIP应用程序,那么数据量可能会大大下降。

有趣的是,getTotalRxBytes(跨移动和Wi-Fi组合的所有接口接收的字节)和getMobileRxBytes(仅在移动接口上接收的字节)包括包括开销的所有字节。 所以基本上,你的应用程序字节数总数将less于你的接口字节数总和,因此less于你的networking运营商为你计费的数据量。

最后一点,大多数stream媒体应用程序不会在自己的UID下logging数据。 它们被logging在system.media UID下。 因此,如果您正在监控YouTube的数据使用情况,那么该应用下实际上只会显示less量数据。 其余的将根据媒体UID(1013)。

在这里,我得到这些具有互联网许可的应用程序,您可以根据需要更改权限名称并获取应用程序。

 ArrayList<AppObject> listApps; public void getAllAppList() { listApps = new ArrayList<AppObject>(); PackageManager p = getPackageManager(); List<ApplicationInfo> packages = p.getInstalledApplications(PackageManager.GET_META_DATA); for (ApplicationInfo applicationInfo : packages) { try { PackageInfo packageInfo = p.getPackageInfo(applicationInfo.packageName, PackageManager.GET_PERMISSIONS); String[] permissions = packageInfo.requestedPermissions; for (String permissionName : permissions) { if (permissionName.equals("android.permission.INTERNET")) { ApplicationInfo appInfo = packageInfo.applicationInfo; AppObject appObject = new AppObject(); appObject.appDrawable = getPackageManager().getApplicationIcon(appInfo); appObject.appName = (String) getPackageManager().getApplicationLabel(appInfo); appObject.dataUsage = getDataUsage(appInfo); listApps.add(appObject); } } } catch (NullPointerException e) { e.printStackTrace(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } Debug.e("APP_SIZE", ":" + listApps.size()); appsAdapter.addAll(listApps); } public String getDataUsage(ApplicationInfo appInfo) { int uid = appInfo.uid; double received = (double) TrafficStats.getUidRxBytes(uid) / (1024 * 1024); double sent = (double) TrafficStats.getUidTxBytes(uid) / (1024 * 1024); double total = received + sent; return String.format("%.2f", total) + " MB"; } 

getUidRxBytes()和getUidTxBytes()分别用于接收和发送的字节。 要监视每个应用程序的数据,只需find每个进程的uid,并find每个进程的相应数据,这将是每个应用程序的数据,然后您可以使用此代码进行计算。

  TextView totData = (TextView)findViewById(R.id.totData); TextView wifiTot = (TextView)findViewById(R.id.wifitotData); TextView wifiTX = (TextView)findViewById(R.id.wifiUpData); TextView wifiRX = (TextView)findViewById(R.id.wifiDownData); TextView mobileTot = (TextView)findViewById(R.id.mobtotData); TextView mobTX = (TextView)findViewById(R.id.mobUpData); TextView mobRX = (TextView)findViewById(R.id.mobDownData); /* * Converting bytes to MB */ long rxBytes = TrafficStats.getTotalRxBytes()/1048576; long txBytes = TrafficStats.getTotalTxBytes()/1048576; long mobUpload = TrafficStats.getMobileTxBytes()/1048576; long mobDown = TrafficStats.getMobileRxBytes()/1048576; long wifiUpload = txBytes-(mobUpload); long wifiDown = rxBytes-(mobDown); wifiRX.setText(Long.toString(wifiDown)); wifiTX.setText(Long.toString(wifiUpload)); long wifitot = wifiUpload+wifiDown; wifiTot.setText(Long.toString(wifitot)); mobTX.setText(Long.toString(mobUpload)); mobRX.setText(Long.toString(mobDown)); long mobTot = mobUpload+mobDown; mobileTot.setText(Long.toString(mobTot)); totData.setText(Long.toString(wifitot+mobTot));