*i am get some data like this *
UsageStatsManager usageStatsManager = (UsageStatsManager) this.getSystemService("usagestats");
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -1);
long start = calendar.getTimeInMillis();
long end = System.currentTimeMillis();
List<UsageStats> stats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, start, end);
//Map<String,UsageStats> stats =usageStatsManager.queryAndAggregateUsageStats( start, end);
for (int i = 0; i < stats.size() ; i++)
{
Log.e(TAG,"<<<<"+i+">>>>"+"--------------------------------------------------------------------------");
Log.e(TAG,"Package Name = "+stats.get(i).getPackageName());
printt("First Time Stamp = ",stats.get(i).getFirstTimeStamp());
printt("Last Time Stamp = ",stats.get(i).getLastTimeStamp());
printt("Last Time Used = ",stats.get(i).getLastTimeUsed());
printt("Total Time Used in foreground = ",stats.get(i).getTotalTimeInForeground());
}
but how i calculate and show like this and how to i get app start time and end time from this available data
Related
I have the following code:
Calendar nextSchedule = Calendar.getInstance();
nextSchedule.set(Calendar.HOUR_OF_DAY, 0);
nextSchedule.set(Calendar.MINUTE, 0);
nextSchedule.set(Calendar.SECOND, 10);
nextSchedule.set(Calendar.MILLISECOND, 0);
nextSchedule.add(Calendar.DAY_OF_YEAR, 1);
Calendar cal = Calendar.getInstance();
long diff = nextSchedule.getTimeInMillis() - cal.getTimeInMillis();
long seconds = diff / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
As expected, around 11am it gave me 13/12hours but when doing the following in a widget:
Calendar nextSchedule = Calendar.getInstance();
nextSchedule.set(Calendar.HOUR_OF_DAY, 0);
nextSchedule.set(Calendar.MINUTE, 0);
nextSchedule.set(Calendar.SECOND, 10);
nextSchedule.set(Calendar.MILLISECOND, 0);
nextSchedule.add(Calendar.DAY_OF_YEAR, 1);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, nextSchedule.getTimeInMillis(), pendingIntent);
Around 1:30am, it was still not updated. Only somewhen between 2am and 9am (I was asleep) it got updated.
A similar strange thing happens elsewhere. I have a calendar view (applandeo) with the following code: cvCalendar.setOnDayClickListener(eventDay -> showDateItems(eventDay,lvCalendar));
private void showDateItems(EventDay eventDay, ListView lvCalendar) {
Calendar cal = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal.set(eventDay.getCalendar().get(Calendar.YEAR),eventDay.getCalendar().get(Calendar.MONTH),eventDay.getCalendar().get(Calendar.DATE));
cal2.set(eventDay.getCalendar().get(Calendar.YEAR),eventDay.getCalendar().get(Calendar.MONTH),1);
cal2.add(Calendar.MONTH, -1);
ArrayList<String> items = new ArrayList<>();
String line;
for (ItemsHistoryItem item: Utils.getInstance().itemsHistory) {
if (item.getxDay() < Utils.getInstance().calenderToEpoch(cal2) && item.getyDay() < Utils.getInstance().calenderToEpoch(cal2)) break;
if (item.getxDay() != Utils.getInstance().calenderToEpoch(cal) && item.getyDay() != Utils.getInstance().calenderToEpoch(cal)) continue;
line = item.getItemId() + ": $" + item.getAmount();
if (item.getxDay() == Utils.getInstance().calenderToEpoch(cal))
line += " (x day)";
else
line += " (y day)";
items.add(line);
}
ArrayAdapter<String> lcAdapter = new ArrayAdapter<>(requireActivity(), android.R.layout.simple_list_item_1, items);
lvCalendar.setAdapter(lcAdapter);
}
long calenderToEpoch(Calendar cal2) {
return TimeUnit.MILLISECONDS.toDays(cal2.getTimeInMillis());
}
Basically, the above code scans dates of items and when the user select a certain date, he gets a list of items which dates (x and y) are of that date. When doing so during the day, it works. When doing so in 1:30am (for example), it shifts one day ahead so if the user clicks on 12-oct, he gets the items of 11-oct. Somwhen between 2am and 9am it "shifts" back and works as expected.
Any idea what's wrong here?
I have a suggestion for using alarmmanager properly if you want it to fire exactly at the time you want else it does not fire on time when device is in deep sleep mode and gets delayed:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// use setAlarmClock function of AlarmManager
// but this function will show an alarm icon on statusbar
// if you dont want to show that icon you can use
// setExactAndAllowWhileIdle function but that will not be
// perfectly exact
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// use setExact function of AlarmManager
}
else {
// use set function of AlarmManager
}
Apparently the default timezone for Calendar.getInstance() in my case was GMT+3 so at 3am the items were shown for their dates and the widget was updated. to fix it, I simply did the following:
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
I'm using the NetworkStatsManager class to retrieve the data usage of the apps.
If I provide 01.01.2018 as start time, it shows that my phone has sent out 5,4 GB.
If I provide 01.01.2017, it still shows 5,4 GB.
This lets me assume that there is a limit somehow regarding the start time. The documentation unfortunately does not mention anything regarding this.
So, how much in time can we go back?
Code:
This is the code which retrieves the data using querySummary:
private long[] getBytesSummary(Context context, int networkType, Calendar calendar) {
NetworkStatsManager networkStatsManager = (NetworkStatsManager) context.getSystemService(Context.NETWORK_STATS_SERVICE);
NetworkStats networkStats = null;
try {
networkStats = networkStatsManager.querySummary(
networkType,
Util.getSubscriberId(context, networkType),
calendar.getTimeInMillis(),
System.currentTimeMillis());
} catch (RemoteException e) {
if (debug) Log.e(TAG, "getBytesSummary: " + e.toString());
}
long[] result = new long[2];
long totalRxBytes = 0;
long totalTxBytes = 0;
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
if (networkStats != null) {
while (networkStats.hasNextBucket()) {
networkStats.getNextBucket(bucket);
int uid = bucket.getUid();
long uidRxBytes = bucket.getRxBytes();
long uidTxBytes = bucket.getTxBytes();
if (uidsWithNetworkUsageMap.indexOfKey(uid) < 0) {
long[] uidBytes = new long[2];
uidBytes[0] = uidRxBytes;
uidBytes[1] = uidTxBytes;
uidsWithNetworkUsageMap.put(uid, uidBytes);
} else {
long[] value = uidsWithNetworkUsageMap.get(uid);
value[0] = value[0] + uidRxBytes;
value[1] = value[1] + uidTxBytes;
uidsWithNetworkUsageMap.put(uid, value);
}
totalRxBytes += bucket.getRxBytes();
totalTxBytes += bucket.getTxBytes();
}
networkStats.close();
}
result[0] = totalRxBytes;
result[1] = totalTxBytes;
return result;
}
As you can see above, I give a calendar object to the method.
This is how I get the calendar for the current year:
public static Calendar getCalendarCurrentYear() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_YEAR, 1);
// for 0-12 clocks
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
// for 0-24 clocks
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// calendar.set(Calendar.YEAR, 2017);
Log.i("DataUsage", "getCalendarCurrentYear: " + calendar.getTime());
return calendar;
}
This returns Mon Jan 01 00:00:00 GMT+01:00 2018.
If I set it now to 2017, the result is the same as for 2018.
Am I doing something wrong?
EDIT:
I just did some testing, the limit seems to be 3 months somehow.
Anything greater than 3 months as start time results in the same value.
Can anyone confirm that managed to get it working for more than 3 months from current time?
Or is there any official documentation addressing this?
It shows the data usage since last factory reset of your device.
May be the date that you are providing is older than your factory reset of your device.
hope i was helpful.
Time 1 : 10:30 06/05/2018
Time 2 : 19:45 06/05 2018
I want to pick a random time between these two time. The result may be (13:15 06/05/2018).
I look into Calendar but seem it does not support a method like range(time1, time2)
What is the solution for this case ? Thanks.
I would use something like this.
public static Calendar getRandomTime(Calendar begin, Calendar end){
Random rnd = new Random();
long min = begin.getTimeInMillis();
long max = end.getTimeInMillis();
long randomNum = min + rnd.nextLong()%(max - min + 1);
Calendar res = Calendar.getInstance();
res.setTimeInMillis(randomNum);
return res;
}
if you have API 21+, use ThreadLocalRandom
public static Calendar getRandomTime(Calendar begin, Calendar end){
long randomNum = ThreadLocalRandom.current().nextLong(begin.getTimeInMillis(), end.getTimeInMillis() + 1);
Calendar res = Calendar.getInstance();
res.setTimeInMillis(randomNum);
return res;
}
you should convert your times objects to long first as follows (I suppose that you have two Calendar objects already)
long time1InLong = time1.getTimeInMillis();
long time2InLong = time2.getTimeInMillis();
Then you can use following code to generate random number
Random r = new Random();
long randomTime = r.nextLong(time2InLong - time1InLong) + time1InLong;
Then you can convert this randomTime back to Calendar as follows
// Create a DateFormatter object for displaying date in specified format.
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm dd/MM/yyyy");
// Create a calendar object that will convert the date and time value in milliseconds to date.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(randomTime);
I'm using UsageStatsManager API to get usage statistics for a certain time interval. All works fine if I use the predefined intervals i.e. INTERVAL_DAILY, INTERVAL_WEEKLY, INTERVAL_MONTHLY, INTERVAL_YEARLY. But if I want to view the data for the past 2 or 3 hours, I am getting today's data for the whole day. I have tried using Calendars and System.currentTimeMillis() but that didn't give me filtered results.
Calendar approach :
Calendar startCalendar = Calendar.getInstance();
startCalendar.add(Calendar.HOUR_OF_DAY, -2);
Calendar endCalendar = Calendar.getInstance();
And pass this to queryUsageStats method like this:
usageList = usm.queryUsageStats(interval, startCalendar.getTimeInMillis(), endCalendar.getTimeInMillis());
where interval is INTERVAL_BEST.
System.currentTimeMillis() approach :
long startTime = System.currentTimeMillis() - 7200*1000 // 7200 seconds i.e. 2 hrs
long endTime = System.currentTimeMillis();
Pass this to queryUsageStats just like above :
usageList = usm.queryUsageStats(interval, startTime, endTime);
where interval is again INTERVAL_BEST.
I'd like to know whether it's possible to get data for this duration i.e. less than a day, as the INTERVAL_BEST hasn't been documented properly to include this information. Any help would be appreciated as I'm stuck on this problem.
As UsageStatsManager doc says:
A request for data in the middle of a time interval will include that interval.
It seems that usage data is stored in buckets, and minimum bucket is a day, so you can't query usage stats for period less than a day. Even if you query a one-hour interval for a particular day, usage stats for the whole day is returned.
A little late to the party, but I think this might be useful to some.
You could use the queryEvents(long startTime, long endTime) from UsageStatsManager for achieving the desired result. The method could look like this (inspired by this post):
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public HashMap<String, AppUsageInfo> queryUsageStatistics(Context context, long startTime, long endTime) {
UsageEvents.Event currentEvent;
List<UsageEvents.Event> allEvents = new ArrayList<>();
HashMap<String, AppUsageInfo> map = new HashMap<>();
UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
assert mUsageStatsManager != null;
// Here we query the events from startTime till endTime.
UsageEvents usageEvents = mUsageStatsManager.queryEvents(startTime, endTime);
// go over all events.
while (usageEvents.hasNextEvent()) {
currentEvent = new UsageEvents.Event();
usageEvents.getNextEvent(currentEvent);
String packageName = currentEvent.getPackageName();
if (currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED || currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED ||
currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_STOPPED) {
allEvents.add(currentEvent); // an extra event is found, add to all events list.
// taking it into a collection to access by package name
if (!map.containsKey(packageName)) {
map.put(packageName, new AppUsageInfo());
}
}
}
// iterate through all events.
for (int i = 0; i < allEvents.size() - 1; i++) {
UsageEvents.Event event0 = allEvents.get(i);
UsageEvents.Event event1 = allEvents.get(i + 1);
//for launchCount of apps in time range
if (!event0.getPackageName().equals(event1.getPackageName()) && event1.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED) {
// if true, E1 (launch event of an app) app launched
Objects.requireNonNull(map.get(event1.getPackageName())).launchCount++;
}
//for UsageTime of apps in time range
if (event0.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED &&
(event1.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED || event1.getEventType() == UsageEvents.Event.ACTIVITY_STOPPED)
&& event0.getPackageName().equals(event1.getPackageName())) {
long diff = event1.getTimeStamp() - event0.getTimeStamp();
Objects.requireNonNull(map.get(event0.getPackageName())).timeInForeground += diff;
}
}
// and return the map.
return map;
}
The AppUsageInfo class would be:
public class AppUsageInfo {
public long timeInForeground;
public int launchCount;
AppUsageInfo() {
this.timeInForeground = 0;
this.launchCount = 0;
}
}
To then get the usage stats for the last two hours, simply call
Calendar startCalendar = Calendar.getInstance();
startCalendar.add(Calendar.HOUR_OF_DAY, -2);
Calendar endCalendar = Calendar.getInstance();
HashMap<String, AppUsageInfo> result = queryUsageStatistics(context, startCalendar.getTimeInMillis(), endCalendar.getTimeInMillis();
It can be the similar question that I have found in StackOverFlow. But I have a little bit different situation then all of them. In my database I have start Date and Start Time. I want the system compare it's date and time separately because starting date and time are in separate columns in database. First the system compares the date and then time. The another activity should open only if the date is same and the time is before 15 minutes the starting time in database.
I have done this so far;
private void startTraining() {
Calendar calendar1 = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("MM-dd-yyy");
String currentDate = formatter.format(calendar1.getTime());
System.out.println(currentDate);
Calendar calendar2 = Calendar.getInstance();
SimpleDateFormat formatter2 = new SimpleDateFormat("hh:mm");
String currentTime = formatter2.format(calendar2.getTime());
System.out.println(currentTime);
String trainingStartDate = SharedMemory.getInstance()
.getCurrentTraining().getDate();
String trainingStartTime = SharedMemory.getInstance()
.getCurrentTraining().getStartTime();
int difference = trainingStartTime.compareTo(currentTime);
System.out.println(difference);
//System.out.println(trainingStartTime);
if (currentDate.toString().equals(trainingStartDate)&& difference < 15) {
Log.i("Debug", "CHECKPOINT");
Intent intent = new Intent(getApplicationContext(),
TraineeListActivity.class);
MainActivity.this.startActivity(intent);
finish();
} else{
}
}
I am not getting the result what I am expecting. Thanks in advance.
You use String.compareTo() to compare the "time" String, which won't work correctly. Try changing the code to this
private void startTraining() throws ParseException {
// current date & time
Calendar now = Calendar.getInstance();
// parse date & time from database
String trainingStartDate = SharedMemory.getInstance()
.getCurrentTraining().getDate();
String trainingStartTime = SharedMemory.getInstance()
.getCurrentTraining().getStartTime();
String strDateTime = trainingStartDate + " " + trainingStartTime;
Calendar training = Calendar.getInstance();
training.setTime(new SimpleDateFormat("MM-dd-yyyy kk:mm")
.parse(strDateTime));
// find difference in milliseconds
long difference = training.getTimeInMillis() - now.getTimeInMillis();
if (difference < 15 * 60 * 1000) { //less than 15 minutes
Log.i("Debug", "CHECKPOINT");
Intent intent = new Intent(getApplicationContext(),
TraineeListActivity.class);
MainActivity.this.startActivity(intent);
finish();
} else {
}
}