java-截图已拍摄,但未授予权限?

java-截图已拍摄,但未授予权限?,java,permissions,screenshot,Java,Permissions,Screenshot,我正在编写一个应用程序,需要截图的用户屏幕。 我正在使用Robot类和方法来实现这一点 正如Javadoc所述,拍摄屏幕截图需要readDisplayPixels权限 然后,我继续进行,并试图检查许可,然后再试图采取截图。 我准备了一些代码来展示我所做的: import java.awt.AWTPermission; import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt

我正在编写一个应用程序,需要截图的用户屏幕。 我正在使用Robot类和方法来实现这一点

正如Javadoc所述,拍摄屏幕截图需要
readDisplayPixels
权限

然后,我继续进行,并试图检查许可,然后再试图采取截图。 我准备了一些代码来展示我所做的:

import java.awt.AWTPermission;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;

public class ScreenshotTest {
    public static void main(String[] args) {
        try {
            new SecurityManager().checkPermission(new AWTPermission("readDisplayPixels"));
        } catch (SecurityException e) {
            System.out.println("Permission not granted!");
        }

        try {
            Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
            BufferedImage capture = new Robot().createScreenCapture(screenRect);
            System.out.println("Screenshot taken!");
        } catch (Exception e) {
            System.out.println("Taking screenshot failed.");
        }
    }
}
控制台打印输出为:

Permission not granted!
Screenshot taken!

我现在很困惑,因为我没想到会发生这种事。
createScreenCapture
方法不应该因为未授予权限而引发异常吗?

您需要重新构造代码,只需一点:)。你很接近

 try {
     new SecurityManager().checkPermission(new AWTPermission("readDisplayPixels"));
     Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
     BufferedImage capture = new Robot().createScreenCapture(screenRect);
     System.out.println("Screenshot taken!");
 }  catch (SecurityException e) {
     System.out.println("Permission not granted!");
 }  catch (Exception e) {
     System.out.println("Taking screenshot failed.");
 }
当抛出第一个安全异常时,它们将永远不会进入屏幕捕获语句


希望有帮助:)

您正在创建一些新的
SecurityManager
,而不是与(可能)现有的安全管理器对话,因此请尝试以下操作:

SecurityManager sm = System.getSecurityManager();
if (sm != null) {
    sm.checkPermission(new AWTPermission("readDisplayPixels"));
}
也就是说,如果虚拟机有一个
SecurityManager
实例,您可以与其通信以检查限制,如果没有这样的实例,只需执行您想要执行的任何操作即可。祝你好运

另外,你不应该用你自己的信息来掩盖这些信息,除非它们包含一些有用的信息。在你的例子中,你只是隐藏了一些重要的信息来支持无意义的信息。不要那样做

为了以防万一,我没有说清楚-第二个
try catch
块中的异常不会被抛出,因为
Robot
的内部确实与系统的
SecurityManager
通信,而您正在与一些没有任何有用负载的新实例进行通信。下面是来自
Robot.java
的实际代码:

public synchronized BufferedImage createScreenCapture(Rectangle screenRect) {
    checkScreenCaptureAllowed();
    //... proceed
}

private static void checkScreenCaptureAllowed() {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkPermission(
            SecurityConstants.AWT.READ_DISPLAY_PIXELS_PERMISSION);
    }
}

第一个
try/catch
块中
SecurityException e
的堆栈跟踪是什么?@Mateusz堆栈跟踪:java.security.AccessControlException:java.security.accesscontrolpermission的访问被拒绝(“java.awt.AWTPermission”“readDisplayPixels”)。java.security.AccessController.checkPermission的checkPermission(未知源)(未知源)位于java.lang.SecurityManager.checkPermission(未知源)位于exp.ScreenshotTest.main(ScreenshotTest.java:12)在问题中,它们是独立的try-catch块。问题是为什么没有从第二个try-catch抛出异常?抱歉,我可能不够清楚。在第一个代码段中,我显式检查是否授予了
readDisplayPixels
权限。在第二个代码段中,我只是截图。如果权限被授予在第一个块中没有授予,第二个块也应该抛出一个异常,因为
createScreenCapture
的javadoc声明:
抛出SecurityException-如果未授予readDisplayPixels权限
。谢谢,我想这就是解决方案!我尝试了
System.getSecurityManager()
现在,它返回null,所以我不会检查权限。我最初的想法是,这些权限是由操作系统或JVM授予的,我可以检查它们。注意:通常我不会像上面的代码那样处理异常,这应该是一个SSCCE,以使我的观点得到理解。编辑:感谢Robot.j提供的代码ava。@greenkeeper,不客气。顺便说一句,你可以通过捕获相应的
SecurityException
来消除第一次检查,作为你截图的
try
块的一部分。嗯,我的实际代码比我发布的代码复杂一点。在我的应用程序中,我启动了一个新线程,我可以在循环中创建屏幕截图,这就是为什么我想在启动线程之前检查权限。