【问题标题】:Android, how to get app on foregroundAndroid,如何在前台获取应用程序
【发布时间】:2016-09-28 05:20:40
【问题描述】:

我正在尝试开发一种服务,只要用户打开应用程序,我的服务就会识别它。我正在使用以下文件:/proc/[pid]/cgroup,/proc/[pid]/cmdline,/proc/[pid]/oom_score,/proc/[pid]/oom_score_adj 来检查它是否是正在运行的用户应用程序在前台。实际上它正在工作,但是当我尝试打开任何游戏时,服务不会一直识别它。 (该服务仅识别具有最低值的文件(oom_score)。

示例:“com.google.android.googlequicksearchbox:interactor”的 oom_score 为 75,但“com.king.candycrushsaga”的 oom_score 为 >150,因此代码永远不会检测到它(如下所示)。

服务代码:

scheduler.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        s=appManager.getAppRunningForeground();
        System.out.println(s);
    }
},1,2,SECONDS);

让应用程序运行的函数:

private ReadWriteFile readWriteFile = new ReadWriteFile();
public String getAppRunningForeground(){
    int pid;
    File[] files = new File("/proc").listFiles();
    int lowestOomScore = Integer.MAX_VALUE;
    String foregroundProcess = null;
    for (File file : files) {
        if (!file.isDirectory() || (!file.getName().matches(("\\d+"))))
            continue;
        pid = Integer.parseInt(file.getName());
        try {
            String cgroup = readWriteFile.read(String.format("/proc/%d/cgroup", pid));
            String[] lines = cgroup.split("\n");
            if (lines.length != 2)
                continue;
            String cpuSubsystem = lines[0];
            String cpuaccctSubsystem = lines[1];
            if (!cpuaccctSubsystem.endsWith(Integer.toString(pid)) || cpuSubsystem.endsWith("bg_non_interactive"))
                continue;
            String cmdline = readWriteFile.read(String.format("/proc/%d/cmdline", pid));
            if (cmdline.contains("com.android.systemui")||cmdline.contains("com.google.android.googlequicksearchbox:interactor")) {
                continue;
            }
            int uid = Integer.parseInt(cpuaccctSubsystem.split(":")[2].split("/")[1].replace("uid_", ""));
            if (uid > 1000 && uid <= 1038)//System process
                continue;
            File oomScoreAdj = new File(String.format("/proc/%d/oom_score_adj", pid));
            if (oomScoreAdj.canRead()) {
                int oomAdj = Integer.parseInt(readWriteFile.read(oomScoreAdj.getAbsolutePath()));
                if (oomAdj != 0) {
                    continue;
                }
            }
            int oomscore = Integer.parseInt(readWriteFile.read(String.format("/proc/%d/oom_score", pid)));
            if (oomscore < lowestOomScore) {
                lowestOomScore = oomscore;
                foregroundProcess = cmdline.replaceAll("\\p{Cntrl}", "");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return foregroundProcess;
}

读取文件的类。

public class ReadWriteFile{
    File file;
    StringBuilder teste3 = new StringBuilder();
    FileOutputStream outputStream;
    public static String read(String path) throws IOException {
        StringBuilder output = new StringBuilder();
        BufferedReader reader = new BufferedReader(new FileReader(path));
        output.append(reader.readLine());
        for (String line = reader.readLine(); line != null; line = reader.readLine())
            output.append('\n').append(line);
        reader.close();
        return output.toString();
    }
}

P.S:getRunningTasks 已被弃用,所以请不要推荐它。

【问题讨论】:

    标签: android service foreground


    【解决方案1】:

    您可以使用在 android api 21 中添加的UsageStatsManager 类。参见this me提出并回答的问题。

    上面的答案会为你提供一个排序后的应用程序ArrayList,需要的前台应用程序会在ArrayList中的第一个索引号为0。

    希望这会有所帮助。

    【讨论】:

    • 非常感谢先生。 Gagan Deep 在我绝望的时候,他在凌晨 1:30 给我发了关于这门课的邮件。
    【解决方案2】:

    这些方法可以帮助你

      void checkForegroundAppCompat()
            {
                ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
                final List<ActivityManager.RunningTaskInfo> taskInfo = activityManager.getRunningTasks(1);
                final ComponentName componentName = taskInfo.get(0).topActivity;
                if(!getWhiteListedPackages().contains(componentName.getPackageName()) &&
                        SecurityStatusManager.isAppsBlockingEnabled(this))
                {
                    int pid = android.os.Process.getUidForName(componentName.getPackageName());
    // Kill blick APP here               
      GRLog.w("KILL Blacklist App Package: " + componentName.getPackageName() + " with pid: " + pid);
                    killApp(componentName.getPackageName(), pid);
                }
            }
    

    【讨论】:

    • getRunningTasks 如我所说已被弃用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-19
    • 1970-01-01
    • 2012-11-26
    相关资源
    最近更新 更多