TrafficStats Api android and calculation of daily data usage
对以下两种Android TrafficStats方法感到困惑:
getUidTxBytes(int uid)和getUidRxBytes(int uid),
这两种方法返回通过网络为此UID发送和接收的字节数。 但它的时间单位是多少,是每秒?
如果我想计算每个应用每天传输和接收的数据,我该怎么办。 我想过一种方法,在sql中存储数据并继续向表中添加数据。 这是正确的方法吗?
这些是计数器"因为接口上升"或"因为具有此UID的应用程序已启动"。所以说如果你的手机进入"飞行模式"然后再回来,计数器可能会再次从零开始。如果需要每秒的值,则需要每秒调用这些函数,然后使用上次调用的增量。如果delta是负数,只需按原样使用该值,这意味着计数器再次从零开始。
还有一件事:据我所知,这些计数器只计算TCP / IP。不是UDP。因此,如果您需要非常精确的记帐,并且有问题的应用程序使用UDP / IP或TCP之外的任何其他协议,这些计数器将是错误的。
有关此功能的工作原理,请查看免费提供的Android源代码。有问题的文件是
此函数从
这些计数器包含自上次重新引导以来的字节数。一些电话这些计数器可能会定期重置,但大部分时间它们只会在重启后重置。进入飞行模式或在移动和Wi-Fi之间切换不会重置这些计数器。
一个重要的一点是,这些计数器不包括数据包开销,只包括有效负载大小。因此,通常这意味着3-4%的数据可能无法计算。但是,如果它是数据包有效负载很小的流媒体,torrent或VoIP应用程序,则可能会有更多的数据未计入。
有趣的是,getTotalRxBytes(所有接口上的接收字节,移动和Wi-Fi组合)和getMobileRxBytes(仅在移动接口上接收的字节)包括所有字节,包括开销。基本上,您的应用字节数总计将小于您的接口字节数总计,因此小于网络运营商为您收费的数据量。
最后一点,大多数流媒体应用程序不会在自己的UID下考虑他们的数据。它们在system.media UID下计算。因此,如果您要监控YouTube的数据使用情况,那么该应用下只会显示非常少量的数据;其余的将在媒体UID(1013)下。
在这里,我获得了那些拥有互联网许可的应用程序,
您可以根据需要更改权限名称并获取应用程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 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()基本上分别用于接收和发送的字节。要监控每个应用程序的数据,只需找到每个进程的uid并找到每个进程的相应数据,这将是每个应用程序的数据,然后您可以使用此代码进行计算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 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)); |