android - ¿Cómo usar UsageStatsManager?
usage-statistics activity-manager (7)
Creo que la documentación fue una breve descripción de las cosas del calendario. No creo que realmente funcione solo con 2014; Sin embargo, puedo estar equivocado.
Para acceder a la lista real de UsageStats, deberá crear un objeto Calendar con el mes, día y año correctos. Exactamente cómo dijo MRK en la otra respuesta. Copié y corregí los errores en el código de MRK para que cualquiera que lo vea en el futuro pueda verlo.
Calendar beginCal = Calendar.getInstance();
beginCal.set(Calendar.DATE, 1);
beginCal.set(Calendar.MONTH, 0);
beginCal.set(Calendar.YEAR, 2012);
Calendar endCal = Calendar.getInstance();
endCal.set(Calendar.DATE, 1);
endCal.set(Calendar.MONTH, 0);
endCal.set(Calendar.YEAR, 2014);
final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, beginCal.getTimeInMillis(), endCal.getTimeInMillis());
-Crédito MRK; corregido por mí (accidentalmente solo puso cal en lugar de beginCal y endCal)
El código para la configuración de acceso de uso se encuentra a continuación. :)
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
Antecedentes
Google ha desaprobado la función "
getRecentTasks
" de la clase "ActivityManager".
Ahora todo lo que hace es obtener la lista de aplicaciones que la aplicación actual ha abierto.
Incluso he escrito una publicación al respecto aquí en StackOverflow , pero noté que es imposible.
El problema
Hice una publicación al respecto ( here , y otra similar, creada por otra persona, here ) y solicité volver a considerarlo, y Google decidió crear una nueva clase, que parece proporcionar una funcionalidad similar (más como estadísticas, pero también podría ser útil), pero no puedo encontrar cómo usarlo.
La clase se llama "
UsageStatsManager
", y supongo que la función "
queryUsageStats
" hace el trabajo.
Además, parece que tiene un nuevo permiso ("
android.permission.PACKAGE_USAGE_STATS
"), que es un
permiso del sistema
, pero está escrito que:
declarar el permiso implica la intención de usar la API y el usuario del dispositivo puede otorgar permiso a través de la aplicación Configuración.
Here''s otro enlace sobre esta nueva funcionalidad.
Lo que he encontrado
Miré el código de Android y noté que "Context" tiene USAGE_STATS_SERVICE, que en los JavaDoc dice lo siguiente:
/**
* Use with {@link #getSystemService} to retrieve a {@link
* android.app.UsageStatsManager} for interacting with the status bar.
*
* @see #getSystemService
* @see android.app.UsageStatsManager
* @hide
*/
public static final String USAGE_STATS_SERVICE = "usagestats";
Lo extraño es que no solo dice "
status bar
", sino que también el packageName no coincide (debería ser "
android.app.usage.UsageStatsManager
" en su lugar).
También agregué el permiso correcto:
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
y aquí está el código que uso:
final UsageStatsManager usageStatsManager=(UsageStatsManager)context.getSystemService("usagestats");// Context.USAGE_STATS_SERVICE);
final int currentYear=Calendar.getInstance().get(Calendar.YEAR);
final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY,currentYear-2,currentYear);
En el emulador mismo, fui a "
Settings"->"security"->"apps with usage access
", y habilité mi aplicación.
Sin embargo, cuando ejecuto el código, todo lo que obtengo es una lista vacía ...
La pregunta
¿Cómo se usa
UsageStatsManager
?
Además, ¿cómo permite que el usuario otorgue el permiso de la manera más fácil posible? ¿O se hace automáticamente, tan pronto como la aplicación intenta obtener la información necesaria?
¿Qué sucede cuando intento usar esta clase y el usuario aún no la ha confirmado?
¿Cómo puedo hacer que el código me devuelva una lista real de aplicaciones?
En realidad, hay una
aplicación de ejemplo incluida en el código de muestra de AOSP
:
developers/samples/android/system/AppUsageStatistics/
Incluye todos los bits necesarios para usar
UsageStats
en una aplicación:
-
Declarando el permiso en
AndroidManifest.xml
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
-
Mostrar configuración para otorgar permiso para acceder a
UsageStatsManager
startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
-
Consulta
UsageStatsManager
para estadísticas.Calendar cal = Calendar.getInstance(); cal.add(Calendar.YEAR, -1); List<UsageStats> queryUsageStats = mUsageStatsManager .queryUsageStats(intervalType, cal.getTimeInMillis(), System.currentTimeMillis());
Para resumir y aplicar a su ejemplo:
- Parece que solicita y concede permisos correctamente para acceder a las estadísticas de uso.
-
Obtiene correctamente el servicio del sistema
UsageStats
. -
Sin embargo, el período de tiempo que consulta es corto: los argumentos
beginTime
yendTime
se miden en milisegundos desde la época.Calendar
instancias deCalendar
pueden darle este valor congetTimeinMillis()
. Lo que hace erróneamente es dar solo los números de año (2015
y2017
si ejecutara el programa hoy). Estos valores se interpretan como milisegundos desde la época y, por lo tanto, el intervalo es de solo 2 milisegundos y es en algún momento de 1970.
En lugar del siguiente fragmento de código que publicó, debe copiar el ejemplo que publiqué a continuación:
Incorrecto:
final int currentYear=Calendar.getInstance().get(Calendar.YEAR);
final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY,currentYear-2,currentYear);
Correcto:
final long currentTime = System.currentTimeMillis(); // Get current time in milliseconds
final Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -2); // Set year to beginning of desired period.
final long beginTime = cal.getTimeInMillis(); // Get begin time in milliseconds
final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, beginTime, currentTime);
He creado una muestra de cómo usar UsageStats en mi Github. Ojalá pueda ser de ayuda para alguien
Respondiendo a su última pregunta "¿Cómo puedo hacer que el código me devuelva una lista real de aplicaciones?". queryUsageStats toma la hora de inicio y la hora de finalización en milisegundos, no el valor del año en int.
Calendar beginCal = Calendar.getInstance();
beginCal.set(Calendar.DATE, 1);
beginCal.set(Calendar.MONTH, 0);
beginCal.set(Calendar.YEAR, 2012);
Calendar endCal = Calendar.getInstance();
endCal.set(Calendar.DATE, 1);
endCal.set(Calendar.MONTH, 0);
endCal.set(Calendar.YEAR, 2014);
final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, beginCal.getTimeInMillis(), endCal.getTimeInMillis());
Esto debería devolver una lista de UsageStats para los años 2012 y 2013 (tenga en cuenta que la hora de finalización es exclusiva del rango de tiempo de resultado final).
Si desea ver estadísticas de uso de un período de tiempo específico. Primero debe calcular el período de tiempo en milisegundos del inicio y el final de su período de tiempo, desde la época. (época es el número de segundos que han transcurrido desde las 00:00:00 UTC, jueves 1 de 1970.) O, como mostraré en el siguiente código de muestra, una forma fácil es calcular hacia atrás desde la hora actual en milisegundos.
Por ejemplo, si desea estadísticas de los últimos 4 días, sería:
UsageStatsManager mUsageStatsManager = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
List<UsageStats> queryUsageStats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
(System.currentTimeMillis() - 345600000), System.currentTimeMillis());
El número 345600000 es la cantidad de milisegundos de 4 días.
Y para INTERVAL_TYPE this explica bien.
El sistema recopila y agrega los datos en 4 intervalos diferentes y son: INTERVAL_DAILY, INTERVAL_WEEKLY, INTERVAL_MONTHLY e INTERVAL_YEARLY. Los registros del sistema son limitados en el tiempo, por lo que podrá recuperar datos de uso de la aplicación durante un máximo de 7 días para intervalos diarios, hasta 4 semanas para intervalos semanales, hasta 6 meses mensuales y finalmente hasta 2 años anuales . Hay una quinta opción para mencionar: INTERVAL_BEST elegirá el mejor intervalo de ajuste entre los cuatro anteriores en función del intervalo de tiempo que haya elegido.
Use UsageStats obtendrá la información incorrecta cuando el usuario abra el cajón de notificaciones o en una pantalla bloqueada. Debe usar UsageStatsManager.queryEvents () y buscar el último evento con el tipo de evento MOVE_TO_FOREGROUND.
puedes hacer así
//noinspection ResourceType
final UsageStatsManager usageStatsManager=(UsageStatsManager)context.getSystemService("usagestats");// Context.USAGE_STATS_SERVICE);
final int currentYear=Calendar.getInstance().get(Calendar.YEAR);
final List<UsageStats> queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY,currentYear-2,currentYear);