oreo lollipop descargar caracteristicas android android-6.0-marshmallow

lollipop - Android 5.1.1 y superior: getRunningAppProcesses() solo devuelve el paquete de mi aplicaciĆ³n



android oreo (8)

// Esto está funcionando rápido que la respuesta anterior.

String mforegoundPppPackageName; UsageStatsManager usage = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); long time = System.currentTimeMillis(); List<UsageStats> stats = usage.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, 0, time); Collections.sort(stats, usageStatsComparator); if (stats != null && stats.size() > 0) { if (stats.get(stats.size()).getPackageName().equals("android")) { stats.remove(stats.size()); } mforegoundPppPackageName = stats.get(stats.size()).getPackageName(); } else { mforegoundPppPackageName = ""; } **//How to sort** Comparator<UsageStats> usageStatsComparator = new Comparator<UsageStats>() { @Override public int compare(UsageStats o1, UsageStats o2) { if (o1.getLastTimeUsed() > o2.getLastTimeUsed()) { return 1; } else if (o1.getLastTimeUsed() < o2.getLastTimeUsed()) { return -1; } else { return 0; } } };

Parece que Google finalmente cerró todas las puertas para obtener el paquete de aplicación actual en primer plano.

Después de la actualización de Lollipop, que eliminó getRunningTasks(int maxNum) y gracias a esta respuesta , utilicé este código para obtener el paquete de la aplicación en primer plano desde Lollipop:

final int PROCESS_STATE_TOP = 2; RunningAppProcessInfo currentInfo = null; Field field = null; try { field = RunningAppProcessInfo.class.getDeclaredField("processState"); } catch (Exception ignored) { } ActivityManager am = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> appList = am.getRunningAppProcesses(); for (RunningAppProcessInfo app : appList) { if (app.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && app.importanceReasonCode == 0 ) { Integer state = null; try { state = field.getInt( app ); } catch (Exception ignored) { } if (state != null && state == PROCESS_STATE_TOP) { currentInfo = app; break; } } } return currentInfo;

Android 5.1.1 y superior (6.0 Marshmallow), al parecer, también mató a getRunningAppProcesses() . Ahora devuelve una lista de su propio paquete de aplicación.

UsageStatsManager

Podemos usar la nueva API UsageStatsManager como se describe aquí, pero no funciona para todas las aplicaciones. Algunas aplicaciones del sistema devolverán el mismo paquete

com.google.android.googlequicksearchbox

Servicio de accesibilidad (diciembre de 2017: Prohibido su uso por Google)

Algunas aplicaciones usan AccessibilityService (como se ve aquí ) pero tiene algunas desventajas.

¿Hay alguna otra forma de obtener el paquete actual de la aplicación en ejecución?


Eche un vistazo a https://github.com/ricvalerio/foregroundappchecker , podría ser lo que necesita. Proporciona código de muestra y elimina el dolor de tener que implementar un detector de primer plano de versión cruzada.

Aquí hay dos muestras:

AppChecker appChecker = new AppChecker(); String packageName = appChecker.getForegroundApp();

O revise regularmente:

