Calculated mobile data usage is always less than actual - android

I am trying to calculate mobile data usage so I am using a broadcast that inform me about 3G connection then I run a Service to count data.
The problem is the calculating value is always less than the value calculated by the Android data usage default app.
Here is the code :
long now = TrafficStats.getMobileRxBytes();
long before = now;
do {
now = TrafficStats.getMobileRxBytes() ;
Diffnow = now - before;
SystemClock.sleep(500);
}while ((cm.getActiveNetworkInfo() != null) && (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE));
Log.i(TAG,"delta = "+(float)Diffnow/(1024*1024));

I think that i found the answer
To calculate data usage we must calculate either transmetted and received data so i have to change my code as following :
long now = TrafficStats.getMobileRxBytes()+TrafficStats.getMobileTxBytes();
long before = now;
long Diffnow ;
do {
now = TrafficStats.getMobileRxBytes()+TrafficStats.getMobileTxBytes() ;
Diffnow = now - before;
SystemClock.sleep(500);
}while ((cm.getActiveNetworkInfo() != null) && (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE));
Log.i(TAG,"delta = "+(float)Diffnow/(1024*1024));

Related

How to count app usage time while app is on foreground?

I'm working on an android app for tracking daily app usage. The idea is that a user can set daily time limit for any app and a notification will appear within at most 2 minutes after the limit is exceeded. (The reason for delay: I've created an alarm system using AlarmManager class that will go off every minute to run a JobIntentService which will check whether limit for any app is exceeded)
I've used queryEvents method of UsageStatsManager class to count app usage time.
Here's my code for counting app usage time (I've followed How to use queryEvents):
HashMap<String, Integer> getTimeSpent(Context context, String packageName, long beginTime, long endTime) {
UsageEvents.Event currentEvent;
List<UsageEvents.Event> allEvents = new ArrayList<>();
HashMap<String, Integer> appUsageMap = new HashMap<>();
UsageStatsManager usageStatsManager = (UsageStatsManager)context.getSystemService(Context.USAGE_STATS_SERVICE);
UsageEvents usageEvents = usageStatsManager.queryEvents(beginTime, endTime);
while (usageEvents.hasNextEvent()) {
currentEvent = new UsageEvents.Event();
usageEvents.getNextEvent(currentEvent);
if(currentEvent.getPackageName().equals(packageName) || packageName == null) {
if (currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED
|| currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED) {
allEvents.add(currentEvent);
String key = currentEvent.getPackageName();
if (appUsageMap.get(key) == null)
appUsageMap.put(key, 0);
}
}
}
for (int i = 0; i < allEvents.size() - 1; i++) {
UsageEvents.Event E0 = allEvents.get(i);
UsageEvents.Event E1 = allEvents.get(i + 1);
if (E0.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED
&& E1.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED
&& E0.getClassName().equals(E1.getClassName())) {
int diff = (int)(E1.getTimeStamp() - E0.getTimeStamp());
diff /= 1000;
Integer prev = appUsageMap.get(E0.getPackageName());
if(prev == null) prev = 0;
appUsageMap.put(E0.getPackageName(), prev + diff);
}
}
return appUsageMap;
}
In short the above code counts the time difference of the timestamp when an app goes foreground (UsageEvents.Event.ACTIVITY_RESUMED) and the timestamp when it goes background (UsageEvents.Event.ACTIVITY_PAUSED). Then it adds this difference to the total usage time of the app.
The problem is that the amount of time spent on foreground can't be counted unless the app goes background. So, if usage limit is exceeded, notification won't appear until the app goes background.
Is it actually possible to get foreground time while app is on foreground?
N.B. I've tried queryUsageStats along with UsageStats.getTotalTimeInForeground() but couldn't succeed since queryUsageStats had some other issues not related to this question.
I've solved the issue.
Adding difference of current time and timestamp of current running app going foreground does the trick.
I just added the following code before the return statement:
UsageEvents.Event lastEvent = allEvents.get(allEvents.size() - 1);
if(lastEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED) {
int diff = (int)System.currentTimeMillis() - (int)lastEvent.getTimeStamp();
diff /= 1000;
Integer prev = appUsageMap.get(lastEvent.getPackageName());
if(prev == null) prev = 0;
appUsageMap.put(lastEvent.getPackageName(), prev + diff);
}
It is pretty straightforward, I should have thought about it before posting the question.

Android - UsageStats getTotalTimeInForeground doesn't update current foreground app [duplicate]

