0

I use following code to get current foreground apps package name in my app. I have one user running android 5, where this always returns null (I have other users running android 5 confirming, that my code is working!). The user installs my app, gives permissions (I checked them, my app has the permissions to use USAGE_STATS_SERVICE and then I call getCurrentForegroundPackage and it returns null. App is running a minute or so before... It's working on many other devices... Where could be the problem? Any ideas?

Code - getting foreground apps package

public static String getCurrentForegroundPackage(Context context)
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        String foregroundPackage = getCurrentForegroundPackage(context, Constants.CHECK_INTERVAL_SECOND);
        if (foregroundPackage == null)
            foregroundPackage = getCurrentForegroundPackage(context, Constants.CHECK_INTERVAL_MINUTE);
        if (foregroundPackage == null)
            foregroundPackage = getCurrentForegroundPackage(context, Constants.CHECK_INTERVAL_HOUR);
        return foregroundPackage;
    }
    else
    {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
        ComponentName componentInfo = taskInfo.get(0).topActivity;
        return componentInfo.getPackageName();
    }
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static String getCurrentForegroundPackage(Context context, long interval)
{
    long to = System.currentTimeMillis();
    long from = to - interval;
    UsageStatsManager manager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
    UsageEvents usageEvents = manager.queryEvents(from, to);
    return getForeGroundPackage(usageEvents);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static String getForeGroundPackage(UsageEvents usageEvents)
{
    String packageName = null;
    long highestMoveToForegroundTimeStamp = 0;
    while (usageEvents.hasNextEvent())
    {
        UsageEvents.Event event = new UsageEvents.Event();
        usageEvents.getNextEvent(event);
        if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND)
        {
            long timeStamp = event.getTimeStamp();
            if (timeStamp > highestMoveToForegroundTimeStamp)
            {
                packageName = event.getPackageName();
                highestMoveToForegroundTimeStamp = timeStamp;
            }
        }
    }
    return packageName;
}

Code - checking if my app has permissions

@TargetApi(Build.VERSION_CODES.KITKAT)
public static boolean hasUsageAccess()
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        try
        {
            PackageManager packageManager = MainApp.get().getPackageManager();
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(MainApp.get().getPackageName(), 0);
            AppOpsManager appOpsManager = (AppOpsManager) MainApp.get().getSystemService(Context.APP_OPS_SERVICE);
            int mode = appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, applicationInfo.uid, applicationInfo.packageName);
            return mode == AppOpsManager.MODE_ALLOWED;
        }
        catch (Exception e)
        {
            L.e(PermissionUtil.class, e);
        }
        return false;
    }
    return true;
}
prom85
  • 16,896
  • 17
  • 122
  • 242
  • Hi, did you manage to find a solution to this? I have the same problem. It used to work on a Nexus 5 Marshmallow device, then now when I run the same code on the same device, it returns a null package name. I've pinpointed the error the be because usageEvents.hasNextEvent() returns false, but I can't figure out why. – user1118764 Aug 17 '16 at 01:15
  • I deprecated this polling method... I am using the `AccessibilitiesService` now instead which works fine... – prom85 Aug 17 '16 at 07:40
  • Hey check out the comments on the answer on this post http://stackoverflow.com/questions/30619349/android-5-1-1-and-above-getrunningappprocesses-returns-my-application-packag - it looks like OEMs can remove the permission granted causing the call to return null. This blows > – Clocker Nov 28 '16 at 22:41
  • When in your code did you do the permission check? It's possible for the app to have permission but for the user to then revoke the permission after the check, which cause `queryEvents()` to return an empty list. – Sam Feb 17 '19 at 03:13

0 Answers0