非Expo版React Native应用如何监听电池电量变化?
非Expo React Native持续监听电池电量变化方案
方案一:使用支持监听的第三方库
试试react-native-battery,它支持添加电量变化的持续监听器,步骤如下:
- 安装依赖:
npm install react-native-battery --save # 或使用yarn yarn add react-native-battery
- 自动链接(RN 0.60+版本无需手动操作,低于该版本需执行
react-native link react-native-battery) - 代码中使用监听器:
import Battery from 'react-native-battery'; // 注册电量变化监听器 const batteryListener = Battery.addBatteryLevelListener((level) => { console.log('当前电池电量:', level); // level为0-100的数值 }); // 组件卸载时务必移除监听器,避免内存泄漏 componentWillUnmount() { batteryListener.remove(); }
方案二:自定义原生模块(标准化实现)
如果第三方库无法满足需求,自定义原生模块是最可靠的标准化方案,以下是Android和iOS两端的实现步骤:
Android端实现
- 在
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); } }
- 创建
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(); } }
- 在
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端实现
- 在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) } }
- 创建
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
相关产品推荐
相关产品推荐