I'm working on an android app for tracking daily app usage. The idea is that a user can set daily time limit for any app and a notification will appear within at most 2 minutes after the limit is exceeded. (The reason for delay: I've created an alarm system using AlarmManager class that will go off every minute to run a JobIntentService which will check whether limit for any app is exceeded)
I've used queryEvents method of UsageStatsManager class to count app usage time.
Here's my code for counting app usage time (I've followed How to use queryEvents):
HashMap<String, Integer> getTimeSpent(Context context, String packageName, long beginTime, long endTime) {
UsageEvents.Event currentEvent;
List<UsageEvents.Event> allEvents = new ArrayList<>();
HashMap<String, Integer> appUsageMap = new HashMap<>();
UsageStatsManager usageStatsManager = (UsageStatsManager)context.getSystemService(Context.USAGE_STATS_SERVICE);
UsageEvents usageEvents = usageStatsManager.queryEvents(beginTime, endTime);
while (usageEvents.hasNextEvent()) {
currentEvent = new UsageEvents.Event();
usageEvents.getNextEvent(currentEvent);
if(currentEvent.getPackageName().equals(packageName) || packageName == null) {
if (currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED
|| currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED) {
allEvents.add(currentEvent);
String key = currentEvent.getPackageName();
if (appUsageMap.get(key) == null)
appUsageMap.put(key, 0);
}
}
}
for (int i = 0; i < allEvents.size() - 1; i++) {
UsageEvents.Event E0 = allEvents.get(i);
UsageEvents.Event E1 = allEvents.get(i + 1);
if (E0.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED
&& E1.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED
&& E0.getClassName().equals(E1.getClassName())) {
int diff = (int)(E1.getTimeStamp() - E0.getTimeStamp());
diff /= 1000;
Integer prev = appUsageMap.get(E0.getPackageName());
if(prev == null) prev = 0;
appUsageMap.put(E0.getPackageName(), prev + diff);
}
}
return appUsageMap;
}
In short the above code counts the time difference of the timestamp when an app goes foreground (UsageEvents.Event.ACTIVITY_RESUMED) and the timestamp when it goes background (UsageEvents.Event.ACTIVITY_PAUSED). Then it adds this difference to the total usage time of the app.
The problem is that the amount of time spent on foreground can't be counted unless the app goes background. So, if usage limit is exceeded, notification won't appear until the app goes background.
Is it actually possible to get foreground time while app is on foreground?
N.B. I've tried queryUsageStats along with UsageStats.getTotalTimeInForeground() but couldn't succeed since queryUsageStats had some other issues not related to this question.
I've solved the issue.
Adding difference of current time and timestamp of current running app going foreground does the trick.
I just added the following code before the return statement:
UsageEvents.Event lastEvent = allEvents.get(allEvents.size() - 1);
if(lastEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED) {
int diff = (int)System.currentTimeMillis() - (int)lastEvent.getTimeStamp();
diff /= 1000;
Integer prev = appUsageMap.get(lastEvent.getPackageName());
if(prev == null) prev = 0;
appUsageMap.put(lastEvent.getPackageName(), prev + diff);
}
It is pretty straightforward, I should have thought about it before posting the question.

Compare a set of numbers in string

I am trying to make somekind of version checker for my application.
The idea is to compare the numbers from 2 strings and if 1 set of numbers is bigger then the other a new version has been found.
oldString = 360 some - File v1.52.876 [build 2546]
newString = 360 some - File v1.53.421 [build 2687]
What I need is to compare the set numbers after the 'v' in both strings as there can also be numbers (360) in front of the file, as shown in above example.
Below method checks an arraylist (loadTrackedItems) which contains the files to be checked agains the newly received item (checkItemTrack).
But I am having trouble getting the correct numbers.
Is there a better way to do this?, could somebody be so kind and help a bit.
Thank you in advance.
public static boolean newTrackedVersion(String checkItemTrack) {
final List<String> tracking = new ArrayList<String>(loadTrackedItems);
boolean supported = false;
for (final String u : tracking) {
if (checkItemTrack.contains(u)) {
supported = true;
// get the index of the last 'v' character
int trackindex = checkItemTrack.lastIndexOf("v");
String newItem = checkItemTrack.replaceAll("[a-zA-Z]", "").replace("\\s+", "")
.replaceAll("[-\\[\\]^/,'*:.!><~##$%+=?|\"\\\\()]+", "");
String inList = u.replaceAll("[a-zA-Z]", "").replace("\\s+", "")
.replaceAll("[-\\[\\]^/,'*:.!><~##$%+=?|\"\\\\()]+", "");
long newTrack = Long.parseLong(newItem.trim());
long inTrackList = Long.parseLong(inList.trim());
if (newTrack > inTrackList) {
//Toast.makeText(context,"New version found: " + checkItemTrack, Toast.LENGTH_LONG).show();
Log.w("NEW VERSION ", checkItemTrack);
Log.w("OLD VERSION ", u);
}
break;
}
}
return supported;
}
if you receive only two strings to compare this solution will work try it.
String oldString = "360 some - File v1.52.876 [build 2546]";
String newString = "360 some - File v1.53.421 [build 2687]";
String oldTemp = oldString.substring(oldString.indexOf('v'), oldString.indexOf('[')).trim();
String newTemp = newString.substring(newString.indexOf('v'), newString.indexOf('[')).trim();
int res = newTemp.compareTo(oldTemp);
if(res == 1){
//newString is higher
}else if(res == 0){
//both are same
}else if(res == -1){
//oldString is higher
}

