【问题标题】:App for jailbroken iOS device: Consistent background operation越狱iOS设备应用:一致的后台操作
【发布时间】:2013-03-16 11:46:32
【问题描述】:

我是名为 AirFloat 的 Cydia 调整的作者。一款实现 AirPlay 音频协议(以前称为 AirTunes)的应用,可以将音频流式传输到您的 iOS 设备。 AirFloat 最初是一个 App Store 应用程序,直到它被 Apple 从 App Store 启动。

我已经在 Cydia 中免费提供了它。目前,该应用程序在 Cydia 中与之前的 App Store 版本完全相同。因此,我收到了很多让它在后台工作的请求。但我无法让它工作。

基本上我在考虑两种方法。

注意:AirFloat 在 iOS 锁定屏幕上显示当前播放的曲目。

  1. 创建一个守护程序,它运行实际的 AirPlay 实现,并使用 notify 与 UI 应用程序通信。这行得通。的种类。它运行并播放音频,但 MPNowPlayingInfoCenter 似乎不能从非 UI 应用程序更新。同样当守护进程以用户 mobile 运行时。

  2. 第二种方法是让它全部在 UI 应用程序中工作。但是我很难让它被暂停。我已将“必需的背景模式”设置为 audiocontinuous。服务器可能仍在运行,但随后 Bonjour 广告被关闭,因为运行循环在后台停止。其次,应用应使用 SpringBoard 自动启动,并在异常退出时重新启动。

我个人更喜欢第二种方法,因为我会避免进行进程间通信。对于这种工作方法,我需要完整的后台执行(包括运行循环),并在 SpringBoard 启动时启动它并在异常退出时重新启动。

有人对如何解决这个问题有任何建议吗?

【问题讨论】:

    标签: ios jailbreak airplay cydia mpnowplayinginfocenter


    【解决方案1】:

    首先感谢您使用 AirFlow RAOP 的出色工作是一件非常困难的事情!

    所以你能做的就是

    1.创建一个后台任务处理程序作为 dispatch_block_t,比如说

         dispatch_block_t myDummyBackgroundTaskBlock = {
            [[UIApplication sharedApplication] endBackgroundTask:myDummyBackgroundTask];
            myDummyBackgroundTask = UIBackgroundTaskInvalid;
            myDummyBackgroundTask = [app beginBackgroundTaskWithExpirationHandler:myDummyBackgroundTask];
        };
    

    2。在某处定义此后台和前台任务处理程序

            // foreground
            -(void)handleTasksForApplicationInForeground {
            if(myDummyBackgroundTask) { // reset that task
               [[UIApplication sharedApplication] endBackgroundTask: myDummyBackgroundTask];
               myDummyBackgroundTask = UIBackgroundTaskInvalid;
             }
            }
    
             // background
             -(void) handleTasksForApplicationInBackground {
                 UIDevice *device = [UIDevice currentDevice];
                 BOOL backgroundSupported = NO;
                if ([device respondsToSelector:@selector(isMultitaskingSupported)])
                 backgroundSupported = device.multitaskingSupported;
                if(backgroundSupported && backgroundEnabled) { // perform a background task
    
                    myDummyBackgroundTaskBlock = ^{
                        [[UIApplication sharedApplication] endBackgroundTask: myDummyBackgroundTaskBlock];
                        myDummyBackgroundTaskBlock = UIBackgroundTaskInvalid;
                   };
    
                   SEL sel = @selector(doDummyBackgroundTask);
                   [self doBackgroundTaskAsync:sel];
    
                   [self performSelector:@selector(doBackgroundTaskAsync:) withObject:nil afterDelay:500.0f]; /// LP: this is the funny part since iOS will kill the task after 500 sec.
                     }
                   }
    

    3.现在让我们在应用程序中处理委托后台模式(如之前定义的那样,您可以在应用程序 .plist 中使用不同的选项激活后台模式):

            -(void)applicationDidEnterBackground:(UIApplication *)application {
               [self handleTasksForApplicationInBackground];
             }
    
            -(void)applicationWillEnterForeground:(UIApplication *)application {
               [self handleTasksForApplicationInForeground];
             }
    

    4.让我们看看后台异步任务选择器做了什么

                -(void) doBackgroundTaskAsync:(SEL)selector {
    
                @try {
                     if( [[UIApplication sharedApplication] backgroundTimeRemaining] < 5 ) { 
                       return;
                     }
    
                   if(!myDummyBackgroundTaskBlock) { // need to create again on-the-fly
                        myDummyBackgroundTaskBlock = ^{
                              [[UIApplication sharedApplication] endBackgroundTask:myDummyBackgroundTask];
                             myDummyBackgroundTask = UIBackgroundTaskInvalid;
                        };
                     }
    
                    myDummyBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:myDummyBackgroundTaskBlock];
                  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    
                   while ([[UIApplication sharedApplication] backgroundTimeRemaining] > 5.0) {
                      int delta = 5.0;
                      [self performSelector: selector ];
                      sleep(delta);
                  }
                });
              }
               @catch (...) {
             }
            }
    

    我知道这个解决方案效果很好,但我知道有时 iOS 会终止应用程序后台任务。无论如何,如果用户突然在前台和后台之间切换应用程序,它将无限期地运行。

    【讨论】:

    • 非常感谢!我将在即将发布的版本中对此进行测试。谢谢!
    • 从 iOS7 开始,后台活动从 600 秒减少。 (5 分钟)至 180 秒。 (3 分钟),因此延迟调用 doBackgroundTaskAsync 的选择器 必须 在 >= 180.0f 之后调用
    【解决方案2】:

    部分答案。如果添加“voip”作为后台模式,它会被 SpringBoard 自动启动。

    【讨论】:

    • 这行得通。它会自动启动。一切都很好。但是必须有某种方法让它始终在后台运行。像 MobilePhone.app 或 MobileMail.app。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    相关资源
    最近更新 更多