androidserviceforeground

Get activity name of the foreground app on Android


I need to get the current Activity of the foreground App. I tried following this answer and later used this library(because the first solution only worked from Lollipop), and them indeed worked well getting the foreground app's package name, but I need to know which activity is open.


Solution

  • Hey @Capitan Luzzatto,

    First you need 2 permissions to read the tasks

    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
    

    And you should check first the user API level is 21 or more if yes you should get access for usage access settings like below

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP && !mIsChecked) {
            if (getUsageStatsList(getActivity()).isEmpty()) {
    
                Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
                startActivity(intent);
            }
     }
    

    to get Usage stats list

        public static List<UsageStats> getUsageStatsList(Context context){
        UsageStatsManager usm = (UsageStatsManager) context.getSystemService("usagestats");
        Calendar calendar = Calendar.getInstance();
        long endTime = calendar.getTimeInMillis();
        calendar.add(Calendar.DATE, -1);
        long startTime = calendar.getTimeInMillis();
    
        List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,startTime,endTime);
    
        return usageStatsList;
    }
    

    Finally you can get the latest Foreground app using the following method

    public String getRecentApps(Context context) {
        String topPackageName = "";
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
    
            long time = System.currentTimeMillis();
    
            UsageEvents usageEvents = mUsageStatsManager.queryEvents(time - 1000 * 30, System.currentTimeMillis() + (10 * 1000));
            UsageEvents.Event event = new UsageEvents.Event();
            while (usageEvents.hasNextEvent()) {
                usageEvents.getNextEvent(event);
            }
    
            if (event != null && !TextUtils.isEmpty(event.getPackageName()) && event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
                if (AndroidUtils.isRecentActivity(event.getClassName())) {
                    return event.getClassName();
                }
                return event.getPackageName();
            } else {
                topPackageName = "";
            }
        } else {
            ActivityManager am = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = taskInfo.get(0).topActivity;
    
            if (AndroidUtils.isRecentActivity(componentInfo.getClassName())) {
                return componentInfo.getClassName();
            }
    
            topPackageName = componentInfo.getPackageName();
        }
    
    
        return topPackageName;
    }
    

    To get Foreground activity use the method like this

    public String getRecentActivity(Context context) {
        String topActivityName = "";
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            UsageStatsManager mUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
    
            long time = System.currentTimeMillis();
    
            UsageEvents usageEvents = mUsageStatsManager.queryEvents(time - 1000 * 30, System.currentTimeMillis() + (10 * 1000));
            UsageEvents.Event event = new UsageEvents.Event();
            while (usageEvents.hasNextEvent()) {
                usageEvents.getNextEvent(event);
            }
    
            if (event != null && !TextUtils.isEmpty(event.getPackageName()) && event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
                return event.getClassName();
            } else {
                topActivityName = "";
            }
        } else {
            ActivityManager am = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
            ComponentName componentInfo = taskInfo.get(0).topActivity;
    
            topActivityName = componentInfo.getClassName();
        }
    
    
        return topActivityName;
    }
    

    AndroidUtils.java - To get the device recent screen in Hack way, Maybe we should investigate more on this, Not sure it will work on all device, but it works on almost all devices

    public class AndroidUtils {
        private static final String RECENT_ACTIVITY;
    
        static {
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
                RECENT_ACTIVITY = "com.android.systemui.recents.RecentsActivity";
            } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
                RECENT_ACTIVITY = "com.android.systemui.recent.RecentsActivity";
            } else {
                RECENT_ACTIVITY = "com.android.internal.policy.impl.RecentApplicationDialog";
            }
        }
    
        /**
         * To get the Device recent screen activity
         *
         * @param className
         * @return activity
         */
        public static boolean isRecentActivity(String className) {
            if (RECENT_ACTIVITY.equalsIgnoreCase(className)) {
                return true;
            }
    
            return false;
        }
    }