eg. I have a 1.5 GB data pack. It gives the total sum of 2.0 GB or more than that . any idea about how to get correct speed every second.

1

There are 1 answers

5
Ananta Raha On BEST ANSWER

TrafficStats.getTotalRxBytes() does not return your data pack value. It refers to the total received bytes (either wifi/mobile) since the last boot (turning ON phone). For mobile data, it will be TrafficStats.getMobileRxBytes(). More importantly, these values get reset in every reboot of device.

I have a 1.5 GB data pack. It gives the total sum of 2.0 GB or more than that .

The android system does not know anything about your data pack. You are adding it again and again. When you call TrafficStats.getMobileRxBytes() at a moment, it returns total mobile data received upto this moment since last boot. Following is an explanation. Hope this helps.

// 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

any idea about how to get correct speed every second.

You cannot get actual speed this way. You can only calculate and show how much bytes have been received/transmitted in a second. All the speed meters in android do the same I think. Something like the following:

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);
    }
}

And use like this:

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

Although this code is not perfect, however it will suit your needs.