2010-05-06 18 views
6

Ceci est une question plutôt délicate car je n'ai trouvé aucune information en ligne. Fondamentalement, je souhaite savoir comment vérifier si un ordinateur est inactif en Java. Je souhaite qu'un programme ne fonctionne que si l'ordinateur est en cours d'utilisation mais s'il est inactif alors non.Java: Vérifier si le PC est inactif

La seule façon dont je peux penser à faire cela est de brancher la souris/clavier et avoir une minuterie.

MSN Messenger a cette fonctionnalité "absent", je souhaite quelque chose de similaire à cela. Rien dans le JRE indépendant de la plate-forme ne répondra à cette question.

+0

Il n'y a pas de manière portable de le faire. Quels systèmes ciblez-vous? Quelle est votre définition du ralenti? –

+0

Peut-être que vous trouvez une solution dans cette question connexe: http://stackoverflow.com/questions/614227/how-to-detect-that-a-pc-has-been-idle-for-30-seconds-using-java – Prine

Répondre

0

Vous pourriez être en mesure de deviner en mesurant l'heure de l'horloge pour un calcul, mais ce ne serait pas fiable. Sur des plates-formes spécifiques, il se peut que des API de fournisseur puissent vous aider.

+0

Ce n'est pas tellement le temps d'inactivité du système que je dois trouver. J'ai juste besoin de trouver un utilisateur qui a utilisé PC il ya moins de 10 minutes. Fondamentalement. Je souhaite que les notifications s'affichent uniquement si l'utilisateur se trouve réellement sur son PC. –

+0

Je pense que c'est encore plus impossible que l'utilisation du temps CPU. – bmargulies

2

Java n'a aucun moyen d'interagir avec le clavier ou la souris au niveau du système en dehors de votre application.

That being said here are several ways to do it in Windows. Le plus simple est sans doute de mettre en place JNI et le sondage

GetLastInputInfo

pour le clavier et l'activité de la souris.

0

1) Créer un nouveau fil.

2) Donnez-lui un super super faible priorité (le plus bas possible)

3) Chaque seconde ou deux, ont le fil faire une tâche simple. Si super rapide, au moins 1 CPU est prolly ralenti. Si c'est lent, alors au moins 1 core est prolly pas inactif.

Ou

Il suffit de lancer votre programme à une faible priorité. Cela permettra au système d'exploitation de faire en sorte que d'autres programmes fonctionnent sur votre programme.

1

Je ne suis pas un professionnel, mais j'ai une idée:

vous pouvez utiliser la classe info de la souris de la java pour vérifier la position de la souris à des intervalles certian dire comme:

import java.awt.MouseInfo; 

public class Mouse { 
    public static void main(String[] args) throws InterruptedException{ 
     while(true){ 
      Thread.sleep(100); 
      System.out.println("("+MouseInfo.getPointerInfo().getLocation().x+", "+MouseInfo.getPointerInfo().getLocation().y+")"); 
     } 
    } 
} 

remplacer la déclaration d'impression avec votre logique, comme si pour un intervalle disons 1 min la position passée de la souris est la même que la nouvelle position (vous pouvez simplement comparer seulement les coordonnées x), cela signifie que le système est inactif, et vous pouvez poursuivre votre action comme vous voulez (Espérons que c'est une activité légale que vous voulez implémenter :-)

Assurez-vous d'implémenter cela dans un nouveau thread, sinon votre programme principal va se bloquer afin de vérifier l'état inactif.

1

Vous pouvez résoudre ce problème à l'aide de la classe de robot Java.

Utilisez la classe robot pour prendre une capture d'écran, puis attendez 60 secondes et prenez une autre capture d'écran. Comparez les captures d'écran entre elles pour voir si des changements se sont produits, mais ne comparez pas les captures d'écran pixel par pixel. Vérifiez le pourcentage de pixels qui a changé. La raison en est que vous ne voulez pas de petites différences comme l'horloge de Windows pour interférer avec le résultat. Si le pourcentage est inférieur à 0,005% (ou autre), l'ordinateur est probablement inactif.

import java.awt.AWTException; 
import java.awt.DisplayMode; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.Toolkit; 
import java.awt.image.BufferedImage; 

public class CheckIdle extends Thread { 
    private Robot robot; 
    private double threshHold = 0.05; 
    private int activeTime; 
    private int idleTime; 
    private boolean idle; 
    private Rectangle screenDimenstions; 

    public CheckIdle(int activeTime, int idleTime) { 
     this.activeTime = activeTime; 
     this.idleTime = idleTime; 

     // Get the screen dimensions 
     // MultiMonitor support. 
     int screenWidth = 0; 
     int screenHeight = 0; 

     GraphicsEnvironment graphicsEnv = GraphicsEnvironment 
       .getLocalGraphicsEnvironment(); 
     GraphicsDevice[] graphicsDevices = graphicsEnv.getScreenDevices(); 

     for (GraphicsDevice screens : graphicsDevices) { 
      DisplayMode mode = screens.getDisplayMode(); 
      screenWidth += mode.getWidth(); 

      if (mode.getHeight() > screenHeight) { 
       screenHeight = mode.getHeight(); 
      } 
     } 

     screenDimenstions = new Rectangle(0, 0, screenWidth, screenHeight); 

     // setup the robot. 
     robot = null; 
     try { 
      robot = new Robot(); 
     } catch (AWTException e1) { 
      e1.printStackTrace(); 
     } 

     idle = false; 
    } 

    public void run() { 
     while (true) { 
      BufferedImage screenShot = robot 
        .createScreenCapture(screenDimenstions); 

      try { 
       Thread.sleep(idle ? idleTime : activeTime); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      BufferedImage screenShot2 = robot 
        .createScreenCapture(screenDimenstions); 

      if (compareScreens(screenShot, screenShot2) < threshHold) { 
       idle = true; 
       System.out.println("idle"); 
      } else { 
       idle = false; 
       System.out.println("active"); 
      } 
     } 
    } 

    private double compareScreens(BufferedImage screen1, BufferedImage screen2) { 
     int counter = 0; 
     boolean changed = false; 

     // Count the amount of change. 
     for (int i = 0; i < screen1.getWidth() && !changed; i++) { 
      for (int j = 0; j < screen1.getHeight(); j++) { 
       if (screen1.getRGB(i, j) != screen2.getRGB(i, j)) { 
        counter++; 
       } 
      } 
     } 

     return (double) counter 
       /(double) (screen1.getHeight() * screen1.getWidth()) * 100; 
    } 

    public static void main(String[] args) { 
     CheckIdle idleChecker = new CheckIdle(20000, 1000); 
     idleChecker.run(); 
    } 
} 
+2

Ne fonctionne pas avec un économiseur d'écran. –

+0

@Tim, vous avez raison. Doit ajouter un moniteur de souris souris aussi ... – Reg

+1

Mais encore une fois, pourquoi ne pas simplement utiliser le moniteur de la souris et jeter le reste :) – Reg