Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
348 views
in Technique[技术] by (71.8m points)

java - How to get the remaining battery life in a Windows system?

I need to get the remaining battery life in a Windows system. How can I do it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I assume you're talking about a laptop. No such API exist in Standard Java SE API. This information is available in the operating system platform native API only. You would need at least JNI or JNA (JavaWorld article) to be able to communicate with platform native API.

In Windows, you'd like to hook on SYSTEM_POWER_STATUS structure. It offers among others the BatteryLifePercent property which may be of your interest. I found a helpful JNA based code snippet in an old forums.sun.com topic which is currently not available anymore. So the credit actually goes to the Author Whose Name Shall Not Be Known.

To get it to work, first drop jna.jar in the classpath and then copy the following class unmodified into your project:

package com.stackoverflow.q3434719;

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 = Native.load("Kernel32", Kernel32.class);

    /**
     * @see https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-system_power_status
     */
    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() + "
");
            sb.append("Battery Flag: " + getBatteryFlagString() + "
");
            sb.append("Battery Life: " + getBatteryLifePercent() + "
");
            sb.append("Battery Left: " + getBatteryLifeTime() + "
");
            sb.append("Battery Full: " + getBatteryFullLifeTime() + "
");
            return sb.toString();
        }
    }

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

Here's how you can use it, e.g. in your main() method:

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

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

This prints successfully the following at my Latitude E5500:

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

And after plugging off the AC for 10 minutes:

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

(no, no bad battery, I am just compiling a movie and continuously transferring over wifi right now ;) )


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...