【问题标题】:How to detect the active application using C/java?如何使用 C/java 检测活动应用程序?
【发布时间】:2018-03-19 11:44:24
【问题描述】:

我想记录活动应用程序并保存我活动应用程序的历史记录。我说活动应用程序是因为如果我运行一个应用程序并且它被最小化等,我不会将其视为活动应用程序。 为了让我的问题更清楚,让我们看一下这个例子。 我打开 Firefox 并在网上冲浪 20 分钟。然后我打开一个文本编辑器并开始写作 5 分钟(Firefox 正在运行但我不使用它,因此不应将 Firefox 视为活动应用程序)。所以我应该能够记录以下信息:

Firefox -> 20 minutes 
Text editor -> 5 minutes

我想在操作系统(首选 Linux)运行期间跟踪每个使用过的应用程序,并制作一个开源应用程序,说明您使用每个应用程序的程度。

更新:我要记录的应用程序是用户在显示屏上看到并正在使用的应用程序。例如,您可能会更改窗口大小,以使您可以同时看到 Firefox 和文本编辑器(同时在不同的工作空间、级联等),但是您正在输入文本编辑器,因此,文本编辑器是主动申请。换句话说,如果您正在与之交互或者是您正在查看以阅读 pdf、文本等形式的某些内容的最后一个交互应用程序,则该应用程序处于活动状态。与应用程序交互:我的意思是单击、键入、滚动等。

NARROWING : 我唯一想不通的是如何在这些条件下获得活动应用程序。我认为,如果我在当前工作区的显示器上获得可以解决问题的最顶级应用程序,但是,我们有一个属性可以设置为一个窗口(始终在顶部),如果不启用此属性,可能需要获得该属性。我发现this question 可能有助于回答。

使用 Fedora 26,

提前致谢。

【问题讨论】:

  • 没有核心 Java 解决方案,因为 Java 被专门编写为尽可能与操作系统无关。对于解决方案,您需要使用 3rd 方库(题外话)或使用通过 JNI / JNA 链接到 Java 的 C/C++ 解决方案。
  • @Martin:在这方面几乎所有语言都比 Java 好。同样,Java 被编写为尽可能远离金属和平台,因此您没有找到所需功能的原因是它不是故意。使用 C/C++ 更好,如果是 Windows,则可能是 C#。
  • 太晚了。我已经用完了我的重新开放投票。该死的系统。
  • @Martin 您需要为问题添加更多约束... 那么这是一个 X 应用程序,用户运行连接到显示器并且只能看到该显示器上的应用程序,是吗?
  • 我赞成这个问题,因为我需要类似的代码(在 X11 中)。

标签: java c linux operating-system x11


【解决方案1】:

感谢贡献者,我找到了一个解决方案来做我所要求的。我找到了this github 项目,它在 C 中做了类似的工作,然后在 java 中实现了一个解决方案(我更喜欢它,因为 maven 和 JavaFX)。

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class Main {
    private static final DateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    public static void main(String[] args) throws IOException, InterruptedException {
        System.out.println("Start :");

        while(true) {
            Date date = new Date();      
            Process proc = Runtime.getRuntime().exec("xdotool getactivewindow getwindowname");
            java.io.InputStream is = proc.getInputStream();
            java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
            String val = "";
            if (s.hasNext()) {
                val = s.next();
            }
            else {
                val = "";
            }
            System.out.print(val +" " + "at:");
            System.out.println(sdf.format(date));
            TimeUnit.SECONDS.sleep(10);
        }
    }
}

它每 10 秒返回活动窗口名称并打印正在使用的应用程序的标题:

Start :
ApplineBuilder - NetBeans IDE 8.2
 at:2017/10/12 02:58:58
ApplineBuilder - NetBeans IDE 8.2
 at:2017/10/12 02:59:08
GoldenDict
 at:2017/10/12 02:59:18
 at:2017/10/12 02:59:28
How to detect the active application using C/java? - Stack Overflow - Mozilla Firefox
 at:2017/10/12 02:59:38
ApplineBuilder - NetBeans IDE 8.2
 at:2017/10/12 02:59:48
Cancel Running Task
 at:2017/10/12 02:59:58

【讨论】:

    【解决方案2】:
    1. 应用程序是否“最小化”不是 Linux 进程的属性。相反,它由您的“桌面管理器:软件(例如 Gnome)管理,而后者又位于 X Windows 之上。

    2. 换句话说,要找出哪些应用程序“最小化”,哪些不是,您通常必须查询 X Windows。例如:

    How can you check if a window is minimized via the terminal in linux

    if xwininfo -all -id $windowIdGoHere |grep "Hidden"; then
      echo "is hidden"
    fi
    
    1. 如果“xwininfo”对您有用……那么您当然可以从 Java 中调用它,例如使用 Process p = Runtime.getRuntime().exec(...)

    【讨论】:

    • 为什么要获得最小化的应用程序?
    • 再次重申:从操作系统的角度来看,您的应用程序“一直在运行”。无论是“最小化”(我从您的原始描述中想到的)还是只是“不聚焦”......都是您的桌面窗口管理器的财产。其中,对于 Linux,我们通常使用 X Windows 实现。因此,对于 Linux,“X windows”可能是您想要查看的地方。 “xwininfo”是一个很好的起点。 '希望有帮助。
    • 谢谢,我找到了另一个命令xdotool,并根据您的回答提供了解决方案。
    猜你喜欢
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多