Как подсчитать время использования приложения, когда приложение находится на переднем плане?

Я работаю над приложением для Android для отслеживания ежедневного использования приложения. Идея состоит в том, что пользователь может установить дневной лимит времени для любого приложения, и уведомление появится в течение максимум 2 минут после превышения лимита. (Причина задержки: я создал систему сигнализации, используя класс AlarmManager, который будет срабатывать каждую минуту для запуска JobIntentService, который будет проверять, превышен ли лимит для любого приложения. )

Я использовал метод queryEvents. класса UsageStatsManager для подсчета времени использования приложения.

Вот мой код для подсчета времени использования приложения (я следовал Как использовать 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;
}

Вкратце приведенный выше код подсчитывает разницу во времени метки времени, когда приложение переходит в активный режим (UsageEvents.Event.ACTIVITY_RESUMED), и метки времени, когда оно переходит в фоновый режим (UsageEvents.Event.ACTIVITY_PAUSED). Затем он добавляет эту разницу к общему времени использования приложения.

Проблема в том, что количество времени, проведенного на переднем плане, нельзя подсчитать, если только приложение не перейдет в фоновый режим. Таким образом, если лимит использования превышен, уведомление не появится, пока приложение не перейдет в фоновый режим.

Действительно ли возможно получить время переднего плана, пока приложение находится на переднем плане?

Н.Б. Я пробовал queryUsageStats вместе с UsageStats.getTotalTimeInForeground(), но не удалось, так как у queryUsageStats были другие проблемы, не связанные с этим вопросом.


person Tanjim Khan    schedule 08.05.2020    source источник


Ответы (1)


Я решил проблему.

Добавление разницы текущего времени и метки времени текущего работающего приложения, выходящего на передний план, делает свое дело.

Я просто добавил следующий код перед оператором возврата:

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);
}

Это довольно просто, я должен был подумать об этом, прежде чем публиковать вопрос.

person Tanjim Khan    schedule 11.05.2020