-1

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.

ScrappyDev
  • 2,307
  • 8
  • 40
  • 60
  • This is not a duplicate of the other questions. That asked for a C solution, this asked for a Java solution. – ScrappyDev Mar 24 '23 at 16:45
  • And yet the duplicate is tagged with [tag:java] and the accepted answer is Java-based, with a solution that is very similar to the one in your own answer. In other words, it is a duplicate. – Mark Rotteveel Mar 26 '23 at 11:17

2 Answers2

3

I found this when searching for a solution:

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

I modified the solution to better suit my needs:

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);
        }
    }
}
ScrappyDev
  • 2,307
  • 8
  • 40
  • 60
1

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();
Cardinal System
  • 2,749
  • 3
  • 21
  • 42