2

Я пытаюсь запросить UsageStats от UsageStatsManager с целью возвращения всех пакетов приложений, которые использовались ежедневно и надолго.Android: UsageStatsManager не возвращает правильные ежедневные результаты

Кодекс:

public static List<UsageStats> getUsageStatsList(Context context){ 
    UsageStatsManager usm = getUsageStatsManager(context); 
    Calendar calendar = Calendar.getInstance(); 
    long endTime = calendar.getTimeInMillis(); 
    calendar.add(Calendar.DAY_OF_YEAR, -1); 
    long startTime = calendar.getTimeInMillis(); 

    List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,startTime, endTime); 
    return usageStatsList; 
} 

У меня есть тревога, что пожары в день незадолго до полуночи и usagestats запрос, а затем сохраняет полученные данные. Сначала все, казалось, работало нормально, и я получал результаты пакета и их активное время, однако я добавил функцию, которая будет проверять результаты ежечасно, и вот где я сделал странное открытие.

Результаты от UsageStatsManager, похоже, были сброшены в разное время, а не в полночь, что я и ожидал, учитывая, что я использовал INTERVAL_DAILY в качестве параметра поиска.

Из данных я сохранил результаты пакет 'Time', кажется, сброс в (Грубые тайминги):

  • 3am
  • полуденного
  • 3 вечера
  • Полночь

Я понимаю, что существует корреляция между сбросом таймеров пакета, но это должно случиться?

Я уже видел следующую нить и где я получил много моей информации от: How to use UsageStatsManager?

Следовательно: Android UsageStatsManager producing wrong output? В комментариях говорится, что данные, возвращаемые из queryUsageStats нельзя доверять и возвращаются случайные результаты.

Я пропустил что-то простое или UsageStatsManager не работает правильно?

ответ

1

Я тоже заметил это поведение в API 21, данные UsageStats не поддерживаются достаточно долго в API 21. он отлично работает с API 22. Если вы зарегистрируетесь в android /data/system/usagestats, вы найдете ограниченные записи в API 21, поэтому его надежность его использования в API 21.

для API 21+, Вы получите целый день usagestats при запросе INTERVAL_DAILY согласно UsageStatsManager API. Если вы хотите получить запрос в течение нескольких часов, вы должны использовать queryEvents и повторить их по вашей собственной логике.

Я попытался следующим образом ...

Это модальный класс для сбора данных для каждого приложения:

private class AppUsageInfo { 
     Drawable appIcon; 
     String appName, packageName; 
     long timeInForeground; 
     int launchCount; 

     AppUsageInfo(String pName) { 
      this.packageName=pName; 
     } 
} 

List<AppUsageInfo> smallInfoList; //global var

здесь является метод, его легко, плыть по течению:

void getUsageStatistics() { 

UsageEvents.Event currentEvent; 
List<UsageEvents.Event> allEvents = new ArrayList<>(); 
HashMap<String, AppUsageInfo> map = new HashMap <String, AppUsageInfo>(); 

long currTime = System.currentTimeMillis(); 
long startTime currTime - 1000*3600*3; //querying past three hours 

UsageStatsManager mUsageStatsManager = (UsageStatsManager) 
        mContext.getSystemService(Context.USAGE_STATS_SERVICE); 

     assert mUsageStatsManager != null; 
UsageEvents usageEvents = mUsageStatsManager.queryEvents(usageQueryTodayBeginTime, currTime); 

//capturing all events in a array to compare with next element 

     while (usageEvents.hasNextEvent()) { 
      currentEvent = new UsageEvents.Event(); 
      usageEvents.getNextEvent(currentEvent); 
      if (currentEvent.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND || 
        currentEvent.getEventType() == UsageEvents.Event.MOVE_TO_BACKGROUND) { 
       allEvents.add(currentEvent); 
       String key = currentEvent.getPackageName(); 
// taking it into a collection to access by package name 
       if (map.get(key)==null) 
        map.put(key,new AppUsageInfo(key)); 
      } 
     } 

//iterating through the arraylist 
     for (int i=0;i<allEvents.size()-1;i++){ 
      UsageEvents.Event E0=allEvents.get(i); 
      UsageEvents.Event E1=allEvents.get(i+1); 

//for launchCount of apps in time range 
      if (!E0.getPackageName().equals(E1.getPackageName()) && E1.getEventType()==1){ 
// if true, E1 (launch event of an app) app launched 
       map.get(E1.getPackageName()).launchCount++; 
      } 

//for UsageTime of apps in time range 
      if (E0.getEventType()==1 && E1.getEventType()==2 
        && E0.getClassName().equals(E1.getClassName())){ 
       long diff = E1.getTimeStamp()-E0.getTimeStamp(); 
       phoneUsageToday+=diff; //gloabl Long var for total usagetime in the timerange 
       map.get(E0.getPackageName()).timeInForeground+= diff; 
      } 
     } 
//transferred final data into modal class object 
     smallInfoList = new ArrayList<>(map.values()); 

} 
1

я думаю, Я обнаружил, что там происходит. Во-первых я написал ниже код,

(дата сегодня 03.08.2017 00:25:14) и когда я послал ("имя пакета", 02.08.2017 00.00.00, 03.08.2017 00.00.00); к методу (я отправил эти даты с календарем, вы можете искать в google, как установить даты как это) Я получил этот вход;

46-'apppackagename'-9m 31s 
    154-'apppackagename'-22m 38s 

тогда я послал ("имя пакета", 03.08.2017 00.00.00, 04.08.2017 00.00.00); к методу, Я получил этот вход;

25-'apppackagename'-22m 38s 

И я использовал приложение, которое я отправил в методе около 1 мин. Опять же я послал выход метод:

02: 08: 2017-03.08.2017

46-'apppackagename'-9m 31s 
    154-'apppackagename'-23m 32s 

03: 08: 2017-04.08.2017

25-'apppackagename'-23m 32s 

Как вы видите, что они выросли как. После того, как я вижу, что я ждал до 03.00, Я использовал приложение около 5 минут, и я получил эти выходы.

02: 08: 2017-03.08.2017

46-'apppackagename'-9m 31s 
    154-'apppackagename'-23m 32s 

03: 08: 2017-04.08.2017

25-'apppackagename'-23m 32s 
    50-'apppackagename'-4m 48s 

В заключение, вы должны контролировать до дня и его последнего foregroundrunningtime. Если это то же самое в первые дни переднего плана. Вы должны устранить это время и вернуть сумму других. (Даже если я не знаю эту странную систему.) Счетчик нового дня, начинающийся после 03:00.

Надеюсь, это будет полезно для вас.