Detect Device Battery Level via JavaScript

battery-half

I’ve recently come across a handy feature that allows web applications to detect device battery level via javascript from the browser. Currently, the spec for this interface (Battery Status API) is in Working Draft status with W3C but will hopefully see wider adoption in coming months. Google Chrome and Opera have already adopted this feature for desktop and there appears to be early support for Chrome on Android.

At first glance, this might seem like a trivial piece of information that a web app would want to access, but the more I think about it, I see a lot of potential especially in the context of mobile. If an application can detect battery level and charging status it could be smart enough to throttle data requests, save progress to avoid data loss. It could even be used behind the scenes as a diagnostic tool to determine where an application is a power suck.

The Battery Manager Interface

Detecting a device battery level and charging status is done through the Battery Manager interface via a Promise. This object is accessible via the navigator object in the browser. When the promise is returned there are a number of read only properties available are:

  • level (double): Current battery level from 0 to 1.0
  • charging (boolean): Represents if a device is charging
  • chargingTime (unrestricted double): Set to 0 if battery is full or there is no battery attached to the device. Set to Infinity if the battery is discharging.
  • dischargingTime (unrestricted double): Set to Infinity if the battery is charging.

The initial call is very straightforward:

navigator.getBattery().then(function (batt) {
    // Access to interface properties here                
});

Events Available

Along with the read only properties on the interface, there are a handful of events that get fired. They are fairly straight forward and mirror the available properties:

  • onlevelchange (levelchange): Event added to the browser queue when battery level property changes
  • onchargingchange (chargingchange): Event added to the browser queue when charging property changes
  • onchargingtimechange (chargingtimechange): Event added to the browser queue when chargingTime property changes
  • ondischargingtimechange (dischargingtimechange): Event added to the browser queue when dischargingTime property changes

Battery Level via Javascript Example

To accompany this post I’ve put together a quick example that illustrates accessing properties on the interface as well as firing the onlevelchange and onchargingchange events. You can see live demo here (Remember, you will need to use Chrome or Opera).

(function () {

            //#region Constants
            var NOT_APPLICABLE = "N/A";
            //#endregion

            //#region Helper Methods
            function setBatteryLevel(level, callback) {
                document.getElementById("level").innerHTML = "Battery Level: " + level;

                if (callback && typeof (callback) === "function") {
                    callback();
                }
            };

            function setChargingStatus(status, callback) {
                document.getElementById("charging").innerHTML = "Charging Status: " + (status === NOT_APPLICABLE ? NOT_APPLICABLE : (status === true ? "Charging" : "Un-plugged"));

                if (callback && typeof (callback) === "function") {
                    callback();
                }
            };
            //#endregion

            try {

                navigator.getBattery().then(function (battery) {
                    // When initial promise from navigator.getBattery() is recieved set the current statuses.
                    setBatteryLevel(battery.level);
                    setChargingStatus(battery.charging);

                    battery.onlevelchange = function (evt) { // Event info is available as param
                        var _level = battery.level;
                        setBatteryLevel(_level, function () {
                            console.log("Battery level changed: " + _level, battery);
                        });
                    };

                    battery.onchargingchange = function (evt) { // Event info is available as param
                        var _charging = battery.charging;
                        setChargingStatus(_charging, function () {
                            console.log("Battery charging status changed: " + _charging, battery);
                        });
                    }
                });
            }
            catch (e) {
                // Catch the error if navigator.getBattery isn't defined
                document.getElementById("error").innerHTML = "Unable to retrieve battery status. You may be using an incompatible browser.

\
            At the time of this demo, the Battery Status API is only available in Google Chrome 38+ or Opera 25+ and is in Working Draft status.

\
            Error Message: " + e;

                // Update
                setBatteryLevel(NOT_APPLICABLE);
                setChargingStatus(NOT_APPLICABLE);

            }
        })();

Want to Learn More?

The following are a few valuable links on the subject: