1

I have a service that his main goal is to get the package name of the current visible app. This is the code that is responsible for it:

try {
            if (Build.VERSION.SDK_INT > 20) {
                UsageStatsManager usm = (UsageStatsManager) service.getSystemService(Context.USAGE_STATS_SERVICE);
                Calendar calendar = Calendar.getInstance();
                long endTime = calendar.getTimeInMillis();
                calendar.add(Calendar.DAY_OF_WEEK, -1);
                long startTime = calendar.getTimeInMillis();

                List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, startTime, endTime);
                if (usageStatsList != null && usageStatsList.size() > 0) {
                    Collections.sort(usageStatsList, new UsageStatsComparator());
                    UsageStats mUsageStats = usageStatsList.get(0);
                    return mUsageStats.getPackageName();
                }

                else {
                if (!Utils.usageAccessGranted(service) && !directToSettingAlreadyTookPlace) {
                    launchUsageStatsSetting(service);
                }
                return "";
            }
        } else {
            ActivityManager mActivityManager = (ActivityManager) service.getSystemService(Context.ACTIVITY_SERVICE);
            return mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
        }
    } catch (Exception e) {
        Log.e("Error", "Getting Front Package Failed " + e.toString());
        return "";
    }

This is the Comparator I use:

public class UsageStatsComparator implements Comparator<UsageStats> {



    @Override
    public int compare(UsageStats lhs, UsageStats rhs) {

        if(Build.VERSION.SDK_INT > 20)
        {
            long time1 = lhs.getLastTimeUsed();
            long time2 = rhs.getLastTimeUsed();
            if (time1 > time2) {
                return -1;
            } else if (time1 < time2) {
                return 1;
            }
            return 0;
        }
        else
            return 0;

    }

}

This problem is on Lollipop and forward devices.

Everything works well, until the user expends the Status bar. once expanded I start getting packages related to Notifications, and the most problematic thing is when the user closes the status bar I am not getting the package of the visible app, I still get the last Package received when the status bar was open.

This causing a major issue to may desired functionality.

I tried the following approach:

  1. Get notifies when the Status bar is extended. I searched deeply but the only solution I found can be handled only by an Activity, but in my case it is impossible, because I am working through a Service...

  2. My Service is always showing a Notification in the Status bar as a Custom Remote View. I tried to find a way to know if the Notification is visible to the user, with no success.

Any one have an idea how to tackle it?

Gal Rom
  • 6,221
  • 3
  • 41
  • 33
  • did you try getRunningAppProcesses() for above api 20 ? – santoXme Feb 17 '17 at 10:48
  • @santoXme IgetRunningAppProcesses() will return a list of all processes running on the device. I have tried it before and I could not figure out which one is the front actviity. I have a feeling it is in my comparator. I edited my answer and added my comparoator – Gal Rom Feb 17 '17 at 13:19

1 Answers1

0

I found my solution here:

Android 6.0 Marshmallow UsageStatsManager issue when trying to retrieve foreground app

The solution is to use UsageEvents The key is checking if the front package you found have the following event type: Event.MOVE_TO_FOREGROUND

Community
  • 1
  • 1
Gal Rom
  • 6,221
  • 3
  • 41
  • 33