简体   繁体   中英

java - screenshot taken, but permission not granted?

I am writing an application that needs to take screenshots of the users screen. I am using the Robot class and the createScreenCapture method to achieve this.

As the Javadoc states, the readDisplayPixels permission is needed to take a screenshot.

I then went ahead and tried to check the permission before attempting to take a screenshot. I prepared some code to show what I did:

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.");
        }
    }
}

The console printout is:

Permission not granted!
Screenshot taken!

I am confused right now, because I did not expect that to happen. Shouldn't the createScreenCapture method throw an exception because the permission is not granted?

You are creating some new SecurityManager instead of talking to the (maybe) existing one, so try this:

SecurityManager sm = System.getSecurityManager();
if (sm != null) {
    sm.checkPermission(new AWTPermission("readDisplayPixels"));
}

That is, if the VM has an instance of SecurityManager , you can communicate with it to check for the restriction, and if such an instance is absent - just perform any action you want to perform. Good luck with that!

PS You should never shadow stacktraces with your own messages unless they carry some useful information. In your case, you just hid some impotrtant info in favour of senseless messages. Don't do that.

And just in case I didn't make it clear - the exception in second try-catch block isn't thrown because internals of Robot do communicate with system's SecurityManager , while you were talking to some new instance, which hadn't had any useful payload. Here is the actual code from 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);
    }
}

You need to restructure your code, just a little:). You are close.

 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.");
 }

When the first security exception is thrown, they will never get to the screen capture statements.

Hope that helps:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM