0

例如。我有一个 1.5 GB 的数据包。它给出的总和为 2.0 GB 或更多。关于如何每秒获得正确速度的任何想法。

4

1 回答 1

1

TrafficStats.getTotalRxBytes()不返回您的数据包值。它是指自上次启动(打开手机)以来接收到的总字节数(wifi/mobile)。对于移动数据,它将是TrafficStats.getMobileRxBytes(). 更重要的是,这些值会在设备每次重新启动时重置。

我有一个 1.5 GB 的数据包。它给出的总和为 2.0 GB 或更多。

安卓系统对你的数据包一无所知。您一次又一次地添加它。当您TrafficStats.getMobileRxBytes()一次调用时,它会返回自上次启动以来接收到的总移动数据。以下是解释。希望这可以帮助。

// Suppose, you have just rebooted your device, then received 400 bytes and transmitted 300 bytes of mobile data
// After reboot, so far 'totalReceiveCount' bytes have been received by your device over mobile data.
// After reboot, so far 'totalTransmitCount' bytes have been sent from your device over mobile data.
// Hence after reboot, so far 'totalDataUsed' bytes used actually.
long totalReceiveCount = TrafficStats.getMobileRxBytes();
long totalTransmitCount = TrafficStats.getMobileTxBytes();
long totalDataUsed = totalReceiveCount + totalTransmitCount;

Log.d("Data Used", "" + totalDataUsed + " bytes"); // This will log 700 bytes

// After sometime passed, another 200 bytes have been transmitted from your device over mobile data.
totalDataUsed = TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();

Log.d("Data Used", "" + totalDataUsed + " bytes"); // Now this will log 900 bytes

关于如何每秒获得正确速度的任何想法。

您无法通过这种方式获得实际速度。您只能计算并显示一秒钟内接收/发送了多少字节。我认为android中的所有速度计都一样。类似于以下内容:

class SpeedMeter {
    private long uptoNow = 0;
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private ScheduledFuture futureHandle;

    public void startMeter() {
        final Runnable meter = new Runnable() {
            public void run() {
                long now = TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();
                System.out.println("Speed=" + (now - uptoNow)); // Prints value for current second
                uptoNow = now;
            }
        };
        uptoNow = TrafficStats.getMobileRxBytes() + TrafficStats.getMobileTxBytes();
        futureHandle = scheduler.scheduleAtFixedRate(meter, 1, 1, SECONDS);
    }

    public void stopMeter() {
        futureHandle.cancel(true);
    }
}

并像这样使用:

SpeedMeter meter = new SpeedMeter();
meter.startMeter();

尽管此代码并不完美,但它会满足您的需求。

于 2021-06-12T08:32:13.263 回答