【问题标题】:Getting foreground app's packageName in Marshmallow delayed by 3 seconds在棉花糖中获取前台应用程序的 packageName 延迟 3 秒
【发布时间】: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;

                                    }
                                }

【问题讨论】:

    标签: android package android-6.0-marshmallow foreground usagestatsmanager


    【解决方案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;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-07-20
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-02
      • 1970-01-01
      相关资源
      最近更新 更多