我正在编写一个IOS应用程序,它将记录(随着时间的推移)iPhone设备的当前电池电量。
我使用UIDeviceBatteryLevelDidChangeNotification在前台执行代码,当应用程序处于前台模式时,会触发通知(处理成功)。
代码如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
return YES;
}
- (void)batteryChanged:(NSNotification *)notification
{
NSLog(@"Battery Changed From Observer");
[self UpdateBatteryStatus];
}
-(void)UpdateBatteryStatus
{
UIDevice *myDevice = [UIDevice currentDevice];
double batLeft = (float)[myDevice batteryLevel] * 100;
NSLog(@"Battery level: %f", batLeft);
// Do some stuff related to battery status
}
这会对手机上电池状态的每1%增量(或减量)执行(通过日志输出证明),这与预期完全一致。
然而,当应用程序移动到后台时,事件将停止触发。将应用程序移回前台后,会触发事件(这几乎就像它们排队到达前景一样)。
我搜索了堆栈溢出,大多数答案都是一样的,基本上这是后台模式权限问题。所以我勾选了所有方框:
我添加了一切只是为了确保它不是后台持久性问题。不幸的是,即使在干净,重建(也关闭Xcode,重新插入iPhone)之后,事件仍然无法解决。
请记住,我无意将其发布到应用程序商店,我知道伪造后台模式用例是一种快速而简单的拒绝。但我想让它适合个人使用。
编辑:ios target 11.3
答案 0 :(得分:0)
您的应用在后台/暂停期间不会收到NSNotificationCenter
次通知。您可以尝试使用获取后台模式来模拟远程下载。但是请注意这种方法的缺点 - 系统本身将决定何时调用回调。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
return YES;
}
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
UIDevice *myDevice = [UIDevice currentDevice];
double batLeft = (float)[myDevice batteryLevel] * 100;
NSLog(@"Battery level: %f", batLeft);
completionHandler(UIBackgroundFetchResultNewData);
}
如果您按照规定不打算在AppStore中发布您的应用程序,您可以尝试使用背景模式的其他黑客,例如在背景中无限播放静音。