电池状态信息显示

592 阅读1分钟

前言

最近比较好奇如何在前端页面上检测当前设备的电池状态,然后去实时的显示它?出于这个好奇心,便去网上查了查,基于react写了一个小小的demo进行显示。

声明电池的类型

interface BatteryManager {
  charging: boolean;
  chargingTime: number;
  dischargingTime: number;
  level: number;
  addEventListener: Function;
}

declare global {
  interface Navigator {
    getBattery: () => Promise<BatteryManager>;
    battery: BatteryManager;
  }
}

获取电池状态的API

const bat: BatteryManager = (await navigator.getBattery()) || navigator.battery || (navigator as any).webkitBattery || (navigator as any).mozBattery;

监听电池的状态

battery?.addEventListener('chargingchange', updateBatteryStatus);
battery?.addEventListener('levelchange', updateBatteryStatus);
battery?.addEventListener('chargingtimechange', updateBatteryStatus);
battery?.addEventListener('dischargingtimechange', updateBatteryStatus);

具体效果

断电时:

image.png

充电时:

image.png

代码预览

以上就是获取电池状态的重要部分,下面贴上全部的代码:

import React, { useState, useEffect, useReducer, useRef } from 'react';
import './_styles/battery.css';

interface BatteryManager {
  charging: boolean;
  chargingTime: number;
  dischargingTime: number;
  level: number;
  addEventListener: Function;
}

declare global {
  interface Navigator {
    getBattery: () => Promise<BatteryManager>;
    battery: BatteryManager;
  }
}

export default () => {
  const [isAddListener, setIsAddListener] = useState<boolean>(false);
  const [battery, setBattery] = useState<BatteryManager>();
  const [_, forceUpdate] = useReducer((x) => x + 1, 0);
  const elecQuality = useRef();

  // 更新电池状态
  async function updateBatteryStatus() {
    const bat: BatteryManager =
      (await navigator.getBattery()) ||
      navigator.battery ||
      (navigator as any).webkitBattery ||
      (navigator as any).mozBattery;
    setBattery(bat);
    if (elecQuality.current) {
      elecQuality.current.style.background = `linear-gradient(to right, ${
        bat.level > 0.3 ? '#6feb53' : '#e6260c'
      } ${bat.level * 100}%, transparent ${100 - bat.level * 100}%)`;
    }
    forceUpdate();
  }

  useEffect(() => {
    updateBatteryStatus();
    if (battery && !isAddListener) {
      setIsAddListener(true);
      battery?.addEventListener('chargingchange', updateBatteryStatus);
      battery?.addEventListener('levelchange', updateBatteryStatus);
      battery?.addEventListener('chargingtimechange', updateBatteryStatus);
      battery?.addEventListener('dischargingtimechange', updateBatteryStatus);
    }
  }, [battery]);
  return (
    <div className="battery-container">
      {battery && (
        <>
          <p className="battery-title">电池状态({battery.level * 100}%)</p>
          <div className="battery-status">
            <div ref={elecQuality} className="status-quantity"></div>
            {battery.charging && <div className="battery-charging"></div>}
          </div>
        </>
      )}
    </div>
  );
};

上面使用了 useReducer,因为使用useState改变数据后页面不能及时的刷新,无法实时看到电池状态,因而采用了reducer进行强制刷新。

实例demo链接

电池状态显示demo,点此查看