I'm developing an application that measure the data traffic recived through mobile data interface (no wifi) from all processes. Additionally this counter have to be related to a date range, i.e. betheen March 1 and April 1.
I had read about TrafficStats class, but in the documentation doesn't mentioned any about from when are the stats.
This is my first question and I really appreciate your help.
Thanks
I had read about TrafficStats class, but in the documentation doesn't mentioned any about from when are the stats.
"From when" should not matter to you. Take a reading at a point in time, take another reading at a later point in time, and the difference between the two is the bandwidth consumed between those two points in time.
Additionally this counter have to be related to a date range, i.e. betheen March 1 and April 1.
You would need to handle this yourself, most likely, checking for the amount of bandwidth consumption every so often (e.g., every 4 hours via AlarmManager), storing the results in a database, and then using that information to determine the bandwidth consumed over extended periods of time.
Related
I am trying to get the exact Data Usage per Day , or by Range of Time in Android
however from what I searched, I cannot found anything that could do this
Something that I tried
TrafficStats
this one will reset all data every time the device is boot, so I
couldn't use it
NetworkPolicyManager
this one require system permission. So, I can't use it
any help would be appreciate
You need to have a service that will periodically call TrafficStats APIs to get current statistics, and store the results. E.g. the delta between two invocations of getMobileTxBytes() is the number of bytes received during that time period.
Of course, if someone just pulls a battery out of their phone, you'll lose statistics since the last invocation of your service. So set the frequency of updates according to your needs (every hour versus every minute).
Short skippable intro:
I work at a rehabilitation hospital that's a couple kilometers from where I live. The hospital pays a bus service that picks the employees up at certain fixed locations. There's this bus driver, that picks us at 7:00. The guy is FREAKISHLY PUNCTUAL. I mean, this guy has to be in the tenth of a second order. The clock turns from 6:59 to 7:00 EXACTLY when he opens the bus door. And I was thinking of recording his punctuality for like 30 days and make a nice Excel spreadsheet for him. Error propagation and everything. He might even get a raise, who knows?
I'll make a simple app to save time in milliseconds, that seems easy enough, there're like half a dozen solutions for that here in Stackoverflow.
So, to the question:
I hit a button on a widget. It gets a time in ms. It saves it on a file (.txt, .csv, whatever)
How would you estimate the mean error of an NTP synchronized Android phone? What's the most precise and exact way to save a timestamp?
Thanks in advance
First thing that comes to mind is that time is relative, in the Einstein kind of way :) So if your reference is an Android phone synchronized with NTP, what is the driver's time reference? What if synchronization or timing somehow gets off, delayed on your phone and you have the impression that he's late one day, when in fact he's precisely on time relative to his reference?
But for the sake of solving the problem i think you can start by assuming he has the same time reference with you: some place in a network. I don't know the details of Android synchronization via time protocols, but i do know i built a so called Network Synchronization API. In your case i think my Java API might be of help. It tries to make a request for the number of milliseconds since the Unix epoch and then reads the response. The feature is that it gives you a framework on which you can estimate your true time compared to the server's by trying to discard network lag.
One thing to bear in mind: the solution above makes a request to my site (a.k.a. GoDaddy servers) which is probably different than the network location Android phones sync with. Feel free to change the request location.
Second thing to bear in mind: this rabbit hole goes deep :) No measurement can be perfect. You can try to achieve human / reasonable precision but it can never be perfect (e.g. there are other unknowns: what if there's a lag in your Android CPU just as you press the button, or what if your own reaction takes a few milliseconds? The moment you press the button is not the same as the moment the doors actually open and my impression is they're at least a few millis apart)
I'm currently writing an Android app that will need to do things such as :
Retrieving sensors data such as
ActivityRecognition data, say every 20-30 seconds
Retrieving GPS data from time to time (e.g. when activity recognition sends that user is using its bike or car), so I'd say a few times per day max for average user. Frequency of GPS data retrieving could be every 5-10 seconds for example.
Of course, this data should be stored somewhere to be, later on, analysed by my app. The analyse part is not the problem here as I do not need a real-time calculation of any kind, so my actual concern is how to store the data efficiently.
So if we consider an average user that will generate about 5000 sensors data + 5000 GPS data :
How to best store this data ? Database ? 1 file per day ? I'd say database for performance issue and simplicity of use, but I'm not sure it's very good practice to open/close a database connection every 10/20 seconds to add just one line of data. Also, a journaled file (one per day) could be a good idea but I think this is pretty bad for a performance point of view, even using serialization ?
Will storing these 10000 data degrade battery life much more than just retrieving sensors (ActivityRecognition, GPS) data without storage ? I mean, it seems to me that it will be a bit overconsuming, but in the same time GPS is already using so much battery...
Is there another way to do that ?
Also thought of in-memory storage then every few minutes it could be put in hard storage (SQLite, files), but I'm not sure this is a good idea in terms of safely keeping the data...
Thanks in advance
Compared to the GPS battery consumption, the reading and writing in the database will consume almost nothing (it is flash storage, after all), so no worries there. The database would be the best option to store this data in my opinion and I don't see a problem in creating a single entry every 10 or 20 seconds.
Also thought of in-memory storage then every few minutes it could be
put in hard storage (SQLite, files), but I'm not sure this is a good
idea in terms of safely keeping the data...
This is a very good idea.
I have it done this way, and most systems that deal with files do it that way (called a buffer).
If your app crashes due a bug, some data will be lost, depending on the buffer size.
In all other cases (device will shut down, user terminates app) you have time to write (flush) the buffer.
Just an short additional note.
Other than shutting down peripherals, not really an option in your case, maximize the length of time the processor is inactive. (This is not the same as minimizing the length of time the process is active.) This allows the processor to drop into lower sleep states (called C-states). The deeper the sleep state, the more power savings.
In a general sense, this means
no polling; use interrupts instead,
if you need to periodically wake up to see if anything needs to
be done, make sure your interrupt period is the maximum allowable.
(Contrary to current practice, waking up every 10 ms does not
improve your responsiveness when the average event happens every 500
ms.)
This also applies to peripherals, as they drop into sleep states also when not active (Called D-states).
Minimize the number of cloud accesses you do.
Maximize the length of time between cloud accesses.
I'm trying to synchronize the timestamps between multiple Android devices so I can kick off a task at the same time. I figure that I can use Timer and set a Date based on System.currentTimeMillis(), but the problem seems to be that the timestamps of multiple devices are just far enough apart from each other that I'm not getting the precision I want.
I'm looking at somewhere in the range of 50-100 ms, if possible. One idea I had was to use Android Beam to send one device's timestamp to the other device and then calculate a delta, but it turns out that I have to get the timestamp before the message is actually sent and received (i.e., the longer a user waits to send, the bigger the delta will be), which makes that scheme completely fall apart.
How can I sync up two or more devices so that their internal clocks will be no more than 100 ms apart from each other? Is this even possible without using an external server that keeps time?
Any other suggestions for techniques to do something across multiple devices as close to simultaneously as possible would also be welcome.
Why not use the GPS time? The time tags from GPS are pretty accurate.
You could agree on all devices on a certain time and then start it when the GPS tells you to.
Essentially, you have two choices: the simple way or the hard way.
The simple way is to use a single external source for time signals, such NIST, another internet source, or GPS as #Stefan suggests. Internet sources use NTP, see this Java NTP client question.
The hard way is to do Clock synchronization between the devices.
Android GPS hardware generally have only seconds precision. The three last timestamp digits of milliseconds float number are 000.
I am struggling with the same issue right now. I tried gps time, but I cannot guarantee that the user will have gps signal indoors.
My solution was to have all devices retrieve the time from a nist server and then just add or subtract the time difference with System.currentTimeMillis()
If the devices are rooted you could try to sync the clocks.
https://play.google.com/store/apps/details?id=ru.org.amip.ClockSync&hl=en
I would like to get some help about getting 3G data statistics between a date interval.
As far as I know, I should use TrafficStats (Android api 2.2 or higher). I would like to save this information into a SQLite table to show statistics for apps monthly:
Interval date: 01/01/2012 - 31/01/2012
Google Maps - 1,5 Mb
Google Talk - 0,9 Mb
Facebook app - 5,6 Mb
So, I Think I should use a background service. Is this the best way? How should I try to do it in the background service? How do you think I should save the information in SQLite?
(#Pabloku, sorry this answer is coming so late, hopefully it will still be of some help)
Firstly, if you're looking to get traffic stats for individual apps, but only on 3G, it's not possible using public APIs. Android provides the TrafficStats.getUidTxBytes(int) and TrafficStats.getUidRxBytes(int) as public APIs to get the total number of bytes used by apps, but nothing (public) to separate them by interface.
Assuming this doesn't ruin your day, here is a pseudocode algorithm for how to do the rest of what you mention:
Set an alarm if necessary (using AlarmManager) for the start of your range, and store these values (presumably in a DB). Reason: you may need to subtract these existing TrafficStats values as an offset if they are > 0 at the time your date range starts.
Also set an alarm for the end of your range.
Create a BroadcastReceiver to receive ACTION_SHUTDOWN.
In your BroacastReceiver, note down the TrafficStats for your app(s) at shutdown. Reason: TrafficStats will get reset on every reboot.
If this is the first shutdown since start: subtract your initial offset and store that final value (being careful to remove the initial offset)
Otherwise, whatever value is reported will be accurate since boot.
Once your end alarm is triggered, note down the TrafficStats at that point, and add all previously collected stats
(if somehow the phone never rebooted between start and end, just do endStats - startStats).
Good luck!