android 监听前台应用改变

在Android开发中,我们经常需要监听和获取当前正在运行的前台应用程序。这对于一些需要实时监控用户行为、应用状态变化等功能非常重要。本文将介绍如何在Android中监听前台应用的改变,并提供相应的代码示例。

监听前台应用的改变

要实现监听前台应用的改变,我们可以使用UsageStatsManager类来获取当前正在运行的应用程序信息,并通过监听系统广播来实现应用切换的检测。

步骤1:添加权限

首先,在AndroidManifest.xml文件中,需要添加以下权限:

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

这个权限允许我们获取应用程序的使用情况统计信息。

步骤2:获取前台应用信息

我们需要创建一个辅助类ForegroundAppHelper来获取前台应用的相关信息。这个类主要使用UsageStatsManagerActivityManager来实现。

public class ForegroundAppHelper {

    private static ForegroundAppHelper instance;
    private static UsageStatsManager usageStatsManager;
    private static ActivityManager activityManager;

    private ForegroundAppHelper() {
        // 获取系统服务
        usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
        activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    }

    public static ForegroundAppHelper getInstance() {
        if (instance == null) {
            instance = new ForegroundAppHelper();
        }
        return instance;
    }

    public String getForegroundApp() {
        String foregroundApp = null;
        long time = System.currentTimeMillis();

        // 获取最近使用的应用程序统计信息
        List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 10, time);

        if (usageStatsList != null && !usageStatsList.isEmpty()) {
            SortedMap<Long, UsageStats> sortedMap = new TreeMap<>();
            for (UsageStats usageStats : usageStatsList) {
                sortedMap.put(usageStats.getLastTimeUsed(), usageStats);
            }
            if (!sortedMap.isEmpty()) {
                foregroundApp = sortedMap.get(sortedMap.lastKey()).getPackageName();
            }
        }

        return foregroundApp;
    }

    public boolean isForegroundApp(String packageName) {
        List<ActivityManager.RunningTaskInfo> taskInfoList = activityManager.getRunningTasks(1);
        if (taskInfoList != null && !taskInfoList.isEmpty()) {
            ComponentName componentName = taskInfoList.get(0).topActivity;
            if (componentName.getPackageName().equals(packageName)) {
                return true;
            }
        }
        return false;
    }
}

上述代码中,我们定义了一个getForegroundApp()方法来获取当前正在运行的前台应用程序包名,以及一个isForegroundApp()方法来判断指定的应用程序是否在前台运行。

步骤3:监听前台应用的改变

我们需要创建一个BroadcastReceiver来监听系统广播,以便在应用切换时被通知。

public class ForegroundAppReceiver extends BroadcastReceiver {

    private static final String TAG = "ForegroundAppReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_ON) || intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            // 屏幕状态改变,可能发生应用切换
            String foregroundApp = ForegroundAppHelper.getInstance().getForegroundApp();
            Log.d(TAG, "Foreground app: " + foregroundApp);
        } else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
            // 屏幕解锁,可能发生应用切换
            String foregroundApp = ForegroundAppHelper.getInstance().getForegroundApp();
            Log.d(TAG, "Foreground app: " + foregroundApp);
        }
    }
}

在这个广播接收器中,我们监听了Intent.ACTION_SCREEN_ONIntent.ACTION_SCREEN_OFFIntent.ACTION_USER_PRESENT这几个系统广播,当屏幕状态发生改变或解锁时,会调用onReceive()方法,并获取当前正在运行的前台应用。

步骤4:注册广播接收器

最后,我们需要在AndroidManifest.xml文件中注册这个广播接收器。

<receiver
    android:name=".ForegroundAppReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent