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

非Expo版React Native应用如何监听电池电量变化?

非Expo React Native持续监听电池电量变化方案

方案一:使用支持监听的第三方库

试试react-native-battery,它支持添加电量变化的持续监听器,步骤如下:

  1. 安装依赖:
npm install react-native-battery --save
# 或使用yarn
yarn add react-native-battery
  1. 自动链接(RN 0.60+版本无需手动操作,低于该版本需执行react-native link react-native-battery)
  2. 代码中使用监听器:
import Battery from 'react-native-battery';

// 注册电量变化监听器
const batteryListener = Battery.addBatteryLevelListener((level) => {
  console.log('当前电池电量:', level); // level为0-100的数值
});

// 组件卸载时务必移除监听器,避免内存泄漏
componentWillUnmount() {
  batteryListener.remove();
}

方案二:自定义原生模块(标准化实现)

如果第三方库无法满足需求,自定义原生模块是最可靠的标准化方案,以下是Android和iOS两端的实现步骤:

Android端实现

  1. 在android/app/src/main/java/com/[你的项目包名]/路径下创建BatteryModule.java:
package com.yourprojectpackage;

import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.modules.core.DeviceEventManagerModule;

public class BatteryModule extends ReactContextBaseJavaModule {
    private IntentFilter batteryFilter;

    public BatteryModule(ReactApplicationContext reactContext) {
        super(reactContext);
        batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    }

    @Override
    public String getName() {
        return "BatteryModule";
    }

    @ReactMethod
    public void startListening() {
        getReactApplicationContext().registerReceiver(
            intent -> {
                int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
                int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
                float batteryLevel = (level / (float) scale) * 100;
                
                WritableMap params = Arguments.createMap();
                params.putDouble("level", batteryLevel);
                
                getReactApplicationContext()
                    .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                    .emit("batteryLevelChanged", params);
            },
            batteryFilter
        );
    }

    @ReactMethod
    public void stopListening() {
        getReactApplicationContext().unregisterReceiver(null);
    }
}
  1. 创建BatteryPackage.java用于注册模块:
package com.yourprojectpackage;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class BatteryPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new BatteryModule(reactContext));
        return modules;
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}
  1. 在MainApplication.java中添加该包:
// 导入BatteryPackage
import com.yourprojectpackage.BatteryPackage;

// 在getPackages方法中添加注册代码
@Override
protected List<ReactPackage> getPackages() {
    @SuppressWarnings("UnnecessaryLocalVariable")
    List<ReactPackage> packages = new PackageList(this).getPackages();
    packages.add(new BatteryPackage()); // 添加此行
    return packages;
}

iOS端实现

  1. 在Xcode项目中创建BatteryModule.swift:
import Foundation
import UIKit
import React

@objc(BatteryModule)
class BatteryModule: NSObject, RCTBridgeModule {
    static func moduleName() -> String! {
        return "BatteryModule"
    }

    static func requiresMainQueueSetup() -> Bool {
        return true
    }

    private var batteryObserver: NSObjectProtocol?

    @objc func startListening() {
        batteryObserver = NotificationCenter.default.addObserver(
            forName: UIDevice.batteryLevelDidChangeNotification,
            object: nil,
            queue: .main
        ) { [weak self] _ in
            guard let self = self else { return }
            let level = UIDevice.current.batteryLevel * 100
            self.sendEvent(withName: "batteryLevelChanged", body: ["level": level])
        }
        UIDevice.current.isBatteryMonitoringEnabled = true
    }

    @objc func stopListening() {
        if let observer = batteryObserver {
            NotificationCenter.default.removeObserver(observer)
            batteryObserver = nil
        }
        UIDevice.current.isBatteryMonitoringEnabled = false
    }

    func sendEvent(withName name: String, body: Any?) {
        guard let bridge = RCTBridge.current() else { return }
        bridge.eventDispatcher().sendAppEvent(withName: name, body: body)
    }
}
  1. 创建BatteryModule.m桥接文件:
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(BatteryModule, NSObject)
RCT_EXTERN_METHOD(startListening)
RCT_EXTERN_METHOD(stopListening)
@end

React Native端调用

import { NativeModules, NativeEventEmitter } from 'react-native';

const { BatteryModule } = NativeModules;
const batteryEmitter = new NativeEventEmitter(BatteryModule);

// 启动原生监听
BatteryModule.startListening();

// 订阅电量变化事件
const subscription = batteryEmitter.addListener(
  'batteryLevelChanged',
  (data) => {
    console.log('当前电池电量:', data.level);
  }
);

// 组件卸载时停止监听并移除订阅
componentWillUnmount() {
  subscription.remove();
  BatteryModule.stopListening();
}

内容的提问来源于stack exchange,提问作者Sri Sai Sharanya Sirigiri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:17:31