10

对Android的以下两个TrafficStats的方法有混淆: getUidTxBytes(int uid)和getUidRxBytes(int uid),这两个方法返回这个UID通过网络传输和接收的字节数。但是它的时间单位是什么,是每秒吗?如果我想计算每个应用每天发送和接收的数据,我应该怎么做。我想了一种方法,将数据存储在 sql 中并继续向表中添加数据。这是正确的方法吗?

4

4 回答 4

6

这些是“自从接口启动以来”或“自从具有此 UID 的应用程序启动以来”的计数器。因此,假设您的手机进入“飞行模式”然后返回,计数器可能会再次从零开始。如果您需要每秒值,则需要每秒调用这些函数,然后使用上次调用的增量。如果 delta 为负,则直接使用该值,这意味着计数器再次从零开始。

还有一件事:据我所知,这些计数器只计算 TCP/IP。不是UDP。因此,如果您需要非常精确的记帐,并且相关应用程序使用 UDP/IP 或除 TCP 之外的任何其他协议,则这些计数器将是错误的。

要了解此功能的工作原理,请查看免费提供的 Android 源代码。有问题的文件是./frameworks/base/core/jni/android_net_TrafficStats.cpp

该函数从 中获取数据/proc/uid_stat/[uid]/tcp_snd。如果您需要有关此的更多信息,则需要深入研究 Linux 内核......

于 2011-10-03T20:58:00.817 回答
5

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

重要的一点是这些计数器不包括数据包开销,只包括有效负载大小。所以通常这意味着 3-4% 的数据可能下落不明。但是,如果它是数据包有效负载较小的流式传输、洪流或 VoIP 应用程序,则可能会有更多的数据未计入。

有趣的是,getTotalRxBytes(在所有接口上接收到的字节,前移动设备和 Wi-Fi 相结合)和 getMobileRxBytes(仅在移动接口上接收到的字节)包括所有字节,包括开销。因此,基本上,您的应用程序字节总数将少于您的接口字节总数,因此少于您的网络运营商向您收费的数据量。

最后一点,大多数流媒体应用程序不会在自己的 UID 下考虑他们的数据。它们在 system.media UID 下计算。因此,如果您正在监控 YouTube 的数据使用情况,那么该应用程序下实际上只会显示非常少量的数据;其余的将在媒体 UID (1013) 下。

于 2013-04-02T20:49:17.997 回答
2

在这里,我获取了那些具有 Internet 权限的应用程序,您可以更改权限名称并根据需要获取应用程序。

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";

}
于 2016-03-30T10:56:03.197 回答
0

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

    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));
于 2014-02-28T07:31:16.020 回答