2010-08-08 12 views

Respuesta

37

Supongo que estás hablando de una computadora portátil. No existe tal API en la API estándar de Java SE. Esta información está disponible solo en la API nativa de la plataforma del sistema operativo. Necesitará al menos JNI o JNA(JavaWorld article) para poder comunicarse con la API nativa de la plataforma.

En Windows, desea conectar el SYSTEM_POWER_STATUS structure. Ofrece, entre otros, la propiedad BatteryLifePercent que puede ser de su interés. Encontré un fragmento de código basado en JNA útil en un tema antiguo de forums.sun.com que ya no está disponible en este momento. Entonces el crédito en realidad va al Autor cuyo nombre no se conocerá.

Para conseguir que funcione, primera gota jna.jar en la ruta de clase y luego copiar la siguiente clase sin modificar en su proyecto:

package com.example; 

import java.util.ArrayList; 
import java.util.List; 

import com.sun.jna.Native; 
import com.sun.jna.Structure; 
import com.sun.jna.win32.StdCallLibrary; 

public interface Kernel32 extends StdCallLibrary { 

    public Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("Kernel32", Kernel32.class); 

    /** 
    * @see http://msdn2.microsoft.com/en-us/library/aa373232.aspx 
    */ 
    public class SYSTEM_POWER_STATUS extends Structure { 
     public byte ACLineStatus; 
     public byte BatteryFlag; 
     public byte BatteryLifePercent; 
     public byte Reserved1; 
     public int BatteryLifeTime; 
     public int BatteryFullLifeTime; 

     @Override 
     protected List<String> getFieldOrder() { 
      ArrayList<String> fields = new ArrayList<String>(); 
      fields.add("ACLineStatus"); 
      fields.add("BatteryFlag"); 
      fields.add("BatteryLifePercent"); 
      fields.add("Reserved1"); 
      fields.add("BatteryLifeTime"); 
      fields.add("BatteryFullLifeTime"); 
      return fields; 
     } 

     /** 
     * The AC power status 
     */ 
     public String getACLineStatusString() { 
      switch (ACLineStatus) { 
       case (0): return "Offline"; 
       case (1): return "Online"; 
       default: return "Unknown"; 
      } 
     } 

     /** 
     * The battery charge status 
     */ 
     public String getBatteryFlagString() { 
      switch (BatteryFlag) { 
       case (1): return "High, more than 66 percent"; 
       case (2): return "Low, less than 33 percent"; 
       case (4): return "Critical, less than five percent"; 
       case (8): return "Charging"; 
       case ((byte) 128): return "No system battery"; 
       default: return "Unknown"; 
      } 
     } 

     /** 
     * The percentage of full battery charge remaining 
     */ 
     public String getBatteryLifePercent() { 
      return (BatteryLifePercent == (byte) 255) ? "Unknown" : BatteryLifePercent + "%"; 
     } 

     /** 
     * The number of seconds of battery life remaining 
     */ 
     public String getBatteryLifeTime() { 
      return (BatteryLifeTime == -1) ? "Unknown" : BatteryLifeTime + " seconds"; 
     } 

     /** 
     * The number of seconds of battery life when at full charge 
     */ 
     public String getBatteryFullLifeTime() { 
      return (BatteryFullLifeTime == -1) ? "Unknown" : BatteryFullLifeTime + " seconds"; 
     } 

     @Override 
     public String toString() { 
      StringBuilder sb = new StringBuilder(); 
      sb.append("ACLineStatus: " + getACLineStatusString() + "\n"); 
      sb.append("Battery Flag: " + getBatteryFlagString() + "\n"); 
      sb.append("Battery Life: " + getBatteryLifePercent() + "\n"); 
      sb.append("Battery Left: " + getBatteryLifeTime() + "\n"); 
      sb.append("Battery Full: " + getBatteryFullLifeTime() + "\n"); 
      return sb.toString(); 
     } 
    } 

    /** 
    * Fill the structure. 
    */ 
    public int GetSystemPowerStatus(SYSTEM_POWER_STATUS result); 
} 

Así es como se puede usar, por ejemplo, en su main() método:

Kernel32.SYSTEM_POWER_STATUS batteryStatus = new Kernel32.SYSTEM_POWER_STATUS(); 
Kernel32.INSTANCE.GetSystemPowerStatus(batteryStatus); 

System.out.println(batteryStatus); // Shows result of toString() method. 

Esto imprime con éxito el siguiente en mi Latitude E5500:

 
ACLineStatus: Online 
Battery Flag: High, more than 66 percent 
Battery Life: 100% 
Battery Left: Unknown 
Battery Full: Unknown 

Y después de conectar apagaba el aire acondicionado durante 10 minutos:

 
ACLineStatus: Offline 
Battery Flag: High, more than 66 percent 
Battery Life: 82% 
Battery Left: 2954 seconds 
Battery Full: Unknown 

(no, no batería defectuosa, solo estoy compilando una película y continuamente transfiriendo a través de wifi en este momento;))

+1

'Fill the structure' es el método principal para mostrar todo esto? –

+1

@LittleChild: no, es el bloque de código a continuación "Así es como puedes usarlo". Simplemente copie esas líneas en su 'main()'. No necesita editar la interfaz/clase 'Kernel32' (por supuesto, si es necesario, del paquete, pero eso no es más que obvio). – BalusC

+0

El método getBatteryFlagString() de ejemplo podría ser un poco engañoso ya que la documentación a la que se hace referencia establece que BatteryFlag "puede contener uno o más de los siguientes indicadores". Con 1, 2, 4, 8, 128 y 255 en la lista. Un enfoque más confiable podría ser usar un "Y a nivel de bit" para cada valor si el indicador no es 255. Aunque, el valor de "carga" (8) es probablemente lo único que vería con 1, 2 o 4. –

Cuestiones relacionadas