I need to create a simple application to keep my computer from idling and going to sleep.
I'd prefer it to be in java, but am happy to look at other solutions as long as I don't need to install a 3rd party application.
I need to create a simple application to keep my computer from idling and going to sleep.
I'd prefer it to be in java, but am happy to look at other solutions as long as I don't need to install a 3rd party application.
https://code.joejag.com/2013/move-your-mouse-pointer-with-java.html
However, it didn't quite work for me since it moved the mouse pointer all over the place at random. This means I could only use the application when I was not using my computer
https://code.joejag.com/2013/move-your-mouse-pointer-with-java.html
import java.awt.Robot;
import java.util.Random;
public class MouseMover {
public static final int FIVE_SECONDS = 5000;
public static final int MAX_Y = 400;
public static final int MAX_X = 400;
public static void main(String... args) throws Exception {
Robot robot = new Robot();
Random random = new Random();
while (true) {
robot.mouseMove(random.nextInt(MAX_X), random.nextInt(MAX_Y));
Thread.sleep(FIVE_SECONDS);
}
}
}
This version gets the mouse pointer's current location and moves the mouse to where it already is. From a user perspective the mouse doesn't move, but it does prevent the computer from going idle.
import java.awt.*;
public class MouseJiggle {
public static final int SLEEP_MILLIS = 60*1000;
public static void main(String... args) throws Exception {
Robot robot = new Robot();
while (true) {
Point point = MouseInfo.getPointerInfo().getLocation();
robot.mouseMove(point.x, point.y);
System.out.println("Mouse Moved!!");
Thread.sleep(SLEEP_MILLIS);
}
}
}
If you are using Windows, you can call the WinAPI SetThreadExecutionState
function to prevent the computer from sleeping.
To achieve this, first I created a class file with native function definitions:
package com.example.natives;
public class WindowsSleep {
private static final boolean IS_WINDOWS;
static {
IS_WINDOWS = System.getProperty("os.name").toLowerCase().contains("win");
System.load("windows-sleep.dll");
}
private static native void preventSleep();
private static native void allowSleep();
public static void doPreventSleep() {
if (IS_WINDOWS)
preventSleep();
else
throw new UnsupportedOperationException("This operation only works on Windows machines");
}
public static void doAllowSleep() {
if (IS_WINDOWS)
allowSleep();
else
throw new UnsupportedOperationException("This operation only works on Windows machines");
}
}
Then I used javah to generate the following header file:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_natives_WindowsSleep */
#ifndef _Included_com_example_natives_WindowsSleep
#define _Included_com_example_natives_WindowsSleep
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_natives_WindowsSleep
* Method: preventSleep
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_natives_WindowsSleep_preventSleep
(JNIEnv *, jclass);
/*
* Class: com_example_natives_WindowsSleep
* Method: allowSleep
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_natives_WindowsSleep_allowSleep
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
After creating the header file, I wrote the following C++ code:
#include "windows-sleep.h"
#include <jni.h>
#include <Windows.h>
JNIEXPORT void JNICALL Java_com_example_natives_WindowsSleep_preventSleep(JNIEnv *, jclass) {
SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED | ES_CONTINUOUS);
}
JNIEXPORT void JNICALL Java_com_example_natives_WindowsSleep_allowSleep(JNIEnv *, jclass) {
SetThreadExecutionState(ES_CONTINUOUS);
}
Then I used a makefile to compile it:
# Variables
CC = g++
JNI_PATH = C:/Program Files/Java/jdk1.8.0_202/include
JNI_MD_PATH = $(JNI_PATH)/win32
CFLAGS = -Wall -I'$(JNI_PATH)' -I'$(JNI_MD_PATH)' -shared
# Output file
OUTPUT = windows-sleep.dll
# Source file
SOURCE = windows-sleep.cpp
# Rule to build the DLL
all: $(OUTPUT)
$(OUTPUT): $(SOURCE)
$(CC) $(CFLAGS) $^ -o $@
# Rule to clean the build artifacts
clean:
rm -f $(OUTPUT)
After compiling the DLL, I was able to call doPreventSleep
to prevent my computer from sleeping. Keep in mind that you have to keep calling this method - you cannot just invoke it once. Here's an example:
ThreadFactory factory = r -> {
Thread thread = new Thread(r);
// Use daemon threads so they don't keep the JVM alive
thread.setDaemon(true);
return thread;
};
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(factory);
// Call doPreventSleep every 5 minutes
executor.scheduleAtFixedRate(() -> WindowsSleep.doPreventSleep(), 0, 5, TimeUnit.MINUTES);
// Do stuff
executor.shutdownNow();