9

我想从后台作业中找出apps用户在特定时间间隔(例如:5 分钟)内访问的列表?这可能在非rootandroid手机上吗?如果可能的话,我很想知道答案,因为这将是一个很好的关于 android 的学习。

4

2 回答 2

7

更新:

在 android 5.0 中,getRecentTasks() 方法的替代方法是 getAppTasks。

代码示例:

private void listTasks() throws PackageManager.NameNotFoundException {
  ActivityManager mgr = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
  List<ActivityManager.AppTask>  tasks = mgr.getAppTasks();
  String packagename;
  String label;
  for (ActivityManager.AppTask task: tasks){
    packagename = task.getTaskInfo().baseIntent.getComponent().getPackageName();
    label = getPackageManager().getApplicationLabel(getPackageManager().getApplicationInfo(packagename, PackageManager.GET_META_DATA)).toString();
    Log.v(TAG,packagename + ":" + label);
  }
}

原答案:

介绍

ActivityManager 类提供了两种返回此类信息的方法。选择 getRecentTasks 或 getRunningTasks 方法是合适的,因为返回的任务列表无论如何都不是我们的目标。但是,它将用作确定所需列表的过程中的参考点。

代码示例:

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<RecentTaskInfo> activitys = activityManager.getRecentTasks(Integer.MAX_VALUE, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
for (int i = 0; i < activitys.size(); i++) {
    RecentTaskInfo activity = activitys.get(i);
    activity.baseIntent.getComponent().getPackageName();
}

过滤:此列表包括所有类型的任务,包括系统任务。

代码示例:

if (activity.baseIntent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
    // This is an application.
    getPackageManager()
        .getApplicationLabel(getPackageManager()
        .getApplicationInfo(activity.baseIntent.getComponent()
        .getPackageName(), PackageManager.GET_META_DATA)); // application name
}

这与长按主页按钮时显示的列表相同。

抽象方法:(稍后解释)

在我们将调用(期间)的指定时间内确定所需的列表。最近的任务列表将在周期开始时以及在我们称为间隔的周期内的每个较小周期之后被要求。

最近的应用程序。在第一个间隔之后获取的列表将包含三种类型的应用程序。不符合我们兴趣的旧应用程序、新推出和重新推出的应用程序。选择抽象方法的原因是检测重新启动的应用程序。

检测新推出的应用程序:

这些是应用程序。这根本没有出现在第一个获取的列表中。(期间之前)。

通过示例解释为什么这种方法:

  • 考虑任何应用程序都是一个好主意。出现在您的应用程序之前。在后来获取的列表中,重新启动了一个应用程序。因为当我们开始操作时,它是从应用程序内部开始的,你的应用程序。名列榜首。

在此处输入图像描述

  • 但是,你的应用程序。可能会从顶部下台并在间隔时间内回到它。(Facebook > Twitter > 你的应用程序)。

在此处输入图像描述

  • 在稍后获取的列表中,另一个应用程序。可能会登上顶峰。由于您的应用程序的相同原因,将其作为参考也会失败。失败作为参考。

制胜法宝:

在间隔之前获取的列表将作为在间隔之后获取的列表的引用。重新启动的应用程序。将是应用程序。出现在第一排序子列表(fosl)之前。

在此处输入图像描述

所有的应用程序。在 fosl 重新启动之前,不仅是 What's app。而且,它可以很容易地证明。没有办法重新排列 fosl 上的应用程序,因为其中一些应用程序可能在不更改 fosl 的情况下重新启动(变大以包含更多应用程序)。你可以锻炼它。

即使用户删除了一些应用程序,fosl 方法也将起作用。在间隔内手动从列表中。如果在之前的时间间隔内未检测到已删除的应用程序,则不会检测到它们。但是,它不会影响列表中其余部分的 fosl 方法。如果用户清除了所有列表,只有清除的应用程序,同样的事情。不会检测到,也不会在同一时间间隔内启动。

为什么要间隔?因为在这么长的一段时间内,用户可以打开和重新启动应用程序。然后,清除列表或删除一些。

小的间隔也会使用户很难再次打开具有相同顺序的任何顶部子列表,这是 fosl 方法的唯一弱点。

示例代码:(fosl)

public int getIndexOfFirstAppBeforeFOSL(ArrayList<App> recentApps) {
    int i=previousRecentApps.size()-1, j = recentApps.size()-1;
    for (; i>=0 && j>=0 ; i--) {
        App app = previousRecentApps.get(i);
        if (app.equals(recentApps.get(j))) {
            j--;
        } else {
            // this application got re-launched and therefore it changed it place in list.
            // or removed manually by user.
        }
    }

    return j;
}

我为该应用程序创建了一个GitHub 项目。检查一下,如果有错误报告。

没有检测到我们提到的弱点的一两个应用程序真的会影响您从收集应用程序中获得的研究结果。从大量用户那里启动。如果那你在做什么呢。否则,您的应用程序。可以经常获得新推出的应用程序。并通知用户。

于 2014-12-11T01:00:58.273 回答
-1

是的。有可能。您的服务需要每 5 秒运行一次。在该服务中,您必须为用户访问的任何应用程序编写逻辑。您必须使用 ActivityManager 类来获取正在运行的应用程序。

于 2014-12-07T19:48:57.910 回答