iOS中UIDeviceBatteryLevelDidChangeNotification后台不触发问题
iOS 后台持续记录电池电量方案
你已经搞定了前台的电池电量监听,这步走得很稳!不过要实现后台持续记录的话,UIDeviceBatteryLevelDidChangeNotification在后台是不会主动触发的,得结合iOS的后台规则来调整方案,下面给你分步骤讲清楚:
一、先配置后台权限
首先得给应用开启对应的后台模式,让系统允许应用在后台被唤醒:
- 打开项目的
Info.plist,添加UIBackgroundModes数组,加入fetch(后台获取)或者processing(iOS 13+后台处理); - 也可以在Xcode的
Signing & Capabilities面板里,点击+ Capability添加Background Modes,勾选对应的选项。
二、代码实现思路
1. 后台定时唤醒采样(推荐用Background Fetch)
这种方式不需要持续占用资源,系统会根据应用的使用频率、设备状态定期唤醒应用,唤醒后你就可以读取并记录当前电量:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 开启电池监控 [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES]; // 配置后台获取的最小间隔(系统仅作参考,不会严格遵守) [application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum]; // 保留前台监听的代码 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil]; return YES; } // 后台获取回调,系统唤醒应用时触发 - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // 读取当前电池电量 CGFloat batteryLevel = [[UIDevice currentDevice] batteryLevel]; // 执行你的记录逻辑(比如写入本地文件或Core Data) [self saveBatteryRecord:batteryLevel]; // 告诉系统任务完成,避免被强制杀死 completionHandler(UIBackgroundFetchResultNewData); } // 前台电量变化的处理方法 - (void)batteryLevelChanged:(NSNotification *)notification { CGFloat batteryLevel = [[UIDevice currentDevice] batteryLevel]; [self saveBatteryRecord:batteryLevel]; } // 统一的记录方法 - (void)saveBatteryRecord:(CGFloat)level { // 这里替换成你的实际存储逻辑 NSLog(@"记录电池电量:%.2f%%", level * 100); }
2. 关键注意点
- 后台唤醒频率不可控:系统会根据应用的活跃度、设备剩余电量等因素调整唤醒间隔,无法做到精确的实时记录;
- 避免违规后台行为:iOS不允许应用在后台持续监听电量通知,强行保活会被系统判定为违规,大概率会被杀死;
- 权限合规:如果使用定位相关的后台模式辅助唤醒,必须在
Info.plist中添加对应的隐私描述(比如NSLocationAlwaysAndWhenInUseUsageDescription),并向用户说明用途。
内容的提问来源于stack exchange,提问作者user989056
相关产品推荐
相关产品推荐

