 # 🔋 Battery Status Detector

 Test the Battery Status API in your browser. Historically used for fingerprinting, this API is now deprecated in most modern browsers for privacy reasons.

 

 

 

 





 

--

Checking battery status...

Charging

--

 

Charging Time

--

 

Discharging Time

--

 

API Status

--

 

 

 

 ####  Privacy Implications

 **The Battery Status API was historically used for fingerprinting.** Even though battery level is shown as a percentage, combined with charging status and time remaining, it could create a unique signature to track users across websites. Modern browsers now block or limit this API to protect user privacy.

 

   

 The **Battery Status API** allows websites to access information about the device's battery:

- **Battery level** - Percentage from 0 to 1 (0% to 100%)
- **Charging status** - Whether the device is plugged in
- **Charging time** - Estimated time until fully charged (in seconds)
- **Discharging time** - Estimated time until battery depletes (in seconds)
 
##### Browser Support History

- **Firefox** - Supported until 2016, then removed for privacy
- **Chrome** - Supported until 2019, then deprecated
- **Safari** - Never supported
- **Edge (Chromium)** - Deprecated since 2019
- **Opera** - Deprecated since 2019
 
// Original Battery Status API usage navigator.getBattery().then(battery =&gt; { console.log('Battery level:', battery.level * 100 + '%'); console.log('Charging:', battery.charging); console.log('Charging time:', battery.chargingTime + 's'); console.log('Discharging time:', battery.dischargingTime + 's'); // Listen for changes battery.addEventListener('levelchange', () =&gt; { console.log('Battery level changed:', battery.level); }); }); 

 

 

 

  

 The Battery Status API became a significant **privacy concern** because it enabled precise user tracking:

##### How Battery Data Was Used for Fingerprinting

1. **Unique Combinations**: Battery level (0-100%) + charging time creates thousands of possible combinations
2. **Cross-Site Tracking**: Users could be tracked across websites without cookies
3. **Short-Term Tracking**: Battery values change slowly enough to track users for 30-60 minutes
4. **Combined Fingerprinting**: Battery data enhanced other fingerprinting techniques
 
##### Real-World Abuse Examples

 In 2015, researchers demonstrated that two websites could correlate battery levels to identify the same user visiting both sites. A user with battery at 47% and charging time of 1832 seconds would have the same values on both sites for several minutes, enabling cross-site tracking.

##### Browser Vendor Response

- **Firefox (2016)** - First to remove the API entirely
- **Chrome (2019)** - Deprecated the API, returns hardcoded values
- **Safari** - Never implemented the API
 
// Privacy attack example (no longer works in modern browsers) async function fingerprintBattery() { const battery = await navigator.getBattery(); // Create unique ID from battery state const batteryFingerprint = { level: Math.floor(battery.level * 100), charging: battery.charging, chargingTime: battery.chargingTime, dischargingTime: battery.dischargingTime }; // Send to tracking server const fingerprintId = btoa(JSON.stringify(batteryFingerprint)); console.log('Battery fingerprint:', fingerprintId); // This fingerprint could track users for 30-60 minutes return fingerprintId; } 

 

 

 

  

You can detect if the Battery Status API is supported in your browser:

// Feature detection if ('getBattery' in navigator) { console.log('Battery Status API is supported'); navigator.getBattery().then(battery =&gt; { // Check if values are real or spoofed const isRealData = battery.level !== 1.0 || battery.charging !== true || battery.chargingTime !== Infinity || battery.dischargingTime !== Infinity; if (isRealData) { console.log('Battery API returns real data'); } else { console.log('Battery API blocked (returns default values)'); } }); } else { console.log('Battery Status API not supported'); } 

##### Default Values in Blocked Browsers

Modern Chrome/Edge return these hardcoded values:

- `level: 1.0` (100%)
- `charging: true`
- `chargingTime: Infinity`
- `dischargingTime: Infinity`
 
These values ensure existing code doesn't break while preventing fingerprinting.

 

 

 

  

Here's how to safely check battery status in 2025:

async function checkBatteryStatus() { // Check if API exists if (!('getBattery' in navigator)) { return { supported: false, message: 'Battery Status API not supported' }; } try { const battery = await navigator.getBattery(); // Check if returning real or default values const isBlocked = battery.level === 1.0 &amp;&amp; battery.charging === true &amp;&amp; battery.chargingTime === Infinity &amp;&amp; battery.dischargingTime === Infinity; if (isBlocked) { return { supported: true, blocked: true, message: 'Battery API blocked for privacy' }; } // Real battery data return { supported: true, blocked: false, level: Math.floor(battery.level * 100), charging: battery.charging, chargingTime: battery.chargingTime, dischargingTime: battery.dischargingTime }; } catch (error) { return { supported: false, error: error.message }; } } // Usage checkBatteryStatus().then(result =&gt; { console.log('Battery Status:', result); }); 

##### Event Listeners

// Listen for battery changes (if API is available) navigator.getBattery().then(battery =&gt; { battery.addEventListener('levelchange', () =&gt; { console.log('Battery level changed:', battery.level); }); battery.addEventListener('chargingchange', () =&gt; { console.log('Charging status changed:', battery.charging); }); battery.addEventListener('chargingtimechange', () =&gt; { console.log('Charging time changed:', battery.chargingTime); }); battery.addEventListener('dischargingtimechange', () =&gt; { console.log('Discharging time changed:', battery.dischargingTime); }); }); 

 

 

 





 `; document.getElementById('battery-status').textContent = 'Battery API not supported'; document.getElementById('detail-api-status').innerHTML = 'Not Supported'; return; } try { const battery = await navigator.getBattery(); // Check if blocked (default values) const isBlocked = battery.level === 1.0 &amp;&amp; battery.charging === true &amp;&amp; battery.chargingTime === Infinity &amp;&amp; battery.dischargingTime === Infinity; if (isBlocked) { apiStatusContainer.innerHTML = ` ####  Battery Status API Blocked

 Your browser supports the Battery Status API but **blocks real data for privacy**. It returns default values (100%, charging, infinite time) to prevent fingerprinting. This is **good for your privacy**.

 

 `; } else { apiStatusContainer.innerHTML = ` ####  Battery Status API Exposes Real Data

 Your browser exposes **real battery data**. This can be used for fingerprinting and tracking. Consider updating your browser or using privacy-focused settings.

 

 `; } updateBatteryDisplay(battery, isBlocked); // Listen for changes battery.addEventListener('levelchange', () =&gt; updateBatteryDisplay(battery, isBlocked)); battery.addEventListener('chargingchange', () =&gt; updateBatteryDisplay(battery, isBlocked)); battery.addEventListener('chargingtimechange', () =&gt; updateBatteryDisplay(battery, isBlocked)); battery.addEventListener('dischargingtimechange', () =&gt; updateBatteryDisplay(battery, isBlocked)); } catch (error) { apiStatusContainer.innerHTML = ` ####  Battery Status API Error

Error accessing Battery Status API: ${error.message}

 

 `; document.getElementById('battery-status').textContent = 'Error accessing battery'; } } // Run on page load document.addEventListener('DOMContentLoaded', () =&gt; { checkBattery(); });