AppChecker appChecker = new AppChecker(); appChecker .when("com.other.app", new AppChecker.Listener() { @Override public void onForeground(String packageName) { // do something } ) .when("com.my.app", new AppChecker.Listener() { @Override public void onForeground(String packageName) { // do something } ) .other(new AppChecker.Listener() { @Override public void onForeground(String packageName) { // do something } ) .timeout(1000) .start(this);


Google limitó esta funcionalidad solo para aplicaciones del sistema. Como se informó en un code.google.com/p/android-developer-preview/issues/… , necesitará el permiso REAL_GET_TASKS para acceder allí.

Las aplicaciones ahora deben tener ... permiso.REAL_GET_TASKS para poder obtener información de proceso para todas las aplicaciones. Solo se devolverá la información del proceso para la aplicación que realiza la llamada si la aplicación no tiene el permiso. Las aplicaciones de privilegios podrán obtener temporalmente información de proceso para todas las aplicaciones si no tienen el nuevo permiso, pero han desaprobado ... permiso.GET_TASKS Además, solo las aplicaciones del sistema pueden adquirir el permiso REAL_GET_TASKS.


Intente utilizar getRunningServices() lugar del método getRunningAppProcesses() .

ActivityManager mActivityManager = (ActivityManager) getSy stemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningServiceInfo> appProcessInfoList = mActivityManager.getRunningServices(Integer.MAX_VALUE);


Para obtener una lista de los procesos en ejecución en Android 1.6 - Android 6.0, puede usar esta biblioteca que escribí: https://github.com/jaredrummler/AndroidProcesses La biblioteca lee / proc para obtener información del proceso.

Google ha restringido significativamente el acceso a / proc en Android Nougat. Para obtener una lista de los procesos en ejecución en Android Nougat, deberá usar UsageStatsManager o tener acceso de root.

Haga clic en el historial de edición para soluciones alternativas anteriores.


Simplemente lanzando una optimización potencial a lo que imagino es un bit de código fuertemente copiado para detectar la aplicación más avanzada en Android M.

Esta

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { UsageStatsManager usm = (UsageStatsManager)this.getSystemService("usagestats"); long time = System.currentTimeMillis(); List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time); if (appList != null && appList.size() > 0) { SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>(); for (UsageStats usageStats : appList) { mySortedMap.put(usageStats.getLastTimeUsed(), usageStats); } if (mySortedMap != null && !mySortedMap.isEmpty()) { currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName(); } } }

Se puede simplificar a esto

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { UsageStatsManager usm = (UsageStatsManager) context.getSystemService( Context.USAGE_STATS_SERVICE); long time = System.currentTimeMillis(); List<UsageStats> appStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1000, time); if (appStatsList != null && !appStatsList.isEmpty()) { currentApp = Collections.max(appStatsList, (o1, o2) -> Long.compare(o1.getLastTimeUsed(), o2.getLastTimeUsed())).getPackageName(); } }

Me encontré usando este código en un bucle de 2 segundos, y me pregunté por qué estaba usando una solución compleja que era O (n * log (n)) cuando una solución más simple estaba disponible en Collections.max () que es O (n )


public class AccessibilityDetectingService extends AccessibilityService { @Override protected void onServiceConnected() { super.onServiceConnected(); //Configure these here for compatibility with API 13 and below. AccessibilityServiceInfo config = new AccessibilityServiceInfo(); config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED; config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; if (Build.VERSION.SDK_INT >= 16) //Just in case this helps config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS; setServiceInfo(config); } @Override public void onAccessibilityEvent(final AccessibilityEvent event) { if (event == null ) { return; } else if(event.getPackageName() == null && event.getClassName() == null){ return; } if (activityInfo != null){ Log.d("CurrentActivity", componentName.flattenToShortString()); } } private ActivityInfo tryGetActivity(ComponentName componentName) { try { return getPackageManager().getActivityInfo(componentName, 0); } catch (PackageManager.NameNotFoundException e) { return null; } } @Override public void onInterrupt() { } } }//`enter code here`uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" /> <uses-permission android:name="android.permission.GET_TASKS" />

Luego, inicie el servicio y la accesibilidad de la aplicación en la configuración de su dispositivo-> accesibilidad-> Aplicación en ese servicio.


private String printForegroundTask() { String currentApp = "NULL"; if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { UsageStatsManager usm = (UsageStatsManager)this.getSystemService("usagestats"); long time = System.currentTimeMillis(); List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time); if (appList != null && appList.size() > 0) { SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>(); for (UsageStats usageStats : appList) { mySortedMap.put(usageStats.getLastTimeUsed(), usageStats); } if (mySortedMap != null && !mySortedMap.isEmpty()) { currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName(); } } } else { ActivityManager am = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> tasks = am.getRunningAppProcesses(); currentApp = tasks.get(0).processName; } Log.e("adapter", "Current App in foreground is: " + currentApp); return currentApp; }

Use este método para obtener la tarea en primer plano. U necesitará un permiso del sistema "android: get_usage_stats"

public static boolean needPermissionForBlocking(Context context){ 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 true; } }

Si el usuario habilita esto en la configuración -> Seguridad-> aplicación con acceso de uso. Después de eso, obtendrás una tarea en primer plano. Proceso similar Clean matser por Cheetahamobile enlace de Google Play