una solicitud puedo permisos permiso obstaculizando necesario inhabilitaste habilitar esta dar contactos como app aplicaciones administrador activar android usage-statistics

android - solicitud - Comprueba si mi aplicación tiene habilitado el acceso de uso



permisos aplicaciones android 5 (7)

Estoy usando la nueva API de UsageStatsManager para obtener la aplicación de primer plano actual en Android 5.0 Lollipop. Para utilizar esta API, el usuario debe habilitar la aplicación en la pantalla Settings->Security->Apps with usage access .

Envío al usuario directamente a esta pantalla con esta intención:

startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));

Ahora, quiero validar el usuario habilitado mi aplicación. Quería hacerlo así como validé que el usuario habilitó mi aplicación para usar el servicio NotificationListenerService pero no tengo idea de qué es la clave String, si es que existe.

Settings.Secure.getString(contentResolver, "enabled_notification_listeners"); // Tried Settings.ACTION_USAGE_ACCESS_SETTINGS as key but it returns null

El segundo enfoque fue consultar las estadísticas de uso y comprobar si devuelve resultados (devuelve una matriz vacía cuando la aplicación no está habilitada) y funciona la mayoría de las veces, pero a veces devuelve 0 resultados incluso cuando mi aplicación está habilitada.

UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService("usagestats"); long time = System.currentTimeMillis(); List stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 10, time); if (stats == null || stats.isEmpty()) { // Usage access is not enabled }

¿Hay alguna forma de verificar si mi aplicación tiene habilitado el acceso de uso?


Anteriormente usé el mismo código que Bao Le, pero me he topado con el problema de que ciertos dispositivos (por ejemplo, VF-895N) informan que las estadísticas de uso están habilitadas incluso cuando no lo están. Como solución he modificado mi código de esta manera:

public static boolean hasPermission(@NonNull final Context context) { // Usage Stats is theoretically available on API v19+, but official/reliable support starts with API v21. if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) { return false; } final AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); if (appOpsManager == null) { return false; } final int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), context.getPackageName()); if (mode != AppOpsManager.MODE_ALLOWED) { return false; } // Verify that access is possible. Some devices "lie" and return MODE_ALLOWED even when it''s not. final long now = System.currentTimeMillis(); final UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); final List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, now - 1000 * 10, now); return (stats != null && !stats.isEmpty()); }

Probado con éxito en múltiples dispositivos.


Esta es una solución alternativa:

AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), context.getPackageName()); return mode == AppOpsManager.MODE_ALLOWED;


Este código funciona en Lollipop y Marshmallow. Utilicé este código en mi aplicación.

if (Build.VERSION.SDK_INT >= 21) { UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); long time = System.currentTimeMillis(); List stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 10, time); if (stats == null || stats.isEmpty()) { Intent intent = new Intent(); intent.setAction(Settings.ACTION_USAGE_ACCESS_SETTINGS); context.startActivity(intent); } }


Esto funciona hasta KitKat (API 19)

AppOpsManager appOps = (AppOpsManager) context .getSystemService(Context.APP_OPS_SERVICE); int mode = appOps.checkOpNoThrow("android:get_usage_stats", android.os.Process.myUid(), context.getPackageName()); boolean granted = mode == AppOpsManager.MODE_ALLOWED;


Recibí una gran respuesta de alguien en Twitter, probé que funcionaba:

try { PackageManager packageManager = context.getPackageManager(); ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0); AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName); return (mode == AppOpsManager.MODE_ALLOWED); } catch (PackageManager.NameNotFoundException e) { return false; }


Si están utilizando una tableta Amazon Fire (y posiblemente otros dispositivos con sistema operativo Fire), el usuario puede descargar la aplicación desde un Google Play Store instalado por el usuario y no tener la opción que desea activar en su sistema operativo. Lo sé porque como usuario de Fire OS esto me sucedió hace unos minutos. Detectar si un usuario tiene Fire OS y, de ser así, ofrecer una opción que realmente exista sería fantástico tanto para el usuario como para el desarrollador.


prueba esto ,

public boolean check_UsgAccs(){ long tme = System.currentTimeMillis(); UsageStatsManager usm = (UsageStatsManager)getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE); List<UsageStats> al= usm.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, tme - (1000 * 1000), tme); return al.size()>0; }