21

我使用以下代码在变量foregroundTaskPackageName中获取前台应用程序的活动名称。它适用于 4.1 到 4.4 之间的所有操作系统版本,但不适用于 Android 5.0 Lollipop。

任何人都可以帮助解决 5.0 Lollipop 中的变化吗?在 Lollipop 中 - 我为foregroundTaskPackageName得到的文本只是“Launcher3”。我正在使用 Genymotion 模拟器。

ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0); // get
                                                                        // list
                                                                        // of
                                                                        // running
                                                                        // tasks
String foregroundTaskAppName = null;
String foregroundTaskPackageName = foregroundTaskInfo.topActivity
                .getPackageName();
4

7 回答 7

29

这适用于棒棒糖(21):

    ActivityManager manager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);

    List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();

    Log.i("current_app",tasks.get(0).processName);
于 2015-01-06T12:48:17.940 回答
9

您需要使用 newUsageStatsManager并调用其queryUsageStats方法来获取已启动活动的历史记录。请注意,用户需要在安全->具有使用访问权限的应用程序中的设备设置上提供使用统计访问权限。

链接:

UsageStatsManager文件

queryUsageStats方法文档

于 2014-11-23T11:24:08.543 回答
7

您可以使用下面的代码并获取当前的前台活动包名称。

 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        // intentionally using string value as Context.USAGE_STATS_SERVICE was
        // strangely only added in API 22 (LOLLIPOP_MR1)
        @SuppressWarnings("WrongConstant")
        UsageStatsManager usm = (UsageStatsManager) getSystemService("usagestats");
        long time = System.currentTimeMillis();
        List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,
                        time - 1000 * 1000, time);
                if (appList != null && appList.size() > 0) {
                    SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
                    for (UsageStats usageStats : appList) {
                        mySortedMap.put(usageStats.getLastTimeUsed(),
                                usageStats);
                    }
                    if (mySortedMap != null && !mySortedMap.isEmpty()) {
                        currentApp = mySortedMap.get(
                                mySortedMap.lastKey()).getPackageName();
                    }
                }
    } else {
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> tasks = am
                        .getRunningAppProcesses();
                currentApp = tasks.get(0).processName;
    }

将这些权限添加到清单文件中(第一个用于 < API 21,第二个用于 >= API 21)。

<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
于 2015-11-24T05:48:58.723 回答
4

根据getRunningTasks()文档:

此方法在 API 级别 21 中已弃用。从 LOLLIPOP 开始,此方法不再可用于第三方应用程序:引入以文档为中心的最新消息意味着它可以将个人信息泄露给调用者。为了向后兼容,它仍然会返回其数据的一小部分:至少是调用者自己的任务,可能还有其他一些已知不敏感的任务,例如 home。

于 2014-11-23T10:19:28.103 回答
2

我创建了一个使用/system/bin/toolbox命令来识别进程然后识别可见应用程序的类。需要添加识别没有 UI 和 android 启动器的系统应用程序。

进程管理器.java

于 2016-08-18T07:22:16.810 回答
2

一个可用但不是最好的方法是使用可访问性。

在 AndroidManifest xml 文件中声明无障碍服务

<service
            android:name=".MyAccessibilityService"
            android:label="@string/accessibility_service_label"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>

            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/accessibility_service_config" />
        </service>

access_service_config.xml 文件

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_desc"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
/>

当窗口状态改变时存储活动名称

public class MyAccessibilityService extends AccessibilityService{
    public static String sActivityName;
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        // TODO Auto-generated method stub
        if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){
            Log.d("activitytest", "onAccessibilityEvent with window state changed");
            sActivityName = event.getClassName().toString();
        }
    }

    @Override
    public void onInterrupt() {
        // TODO Auto-generated method stub

    }

}

缺点是您需要让用户在设置中启用您的无障碍服务。

于 2015-08-20T03:27:19.017 回答
0

尝试这个

public static boolean isForeground(Context context) {
    ActivityManager manager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> tasks = manager.getRunningAppProcesses();
    if(tasks.isEmpty())
        return false;

    for (ActivityManager.RunningAppProcessInfo task : tasks) {
        if(context.getPackageName().equalsIgnoreCase(task.processName)){
            return task.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
        }
    }
    return false;
}
于 2016-07-21T04:04:26.067 回答