Reputation: 553
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?
Upvotes: 0
Views: 431
Reputation: 4798
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!
P.S. 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);
}
}
Upvotes: 1
Reputation: 556
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:)
Upvotes: 0