getFromLocation using GPS

Can anyone tell me what is going wrong here. I am trying to obtain the address using reverse geocoding..`
if (locationGPS != null) {
list = geocoder.getFromLocation(locationGPS.getLatitude(),
locationGPS.getLongitude(), 3);
if (list != null) {
if (list.size() > 0) {
strZipcode = list.get(0).getPostalCode();
strAdminArea = list.get(0).getAdminArea();
strLocality = list.get(0).getLocality();
strAddressLine = list.get(0).getAddressLine(0);
Log.d(TAG, "list of address: "+ list);
Log.d(TAG, "Data: "+ mobileDataEnabled);
Log.d(TAG, "Data: "+ mobile);
int count = 0;
while ((strZipcode == null || strAdminArea == null
|| strLocality == null || (strAddressLine == null || strAddressLine == "USA"))
&& count < list.size()) {
strZipcode = list.get(count).getPostalCode();
strAdminArea = list.get(count).getAdminArea();
strLocality = list.get(count).getLocality();
strAddressLine = list.get(count)
.getAddressLine(count);
count++;
}`
This thing works fine and gives out the right address. But sometimes it gives out null for the all of the values which i am trying to retrieve despite the fact that i have a check in place for null values.. Am i missing something here?
Reverse Geocoder does not always return a value. It sounds weird but this is the way it is. F0r example if you hit for address 5 times, you won't be lucky enough to get response for all hits. You may get 3 instead. So workaround may be, instead of hitting geocoder one at a time, try looping your request to 2 or 3 times or more, one of the requests will work hopefully.

recursive + 900 elements + neighbor check = causes stackoverflow

