获取前台应用的打开活动

Cap*_*tto 0 service android foreground

我需要获取前台应用程序的当前活动。我尝试遵循这个答案,后来使用了这个库(因为第一个解决方案仅适用于 Lollipop),并且它们确实在告诉前台应用程序的包名称时运行良好,但我需要知道哪些活动是打开的。

Mut*_*ran 6

嘿@Capitan Luzzatto,

  • 在 LOLLIPOP(API 21) 之前,我们可以从 ActivityManager 获取正在运行的应用程序列表
  • 但是从 LOLLIPOP 我们应该只从 UsageStatsManager 中获取

首先,您需要 2 个权限才能读取任务

<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
Run Code Online (Sandbox Code Playgroud)

您应该首先检查用户 API 级别是否为 21 或更高,如果是,您应该获得如下使用权限设置的访问权限

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);
        }
 }
Run Code Online (Sandbox Code Playgroud)

获取使用情况统计列表

    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;
}
Run Code Online (Sandbox Code Playgroud)

最后,您可以使用以下方法获取最新的 Foreground 应用程序

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;
}
Run Code Online (Sandbox Code Playgroud)

要获得前台活动,请使用这样的方法

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;
}
Run Code Online (Sandbox Code Playgroud)

AndroidUtils.java - 要以 Hack 方式获取设备最近的屏幕,也许我们应该对此进行更多调查,不确定它是否适用于所有设备,但几乎适用于所有设备

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;
    }
}
Run Code Online (Sandbox Code Playgroud)