¿Cómo usar UsageStatsManager?

Fondo

Google ha getRecentTasks utilizar la función ” getRecentTasks ” de la clase “ActivityManager”. Ahora todo lo que hace es obtener la lista de aplicaciones que ha abierto la aplicación actual.

Incluso he escrito una publicación sobre esto aquí en StackOverflow , pero noté que es imposible.

El problema

Hice una publicación al respecto ( aquí , y otra similar, creada por otra persona, aquí ) y solicité volver a considerarla, y Google decidió hacer 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 la forma de usarlo.

La clase se llama ” UsageStatsManager “, y creo 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 utilizar la API y el usuario del dispositivo puede otorgar el permiso a través de la aplicación Configuración.

Aquí hay otro enlace sobre esta nueva funcionalidad.

Lo que he encontrado

Miré el código de Android y noté que “Contexto” tenía USAGE_STATS_SERVICE, que en los JavaDocs 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 el nombre del paquete no coincide (debería ser ” android.app.usage.UsageStatsManager ” en su lugar).

También agregué el permiso correcto:

  

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 queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY,currentYear-2,currentYear); 

En el emulador en sí, 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 intente obtener la información necesaria?

¿Qué sucede cuando intentas utilizar esta clase pero el usuario aún no la ha confirmado?

¿Cómo puedo hacer que el código me devuelva una lista real de aplicaciones?

Creo que la documentación era poca para el material del calendario. No creo que realmente funcione solo en 2014; sin embargo, puedo estar equivocado.

Para acceder a la lista real de UsageStats, necesitaría 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 queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, beginCal.getTimeInMillis(), endCal.getTimeInMillis()); 

-Credit MRK; corregido por mí (accidentalmente acaba de poner cal en lugar de beginCal y endCal)

El código para la configuración de acceso de uso está debajo. 🙂

 Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivity(intent); 

Creé una muestra de cómo usar UsageStats en mi Github. Con suerte, puede ser de ayuda para alguien

https://github.com/ColeMurray/UsageStatsSample

Respondiendo a su última pregunta “¿Cómo puedo hacer que el código me devuelva una lista real de aplicaciones?”. queryUsageStats toma el tiempo de inicio y el 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 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 el tiempo de finalización es exclusivo del rango de tiempo del resultado final).

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.

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:

  1. Declarando el permiso en AndroidManifest.xml

  2. Mostrar configuraciones para otorgar permiso para acceder a UsageStatsManager

    startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));

  3. Consulta UsageStatsManager para estadísticas.

     Calendar cal = Calendar.getInstance(); cal.add(Calendar.YEAR, -1); List queryUsageStats = mUsageStatsManager .queryUsageStats(intervalType, cal.getTimeInMillis(), System.currentTimeMillis()); 
  4. Crear una lista de aplicaciones basadas en UsageStats

Para resumir y aplicar a su ejemplo:

  • Parece que pides y concedes 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 beginTime corto: los argumentos beginTime y endTime se miden en milisegundos desde la época. Calendar instancias de Calendar pueden darle este valor con getTimeinMillis() . Lo que hace erróneamente es solo dar los números del año ( 2015 y 2017 si ejecutara el progtwig hoy). Estos valores se interpretan como milisegundos desde la época y, por lo tanto, el intervalo es de solo 2 milisegundos de largo y está en algún momento de 1970.

En lugar del siguiente fragmento de código que ha publicado, debe copiar el ejemplo que publiqué a continuación:

Incorrecto:

 final int currentYear=Calendar.getInstance().get(Calendar.YEAR); final List 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 queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, beginTime, currentTime); 

puedes hacer esto

 //noinspection ResourceType final UsageStatsManager usageStatsManager=(UsageStatsManager)context.getSystemService("usagestats");// Context.USAGE_STATS_SERVICE); final int currentYear=Calendar.getInstance().get(Calendar.YEAR); final List queryUsageStats=usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY,currentYear-2,currentYear); 

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. (epoch es la cantidad de segundos transcurridos desde las 00:00:00 UTC del jueves 1 de 1970). O, como mostraré en el siguiente código de ejemplo, una manera fácil es calcular hacia atrás desde el tiempo actual en milisegundos.

Por ejemplo, si quiere estadísticas de los últimos 4 días, sería:

 UsageStatsManager mUsageStatsManager = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE); List 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 el INTERVAL_TYPE esto lo explica bien.

El sistema recostack y agrega los datos en 4 intervalos diferentes y son: INTERVAL_DELAIE, INTERVAL_MUNICIPALMENTE, INTERVALO_MONTERNA e INTERVALO_AÑO. Los registros del sistema están limitados en el tiempo, por lo que podrá recuperar datos de uso de la aplicación hasta por 7 días por intervalo diario, hasta 4 semanas por intervalo semanal, hasta 6 meses por mes y finalmente hasta 2 años por año . Hay una quinta opción para mencionar: INTERVAL_BEST elegirá el mejor intervalo de adaptación entre los cuatro anteriores en función del período de tiempo que haya elegido.