Android:每小时获取UsageStats [英] Android: get UsageStats per hour
问题描述
我使用Android的 UsageStats
功能,但最小间隔是 DAILY INTERVAL
.
I use UsageStats
feature of Android, but the smallest interval is DAILY INTERVAL
.
long time = System.currentTimeMillis();
List<UsageStats> appList = manager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - DAY_IN_MILLI_SECONDS, time);
如何每隔一个小时获取一次 UsageStats
?
How can I get UsageStats
in an hourly interval?
推荐答案
All credit goes to this answer. I have learned from that one.
我们如何收集自定义时间范围(例如每1小时)的应用使用情况数据?
我们必须调用 queryEvents(long begin_time,long end_time)
方法,因为它将为我们提供从 begin_time
到 end_time
的所有数据.它通过 foreground
和 background
事件为我们提供每个应用数据,而不是像
We have to call queryEvents(long begin_time, long end_time)
method as it will provide us all data starting from begin_time
to end_time
. It give us each app data through foreground
and background
events instead of total spent time like queryUsageStats()
method. So, using foreground and background events time stamp, we can count the number of times an app has been launched and also can find out the usage duration for each app.
收集最近1小时应用使用情况数据的实现
首先,在 AndroidManifest.xml
文件中添加以下行,并要求用户获得使用权限.
At first, add the following line in the AndroidManifest.xml
file and also request user to get permission of usage access.
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
在任何方法内添加以下行
Add the following lines inside any method
long hour_in_mil = 1000*60*60; // In Milliseconds
long end_time = System.currentTimeMillis();
long start_time = end_time - hour_in_mil;
然后,调用方法 getUsageStatistics()
getUsageStatistics(start_time, end_time);
getUsageStatistics methiod
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
void getUsageStatistics(long start_time, long end_time) {
UsageEvents.Event currentEvent;
// List<UsageEvents.Event> allEvents = new ArrayList<>();
HashMap<String, AppUsageInfo> map = new HashMap<>();
HashMap<String, List<UsageEvents.Event>> sameEvents = new HashMap<>();
UsageStatsManager mUsageStatsManager = (UsageStatsManager)
context.getSystemService(Context.USAGE_STATS_SERVICE);
if (mUsageStatsManager != null) {
// Get all apps data from starting time to end time
UsageEvents usageEvents = mUsageStatsManager.queryEvents(start_time, end_time);
// Put these data into the map
while (usageEvents.hasNextEvent()) {
currentEvent = new UsageEvents.Event();
usageEvents.getNextEvent(currentEvent);
if (currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_RESUMED ||
currentEvent.getEventType() == UsageEvents.Event.ACTIVITY_PAUSED) {
// allEvents.add(currentEvent);
String key = currentEvent.getPackageName();
if (map.get(key) == null) {
map.put(key, new AppUsageInfo(key));
sameEvents.put(key,new ArrayList<UsageEvents.Event>());
}
sameEvents.get(key).add(currentEvent);
}
}
// Traverse through each app data which is grouped together and count launch, calculate duration
for (Map.Entry<String,List<UsageEvents.Event>> entry : sameEvents.entrySet()) {
int totalEvents = entry.getValue().size();
if (totalEvents > 1) {
for (int i = 0; i < totalEvents - 1; i++) {
UsageEvents.Event E0 = entry.getValue().get(i);
UsageEvents.Event E1 = entry.getValue().get(i + 1);
if (E1.getEventType() == 1 || E0.getEventType() == 1) {
map.get(E1.getPackageName()).launchCount++;
}
if (E0.getEventType() == 1 && E1.getEventType() == 2) {
long diff = E1.getTimeStamp() - E0.getTimeStamp();
map.get(E0.getPackageName()).timeInForeground += diff;
}
}
}
// If First eventtype is ACTIVITY_PAUSED then added the difference of start_time and Event occuring time because the application is already running.
if (entry.getValue().get(0).getEventType() == 2) {
long diff = entry.getValue().get(0).getTimeStamp() - start_time;
map.get(entry.getValue().get(0).getPackageName()).timeInForeground += diff;
}
// If Last eventtype is ACTIVITY_RESUMED then added the difference of end_time and Event occuring time because the application is still running .
if (entry.getValue().get(totalEvents - 1).getEventType() == 1) {
long diff = end_time - entry.getValue().get(totalEvents - 1).getTimeStamp();
map.get(entry.getValue().get(totalEvents - 1).getPackageName()).timeInForeground += diff;
}
}
smallInfoList = new ArrayList<>(map.values());
// Concatenating data to show in a text view. You may do according to your requirement
for (AppUsageInfo appUsageInfo : smallInfoList)
{
// Do according to your requirement
strMsg = strMsg.concat(appUsageInfo.packageName + " : " + appUsageInfo.launchCount + "\n\n");
}
TextView tvMsg = findViewById(R.id.MA_TvMsg);
tvMsg.setText(strMsg);
} else {
Toast.makeText(context, "Sorry...", Toast.LENGTH_SHORT).show();
}
}
AppUsageInfo.class
import android.graphics.drawable.Drawable;
class AppUsageInfo {
Drawable appIcon; // You may add get this usage data also, if you wish.
String appName, packageName;
long timeInForeground;
int launchCount;
AppUsageInfo(String pName) {
this.packageName=pName;
}
}
如何自定义这些代码以每1小时收集一次数据?
要获取每小时数据,请更改每小时数据的 end_time
和 start_time
值.例如:如果我尝试收集过去每小时的数据(过去2小时的数据).我会做以下事情.
As you want to get per hour data, please change the end_time
and start_time
value for every hour data. For instance: If I would try to collect past per hour data (for past 2 hour data). I would do the following thing.
long end_time = System.currentTimeMillis();
long start_time = end_time - (1000*60*60);
getUsageStatistics(start_time, end_time);
end_time = start_time;
start_time = start_time - hour_in_mil;
getUsageStatistics(start_time, end_time);
但是,您可以使用 Handler
来跳过重复编写 start_time
和 end_time
的操作,以更改这些变量的值.每次将数据收集一个小时,任务将完成,并且在自动更改变量的值之后,您将再次调用 getUsageStatistics
方法.
However, you may use a Handler
to skip repeatedly writing start_time
and end_time
to change value of these variables. Each time data will be collected for one hour, a task will be completed and after automatically changing the values of the variables, you will again call the getUsageStatistics
method.
Note: Maybe, you will not be able to retrieve data for more than past 7.5 days as events are only kept by the system for a few days.
这篇关于Android:每小时获取UsageStats的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!