Android 如何使用后台作业查找用户在一定时间间隔内访问的应用程序列表?

Android 如何使用后台作业查找用户在一定时间间隔内访问的应用程序列表?,android,android-activity,android-background,Android,Android Activity,Android Background,我想从后台作业中找出用户在特定时间间隔(例如:5分钟)内访问的应用程序的列表? 这在非根android手机上可能吗?如果可能的话,我非常有兴趣知道答案,因为这将是对android的一次很好的学习。是的。这是可能的。您的服务需要每5秒运行一次。在该服务中,您必须为用户访问的任何应用编写逻辑。您必须使用ActivityManager类来获取正在运行的应用程序 更新: private void listTasks() throws PackageManager.NameNotFoundExceptio

我想从后台作业中找出用户在特定时间间隔(例如:5分钟)内访问的
应用程序的列表?

这在非根
android
手机上可能吗?如果可能的话,我非常有兴趣知道答案,因为这将是对android的一次很好的学习。

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

更新:

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 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
}
在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 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
}
这与长按home(主页)按钮时显示的列表相同

抽象方法:(稍后解释)

在指定时间内确定所需列表,我们将 通话(句号)。将在中请求最近的任务列表 期初和期内每个较小的期后 我们称之为间隔的时间段

最近的应用程序。在第一个间隔后获取的列表将包含 三种类型的应用程序。不符合我们利益的旧应用程序, 新发布和重新发布的应用程序。为什么选择 抽象方法是检测重新启动的应用程序

检测新发布的应用程序:

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 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
}
这些是应用程序。这在一开始就没有出现 获取的列表。(在此期间之前)

举例说明为什么采用这种方法:

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 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>你的应用程序)

  • 在稍后获取的列表中,另一个应用程序。可能会在上面。将其作为参考也会失败,原因与您的应用程序相同。作为引用失败
获胜方法:

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 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
}
间隔之前获取的列表将作为列表的引用 在间隔之后获取。重新启动的应用程序。将是应用程序。 出现在第一个有序子列表(fosl)之前

所有的应用程序。在fosl重新启动之前,不仅仅是什么应用程序。而且,这很容易被证明。没有办法在fosl上重新安排应用程序,使其中一些应用程序在fosl未更改的情况下重新启动(变得更大以包含更多应用程序)。你可以锻炼它

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

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

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

示例代码:(fosl)

public int getIndexOfFirstAppBeforeFOSL(应用程序的ArrayList)。请检查它,如果有错误,请报告


由于我们提到的弱点,未能检测到一个或两个应用程序。我们真的希望能够影响您从收集应用程序中获得的研究结果。从大量用户处启动。如果这样,您到底在做什么。否则,您的应用程序可以经常获得新启动的应用程序。并通知用户。重新启动是否足够d在这段时间内访问的应用程序?我只需要在这段时间内访问的应用程序名称。你检查了我的答案吗?虽然应用程序有一个错误。在方法中没有,但在打开许多程序后它会被破坏。从服务调用该方法可以解决问题。并且直接发送到web服务。或者在e设备。我的应用程序将它们显示在列表视图中以供测试。它将从UI中丢失。即使我们有服务。我们也需要存储它们。@hasan83谢谢你的回答,但在android 5
getRecentTasks()
不推荐用于用户隐私。是否有其他解决方案。是的,我知道。到目前为止,我没有调查。但我不这么认为。我会调查并更新我的答案。看看这个,现在已经很晚了。我在最后几分钟对代码项目进行了修改。我可以说,一切都很好。方法是理论性的ly看起来很完美。报告我项目代码中的错误。我会修复。不管怎样,这是一个有趣的问题。请注意,从Android 5.0开始,当
getRecentTasks()时,您的技术将不再有效
不再满足您的需要。是的,这是真的。但它仍将在大约一年内适用于80%的设备,在不到一年的时间内适用。如果有5.0版的解决方案,我将更新我的答案。非常感谢您没有忘记分配奖金:)但是,我没有看到绿色的复选标记表示答案被接受!