安卓后台服务以确定前台应用程序

3
我正在开发一个应用程序,它将在一整天内监控手机的使用情况。为此,我有一个后台服务,在设备启动时启动,并不断轮询以查找当前前台应用程序。当我只是点击一个应用程序然后退出并点击另一个应用程序时,下面的代码可以正常工作。现在假设我打开浏览器并转到另一个网页,它将停止注册浏览器作为前台应用程序。或者例如,我打开谷歌聊天,它将注册它作为当前活动,但当我发送消息时,它将不再注册为前台应用程序。你认为这个 bug 的原因可能是什么?如果需要,我会提供任何额外的信息,请告诉我。
也许答案就在这篇帖子里,但我找不到... 从后台任务或服务确定当前前台应用程序
public static RunningAppProcessInfo getForegroundApp() throws NameNotFoundException{
    RunningAppProcessInfo result = null, info = null;
    String currApp = null;
    am = (ActivityManager)context.getSystemService(ACTIVITY_SERVICE);
    Drawable icon = null;
List <RunningAppProcessInfo> l = am.getRunningAppProcesses();
Iterator <RunningAppProcessInfo> i = l.iterator();
PackageManager pm = context.getPackageManager();

while(i.hasNext()){
    info = i.next();
        if(info.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && getActivityForApp(info)!=null ){

            try {
                currApp = getCurrentApplication(info);
                System.out.println(currApp);
                System.out.println(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
                icon = pm.getApplicationIcon(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
                System.out.println(getActivityForApp(info));
            } catch (NameNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            }
        }
    break;       
}

return result;

}

private static ComponentName getActivityForApp(RunningAppProcessInfo target){
    ComponentName result=null;
    ActivityManager.RunningTaskInfo info;

    if(target==null)
        return null;

    if(am==null)
        am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
    List <ActivityManager.RunningTaskInfo> l = am.getRunningTasks(9999);
    Iterator <ActivityManager.RunningTaskInfo> i = l.iterator();

    while(i.hasNext()){
        info=i.next();
        if(info.baseActivity.getPackageName().equals(target.processName)){
            result=info.topActivity;
            break;
        }
    }
    return result;
}
3个回答

6
以下代码适用于我。列表中的第一个任务是我需要确定前台应用程序名称的任务。
ActivityManager activityManager = (ActivityManager) getSystemService(UpdateService.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> appProcesses = activityManager.getRunningTasks(1);

Log.i("MyApp", "Foreground Package: " + appProcesses.get(0).topActivity.getPackageName());

2

找到了答案,这就是我是如何做到的。我只是从后台服务中调用getForegroundApp()。

   public String getForegroundApp() throws NameNotFoundException{ 

        RunningTaskInfo info = null;
        ActivityManager am;
        am = (ActivityManager)mContext.getSystemService(ACTIVITY_SERVICE);
        List<RunningTaskInfo> l = am.getRunningTasks(1000);
        System.out.println(l);
        Iterator <RunningTaskInfo> i = l.iterator();


        String packName = new String();
        String appName = new String();
        ApplicationInfo appInfo = new ApplicationInfo();

        while(i.hasNext()){
            info = i.next();
            packName = info.topActivity.getPackageName();
            if(!packName.equals("com.htc.launcher") && !packName.equals("com.android.launcher")){ //this could be what is causing the problem. not sure.
                packName = info.topActivity.getPackageName();
                break;
            }
            info = i.next();
            packName= info.topActivity.getPackageName();
            break;          
            }
        return packName;
        }

我知道这不是最好的方法,尤其是我是通过判断启动器是否打开来确定的,因为除了我列出的两个之外,还有更多的启动器。但对于我的用例来说,这很有效,所以我想分享一下。


0

这是一个旧线程,但我想在这里补充一点,即getRunningsTasks()在API级别21中已被弃用,因此使用getRunningsTasks()的上述解决方案将不起作用。请参见

https://developer.android.com/reference/android/app/ActivityManager

getRunningTasks(int maxNum) - 此方法在API级别21中已被弃用。从Build.VERSION_CODES.LOLLIPOP开始,此方法不再对第三方应用程序可用:引入面向文档的最近使用列表意味着它可能会向调用者泄漏个人信息。为了向后兼容,它仍将返回其数据的一小部分:至少是调用者自己的任务,以及可能一些其他已知不敏感的任务,例如主页。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接