Android:ottieni UsageStats all'ora
Uso UsageStats
funzionalità di Android, ma l'intervallo più piccolo è DAILY INTERVAL
.
long time = System.currentTimeMillis(); List<UsageStats> appList = manager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - DAY_IN_MILLI_SECONDS, time);
Come posso ottenere UsageStats
in un intervallo orario?
Risposta
Tutto il merito va a questa risposta. Ho imparato da quello.
Come possiamo raccogliere i dati sull'utilizzo delle app per un intervallo di tempo personalizzato (ad es. per 1 ora)?
Dobbiamo chiamare queryEvents(long begin_time, long end_time)
metodo in quanto ci fornirà tutti i dati a partire da begin_time
a end_time
. Ci fornisce i dati di ogni app tramite foreground
e background
eventi invece del tempo totale speso come queryUsageStats()
metodo. Quindi, utilizzando il timestamp degli eventi in primo piano e in background, possiamo contare il numero di volte in cui un'app è stata avviata e possiamo anche scoprire la durata di utilizzo di ciascuna app.
Implementazione per la raccolta dei dati sull'utilizzo dell'app nell'ultima ora
Per prima cosa, aggiungi la seguente riga nel AndroidManifest.xml
file e richiedere anche all'utente di ottenere l'autorizzazione per l'accesso all'utilizzo.
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
Aggiungi le seguenti righe all'interno di qualsiasi metodo
long hour_in_mil = 1000*60*60; // In Milliseconds long end_time = System.currentTimeMillis(); long start_time = end_time - hour_in_mil;
Quindi, chiama il metodo getUsageStatistics()
getUsageStatistics(start_time, end_time);
metodo getUsageStatistics
@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 + "nn"); } 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; } }
Come posso personalizzare questi codici per raccogliere dati ogni ora?
Poiché desideri ottenere i dati orari, cambia il end_time
e start_time
valore per ogni dato orario. Ad esempio:se dovessi provare a raccogliere i dati dell'ora passata (per i dati delle ultime 2 ore). Farei la seguente cosa.
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);
Tuttavia, puoi utilizzare un Handler
saltare ripetutamente la scrittura di start_time
e end_time
per modificare il valore di queste variabili. Ogni volta che i dati verranno raccolti per un'ora, verrà completata un'attività e dopo aver modificato automaticamente i valori delle variabili, chiamerai nuovamente il getUsageStatistics
metodo.
Nota: Forse non sarai in grado di recuperare i dati per più degli ultimi 7,5 giorni poiché gli eventi vengono conservati dal sistema solo per pochi giorni.