HTML5 Battery Status API

The new Battery Status API opens up a lot of potential for developing web apps and sites.

  • 7th January 2015

The new Battery Status API opens up a lot of potential for developing web apps, as well as for more basic sites such as blogs and homepages.

As an example, it is now possible to detect when a device is running low on battery and then either stop, or reduce the number of background ajax requests to a service. If a device has an OLED screen, it would be possible to switch to a dark themed stylesheet, reducing the power consumption on the device.

Another great case for the API, is that a listener can be registered to monitor the battery level and charging state. If the device starts to discharge, or reaches a low level, any data that the user is working on could be saved before it is lost. A more creative use of the API could be to prompt the user to save an article to read later, with a service such as Instapaper or Pocket.

Support for the new API was recently added to Chrome in version 38, and Chrome for Android in version 39. Support for other browsers can be seen on the Can I Use → Battery Status page.

As you are reading this on a browser that supports the API, your battery stats can be viewed below:

Note: At the current time of writing, the spec is a working draft. The syntax has not been finalised and is subject to change.

The new API is very easy to implement, first, we need to check that it is available in the browser.

if("getBattery" in navigator) {
    // API is supported
} else {
    // API is not supported
}

The API provides a navigator.getBattery() method, which will return a promise to access the data asynchronously. Once resolved, a BatteryManager object will be provided containing the events and current battery data.

navigator.getBattery().then(batterySuccess, batteryFailure);

If the promise completes successfully, it will call our batterySuccess function. In the callback, simply assign the BatteryManager object to a global variable, and trigger an update of the display.

var battery;

/**
 * Successful callback providing a Battery Manager object.
 * @param batteryManager
 */
function batterySuccess(batteryManager) {
    battery = batteryManager;

    updatedBatteryStats();
}

/**
 * Failure callback.
 */
function batteryFailure() {
    // Fail gracefully.
}

The (dis)charging time can be "Infinity". This could be because not enough data has been collected, or the device will never charge or discharge due to being plugged in (or not). On some devices like mobile phones, this is often not available, therefore it is always set to Infinity.

/**
 * Update HTML with current battery stats
 */
function updatedBatteryStats() {
    // Example data in window.battery:
    //   BatteryManager
    //     charging: false
    //     chargingTime: Infinity
    //     dischargingTime: 12600
    //     level: 0.56
    //     onchargingchange: null
    //     onchargingtimechange: null
    //     ondischargingtimechange: null
    //     onlevelchange: null
}

The last piece of the puzzle is to listen for changes in the battery level and charging state. These events should be registered once, in the success callback.

    // Register event handlers
    battery.addEventListener('chargingchange', updatedBatteryStats);
    battery.addEventListener('chargingtimechange', updatedBatteryStats);
    battery.addEventListener('dischargingtimechange', updatedBatteryStats);
    battery.addEventListener('levelchange', updatedBatteryStats);

Piecing it all together

Once completed, the following code should look like this. Simply update the updatedBatteryStats() function with the appropriate code, and you're ready to go.

// Initialise Variables
var battery;

// Define functions

/**
 * Successful callback providing a Battery Manager object.
 * @param batteryManager
 */
function batterySuccess(batteryManager) {
    // Assign batteryManager to globally 
    //   available `battery` variable.
    battery = batteryManager;

    // Register event handlers  
    battery.addEventListener('chargingchange', updatedBatteryStats);
    battery.addEventListener('chargingtimechange', updatedBatteryStats);
    battery.addEventListener('dischargingtimechange', updatedBatteryStats);
    battery.addEventListener('levelchange', updatedBatteryStats);

    // Process updated data
    updatedBatteryStats();
}

/**
 * Failure callback.
 */
function batteryFailure() {
    // Fail gracefully. 
}

/**
 * Update HTML with current battery stats
 */
function updatedBatteryStats() {
    // Example data in window.battery:
    //   BatteryManager
    //     charging: false
    //     chargingTime: Infinity
    //     dischargingTime: 12600
    //     level: 0.56
    //     onchargingchange: null
    //     onchargingtimechange: null
    //     ondischargingtimechange: null
    //     onlevelchange: null
}

if("getBattery" in navigator) {
    // API is supported
    
    // Request battery manager object.
    navigator.getBattery().then(batterySuccess, batteryFailure);
    
} else {
    // API is not supported, fail gracefully.
}

References

  1. Mozilla Developer Network - Battery Status API
  2. @rem JSBin Example

This is only an example of the new specification API for Battery Status. Older versions of Chrome and Firefox use a different, older specification, based around using navigator.battery.

If you have any feedback or questions, please leave a comment below.