You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Angular检测设备是否开启省电模式

Angular 检测设备省电模式实现方案

核心基于浏览器原生Battery Status API实现,搭配降级兼容逻辑覆盖不支持API的设备,封装为Angular服务即可实现状态响应式更新,自动切换视频/图片资源。

核心实现逻辑

  • 优先调用navigator.getBattery()接口获取电池管理实例,直接读取原生省电模式标记,同时监听充电状态、电量变化、省电模式开关三类事件,实时更新状态
  • 对不支持Battery API的设备做降级判断:结合系统减少动效偏好、设备硬件配置(CPU核心数、内存大小)做兜底判定,避免功能失效
  • 用Angular Signal存储状态,组件可直接绑定实现视图自动更新,无需手动触发变更检测

可复用服务代码

新建battery-detect.service.ts,代码如下:

import { Injectable, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { fromEvent, merge, of, from } from 'rxjs';
import { map, catchError, switchMap } from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class BatteryDetectService {
  // 存储省电模式状态,支持响应式更新
  isPowerSaveMode = signal(false);
  // 检测当前环境是否支持Battery API
  private isBatteryApiSupported = typeof navigator !== 'undefined' && 'getBattery' in navigator;

  constructor() {
    if (!this.isBatteryApiSupported) {
      this.fallbackDetect();
      return;
    }

    // 初始化电池状态监听
    from(navigator.getBattery()).pipe(
      switchMap((battery: any) => {
        // 初始化状态赋值
        this.updatePowerSaveStatus(battery);
        // 绑定所有状态变更事件
        return merge(
          fromEvent(battery, 'chargingchange'),
          fromEvent(battery, 'levelchange'),
          fromEvent(battery, 'powersavingchange')
        ).pipe(map(() => battery));
      }),
      map((battery: any) => this.updatePowerSaveStatus(battery)),
      catchError(() => {
        this.fallbackDetect();
        return of(this.isPowerSaveMode());
      }),
      takeUntilDestroyed()
    ).subscribe();
  }

  /**
   * 从电池实例计算省电模式状态
   */
  private updatePowerSaveStatus(battery: any): boolean {
    let status = false;
    // 优先读取原生省电模式标记,判断准确率最高
    if (typeof battery.powerSavingMode === 'boolean') {
      status = battery.powerSavingMode;
    } else {
      // 低版本API无原生标记时,兜底判断:非充电状态下电量≤20%视为省电场景
      status = !battery.charging && battery.level <= 0.2;
    }
    this.isPowerSaveMode.set(status);
    return status;
  }

  /**
   * 降级检测逻辑,适配不支持Battery API的环境
   */
  private fallbackDetect() {
    // 匹配系统减少动效偏好:开启该选项的设备通常处于省电模式/低性能模式
    const reduceMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
    // 低配设备判定:CPU核心≤2/设备内存≤2G时默认按省电场景适配
    const isLowEndDevice = navigator.hardwareConcurrency <= 2 || (navigator as any).deviceMemory <= 2;

    const setStatus = () => {
      this.isPowerSaveMode.set(reduceMotionQuery.matches || isLowEndDevice);
    };
    setStatus();
    // 监听系统动效偏好变化
    reduceMotionQuery.addEventListener('change', setStatus);
  }
}

组件内使用方式

在需要切换媒体资源的组件中直接注入服务,绑定模板即可自动切换:

import { Component } from '@angular/core';
import { BatteryDetectService } from './battery-detect.service';
import { NgIf } from '@angular/common';

@Component({
  selector: 'app-biz-media',
  standalone: true,
  imports: [NgIf],
  template: `
    <!-- 非省电模式加载视频 -->
    <video 
      *ngIf="!batteryService.isPowerSaveMode()" 
      src="assets/biz-video.mp4" 
      autoplay muted loop playsinline
    ></video>
    <!-- 省电模式加载静态封面图 -->
    <img 
      *ngIf="batteryService.isPowerSaveMode()" 
      src="assets/biz-cover.jpg" 
      alt="业务内容封面"
    >
  `
})
export class BizMediaComponent {
  constructor(public batteryService: BatteryDetectService) {}
}

适配注意事项

  • iOS Safari 16.4以下版本不支持Battery Status API,会自动走降级逻辑,不会抛出异常
  • 部分安卓定制ROM的省电模式触发规则存在差异,原生powerSavingMode字段为最高优先级判断依据,低电量兜底阈值可根据业务场景自行调整
  • 自动检测存在小概率误判,可在页面增加轻量的手动切换入口,允许用户手动选择视频/图片展示模式,覆盖检测误差

内容的提问来源于stack exchange,提问作者Shrikant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:18:21