I have a city simulation game and try to find a way to check the flow of our power system.
The basics:
The map for the city is based on tiles (30 by 30 tiles = 900 tiles).
Now i start at a power plant and do a recursive neighbor check (top, left, right, bottom) to check if there is something that will transport the power. If there is something, I start checking this tiles for neighbors, too.
To prevent double checks and/or infinite recursive calls, I fill a ArrayList with processed tiles and check if a new tile was already processed and added to the ArrayList...
Recursively started:
public void updatePowerEnvironment(int id, ArrayList<Integer> elements) {
Log.w("GT", "update env for id: " + id);
int newId = id - GameMap.mMapSize;
if (newId >= 0 && GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
updatePowerEnvironment(newId, elements);
}
newId = id + GameMap.mMapSize;
if (newId < GameMap.mMapCells.size() && GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
updatePowerEnvironment(newId, elements);
}
newId = id - 1;
if (newId >= 0 && GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
updatePowerEnvironment(newId, elements);
}
newId = id + 1;
if (newId < GameMap.mMapCells.size()
&& GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
updatePowerEnvironment(newId, elements);
}
}
If I can trust the log output, no tile was tried to processed twice. That means, that I have no errors in the recursive calls. Which also means, the stack is simply too small.
Does someone have an idea how to avoid the stack limit?
[Update and my code as a result of Erics answer]
public void updatePowerEnvironment(int id, ArrayList<Integer> elements) {
Stack<Integer> toProcess = new Stack<Integer>();
toProcess.push(id);
int mapSize = GameMap.mMapCells.size();
while (!toProcess.empty()) {
id = toProcess.pop();
Log.e("GT", "id to process: " + id);
if (elements.contains(id)) {
continue;
}
int[] neighborIds = computeNeighbors(id);
for (int neighbor : neighborIds) {
if (neighbor < 0 || neighbor >= mapSize) {
continue;
}
if (!GameMap.mMapCells.get(neighbor).mPowerEnabled) {
continue;
}
toProcess.push(neighbor);
}
elements.add(id);
}
}
private int[] computeNeighbors(int id) {
return new int[] {id + GameMap.mMapSize, id - GameMap.mMapSize, id + 1, id - 1};
}
If I understand your problem correctly you are attempting to compute the transitive closure of the "is powered by" relation between two tiles. It is certainly possible to compute a transitive closure non-recursively.
Here's a non-recursive algorithm that computes the transitive closure of a relation in C#. You should be able to adapt that to the language of your choice.
http://blogs.msdn.com/b/ericlippert/archive/2010/02/08/making-the-code-read-like-the-spec.aspx
Note that basically what I'm doing here is avoiding the stack limit by allocating my own stack on the heap. That thing can grow as big as you like. (If you run out of heap memory then you've got bigger problems!)
Note also that it would be wise to choose a data structure that makes the "is a member of?" predicate extremely cheap. An array list of size n is usually O(n) to answer the question "is this element a member of this collection?" which means your algorithm is O(n^2) overall. Can you use a collection like a set or a hash table that has O(1) containment testing?
Also, on a purely "code quality" level, this method could use some work. The fact that there is so much duplicated code in there is a red flag. I would be inclined to write this method like this sketch:
Set<int> PoweredTiles(int powersource)
{
Set<int> result = an empy set;
Stack<int> stack = an empty stack;
stack.Push(powersource);
while (stack is not empty)
{
int current = stack.Pop();
if (result.Contains(current)) continue;
result.Add(current);
int[] neighbours = { compute the neighbours }
foreach(int neighbour in neighbours)
{
if (neighbour is not in range of grid) continue;
if (neighbour is not a power carrier) continue;
stack.Push(neighbour);
}
}
return result;
}
Short, to the point, not recursive, no duplicated code, and O(n).
You just need to convert your recursive implementation into an iterative one (as theory tells us is always possible).
For example, you could:
maintain a queue of cells-to-be-checked
while this queue is not empty, process the front element
to process a cell, do whatever you have to do to the cell itself, then for each of its four nneighbours
if they are not already in the queue, add them to the queue
repeat until the queue is empty
An efficient, recursive algorithm should work provided you do clear the flags (I assume you're simply setting flags on whether a tile has power or not) before doing the recursion. Something like this:
void updateCell(position)
{
for each direction (north, south, east, west) do the following:
-- is there a cell there? (test for edges), if not, exit now;
-- can it be powered?
false: exit now;
true: set powered=true, call updateCell(this position);
}
void updatePowerGrid(start)
{
clearPowerFlags();
set powered=true for start;
updateCell(start);
}
This should work well enough until you use really huge grid sizes.
You can make it iterative. Have two lists, one that keeps track of where you have been, and one that keeps track of where you are currently checking.
Psuedo Code with your code:
While(ToBeChecked is not empty) {
//Note In python i'd be using a copy of the list so I could edit it without
//concequence during the iteration. ie for a in b[:]
for each element in ToBeChecked
updatePowerEnvironment(...);
//Remove element you are checking
removeElementFromToBeChecked(...);
}
public void updatePowerEnvironment(int id, ArrayList<Integer> elements) {
Log.w("GT", "update env for id: " + id);
int newId = id - GameMap.mMapSize;
if (newId >= 0 && GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
//call addElementToBeChecked instead and I beleive the above already
//makes sure it has not already been checked
addElementToBeChecked(newId, elements);
}
newId = id + GameMap.mMapSize;
if (newId < GameMap.mMapCells.size() && GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
addElementToBeChecked(newId, elements);
}
newId = id - 1;
if (newId >= 0 && GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
addElementToBeChecked(newId, elements);
}
newId = id + 1;
if (newId < GameMap.mMapCells.size()
&& GameMap.mMapCells.get(newId).mPowerEnabled
&& !elements.contains(newId)) {
elements.add(newId);
addElementToBeChecked(newId, elements);
}
}
addElementToBeChecked(...) {
ToBeChecked.add();
//Some other stuff if needed
}
removeElemenToBeChecked(...) {
ToBeChecked.remove();
//Some other stuff if needed
}
The very first thing I would try is just to change the search order from North-South-West-East to North-East-South-West. Like this:
public void updatePowerEnvironment(int id, ArrayList<Integer> elements) {
if (!GameMap.ValidCellId(id))
return;
if (!GameMap.mMapCells.get(id).mPowerEnabled)
return;
if (elements.Contains(id))
return;
elements.Add(id);
updatePowerEnvironment(id - GameMap.mMapSize, elements);
updatePowerEnvironment(id + 1, elements);
updatePowerEnvironment(id + GameMap.mMapSize, elements);
updatePowerEnvironment(id - 1, elements);
}
This might reduce the recursion depth, depeding on the maps involved.

Categories

Resources