Android:每小时获取UsageStats [英] Android: get UsageStats per hour

查看:69
本文介绍了Android:每小时获取UsageStats的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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.

注意:也许,您将无法在超过7.5天的时间内检索数据,因为

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