在棉花糖中获取前台应用程序的 packageName 延迟 3 秒
Posted
技术标签:
【中文标题】在棉花糖中获取前台应用程序的 packageName 延迟 3 秒【英文标题】:Getting foreground app's packageName in Marshmallow delayed by 3 seconds 【发布时间】:2016-12-07 08:02:09 【问题描述】:在 android 6.0 Marshmallow 中,我使用以下代码查询前台应用程序,但传入通知出现问题,因为它向发送通知的应用程序显示前台应用程序。该问题仅存在于 Marshmallow 中(5.X 可以正常工作)。
// 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;
然后使用此答案UsageEvents 中的解决方案解决通知问题。
作为答案的解决方案,我将代码及其工作用于获取前台应用程序,但延迟了 3 秒。我的服务正在检查前台应用程序,并且每 500 毫秒重复一次,但 whatsapp 包在启动 whatsapp 3 秒后检测到。这是我在上述解决方案中使用的 UsageEvents 代码。
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;
【问题讨论】:
【参考方案1】:尝试此代码并确保代码在用户授予运行时权限后应用
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;
【讨论】:
以上是关于在棉花糖中获取前台应用程序的 packageName 延迟 3 秒的主要内容,如果未能解决你的问题,请参考以下文章