Obtener el nombre de paquete de la aplicación de primer plano en Marshmallow retrasado en 3 segundos

En Android 6.0 Marshmallow solicito la aplicación de primer plano con el código siguiente, pero hubo un problema con las notificaciones entrantes, ya que muestra la aplicación de primer plano a la aplicación que envía notificación. El problema sólo existe en Marshmallow (5.X funciona correctamente).

// API 21 and above @TargetApi(Build.VERSION_CODES.LOLLIPOP) public static String getProcessNew(UsageStatsManager mUsageStatsManager, Context c) throws Exception { String st = null; try { long endTime = System.currentTimeMillis(); long beginTime = endTime - 1000 * 10; // We get usage stats for the last minute List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, beginTime, endTime); // Sort the stats by the last time used if (stats != null) { SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>(); for (UsageStats usageStats : stats) { mySortedMap.put(usageStats.getLastTimeUsed(), usageStats); } if (mySortedMap != null && !mySortedMap.isEmpty()) { st = mySortedMap.get(mySortedMap.lastKey()).getPackageName(); } } } catch (Exception e) { Log.d("main", "Wxxxxexx " + e); } return st; } 

Y entonces el problema de la notificación se resuelve usando la solución de esta respuesta UsageEvents .

Como solución en la respuesta puse el código y su funcionamiento para conseguir la aplicación del primer plano pero retrasó por 3 segundos. Mi servicio está revisando la aplicación de primer plano y está repitiendo cada 500ms pero el paquete de whatsapp detecta después de 3 segundos de iniciar whatsapp. Este es el código de UsageEvents que uso de la solución anterior.

  if (BuildV >= 23) { long endTime = System.currentTimeMillis(); long beginTime = endTime - 1000 * 10; UsageEvents usageEvents = mUsageStatsManager.queryEvents(beginTime, endTime); UsageEvents.Event event = new UsageEvents.Event(); while (usageEvents.hasNextEvent()) { usageEvents.getNextEvent(event); } if (st.equals(event.getPackageName()) && event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) { pack = st; } } 

Pruebe este código y asegúrese de que el código se aplique después de que el usuario haya concedido permiso de ejecución

 private RunningAppProcessInfo getForegroundApp() { RunningAppProcessInfo result=null, info=null; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <RunningAppProcessInfo> l = mActivityManager.getRunningAppProcesses(); Iterator <RunningAppProcessInfo> i = l.iterator(); while(i.hasNext()){ info = i.next(); if(info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && !isRunningService(info.processName)){ result=info; break; } } return result; } private ComponentName getActivityForApp(RunningAppProcessInfo target){ ComponentName result=null; ActivityManager.RunningTaskInfo info; if(target==null) return null; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <ActivityManager.RunningTaskInfo> l = mActivityManager.getRunningTasks(9999); Iterator <ActivityManager.RunningTaskInfo> i = l.iterator(); while(i.hasNext()){ info=i.next(); if(info.baseActivity.getPackageName().equals(target.processName)){ result=info.topActivity; break; } } return result; } private boolean isStillActive(RunningAppProcessInfo process, ComponentName activity) { // activity can be null in cases, where one app starts another. for example, astro // starting rock player when a move file was clicked. we dont have an activity then, // but the package exits as soon as back is hit. so we can ignore the activity // in this case if(process==null) return false; RunningAppProcessInfo currentFg=getForegroundApp(); ComponentName currentActivity=getActivityForApp(currentFg); if(currentFg!=null && currentFg.processName.equals(process.processName) && (activity==null || currentActivity.compareTo(activity)==0)) return true; Slog.i(TAG, "isStillActive returns false - CallerProcess: " + process.processName + " CurrentProcess: " + (currentFg==null ? "null" : currentFg.processName) + " CallerActivity:" + (activity==null ? "null" : activity.toString()) + " CurrentActivity: " + (currentActivity==null ? "null" : currentActivity.toString())); return false; } private boolean isRunningService(String processname){ if(processname==null || processname.isEmpty()) return false; RunningServiceInfo service; if(mActivityManager==null) mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE); List <RunningServiceInfo> l = mActivityManager.getRunningServices(9999); Iterator <RunningServiceInfo> i = l.iterator(); while(i.hasNext()){ service = i.next(); if(service.process.equals(processname)) return true; } return false; } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.