IOS UIDeviceBatteryLevelDidChangeNotification 未在后台模式下触发
IOS UIDeviceBatteryLevelDidChangeNotification not firing in background mode
我正在编写一个 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
}
这会在 phone 上的电池状态每增加(或减少)1% 时执行(通过日志输出证明),这完全符合预期。
然而,当应用移至后台时,事件停止触发。将应用程序移回前台后,事件会触发(这几乎就像它们在到达前台之前排队一样)。
我查了一下stack overflow,大部分答案都是一样的,基本上这是后台模式的权限问题。所以我勾选了所有方框:
我添加了所有内容只是为了确保这不是后台权限问题。不幸的是,即使经过清理和重建(也关闭 Xcode,并重新插入 iPhone),事件仍然不会触发。
请记住,我无意将此发布到应用商店,我知道伪造后台模式用例是一种快速简便的拒绝方法。但我想让它用于个人用途。
编辑:ios 目标 11.3
您的应用在 background/suspended 时不会收到 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 中发布您的应用程序,您可以尝试使用后台模式的其他黑客攻击,例如在后台无限播放静音。
我正在编写一个 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
}
这会在 phone 上的电池状态每增加(或减少)1% 时执行(通过日志输出证明),这完全符合预期。
然而,当应用移至后台时,事件停止触发。将应用程序移回前台后,事件会触发(这几乎就像它们在到达前台之前排队一样)。
我查了一下stack overflow,大部分答案都是一样的,基本上这是后台模式的权限问题。所以我勾选了所有方框:
我添加了所有内容只是为了确保这不是后台权限问题。不幸的是,即使经过清理和重建(也关闭 Xcode,并重新插入 iPhone),事件仍然不会触发。
请记住,我无意将此发布到应用商店,我知道伪造后台模式用例是一种快速简便的拒绝方法。但我想让它用于个人用途。
编辑:ios 目标 11.3
您的应用在 background/suspended 时不会收到 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 中发布您的应用程序,您可以尝试使用后台模式的其他黑客攻击,例如在后台无限播放静音。