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 中发布您的应用程序,您可以尝试使用后台模式的其他黑客攻击,例如在后台无限播放静音。