应用程序永远存在于后台 - 私有应用程序

时间:2016-08-15 09:46:35

标签: objective-c background ios9 ios10

这适用于私有应用程序,当应用程序连接到用户选择的BT时,它可以执行一些操作。 我们使用bluetoothmanager.framework来自https://github.com/michaeldorner/BeeTee,不幸的是它似乎无法唤醒应用程序,如果它在后台。 可能吗?我们很高兴有任何线索如何使用

因此,我们需要找到一种方法来保持应用程序在后台运行,而用户不会在没有大量电池消耗的情况下杀死它。

目前我们使用此工作来保留应用程序。在2&之间活着最多4小时(显然还不够,但有了这个,应用程序什么都不消耗:2小时内大约1%)

后台模式:

  • voIp
  • 位置更新
  • 背景提取
  • 音频播放

使用的代码:

 - (void)applicationDidEnterBackground:(UIApplication *)application {

        if([[NSUserDefaults standardUserDefaults]objectForKey:@"account"]){

            _background_task = [application beginBackgroundTaskWithExpirationHandler:^ {
                NSLog(@"cleanup code for end of background allowed running time");
                [application endBackgroundTask: _background_task];
                _background_task = UIBackgroundTaskInvalid;
            }];

            // run background loop in a separate process
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                NSLog(@"start of background loop");
                while (TRUE)
                {
                    NSTimeInterval remaining = [[UIApplication sharedApplication] backgroundTimeRemaining];
                    // background audio resets remaining time
                    if (remaining < 60) {

                        [self playSpeech:@"up" andVolume:0.0];
                    }
                    [NSThread sleepForTimeInterval:1]; //wait for 1 sec
                }
                NSLog(@"end of background loop");
                [application endBackgroundTask: _background_task];
                _background_task = UIBackgroundTaskInvalid;
            });

            [[Detector singleton] startDetection];
        }
    }

有关如何在不破坏用户电池的情况下保持应用程序在后台运行的任何线索?

1 个答案:

答案 0 :(得分:0)

如果您正在使用蓝牙4和BTLE,那么一个解决方案就是注册(如您所提到的)背景位置更新。

在CoreLocation的帮助下,您可以设置CLLocationManager以监控多达20个不同的区域。区域显然可以由地理/ GPS区域组成,但也可以由iBeacon区域组成,它被称为CLBeaconRegion

因此,如果您实施此设计,您的应用程序可能会在进入和/或退出CLBeaconRegion时被唤醒。最重要的是,如果您的应用程序在注册区域监控后被杀死,iOS将在超过边界时将其唤醒。

Swift 2示例:

// setup your CLLocationManager :

var locManager: CLLocationManager = CLLocationManager()
locManager.delegate = self
locManager.requestAlwaysAuthorization()

// Register for region monitoring : 

let uuid: NSUUID = NSUUID(UUIDString: "BF89DEDF-35E1-93A2-D316-2381E10A28EF")!
let majorValue: CLBeaconMajorValue = CLBeaconMajorValue(UInt16(63468))
let minorValue: CLBeaconMinorValue = CLBeaconMajorValue(UInt16(13575))
let beaconRegion: CLBeaconRegion = CLBeaconRegion(proximityUUID: uuid, major: majorValue, minor: minorValue, identifier: "my-beacon")
self.locManager.startMonitoringForRegion(beaconRegion)

// from there implement the CLLocationManagerDelegates to get updates while in forground :

func locationManager(manager: CLLocationManager, didEnterRegion region: CLRegion)
{
    print("locationManager didEnterRegion = \(region)")
    if let beaconRegion = region as? CLBeaconRegion
    { 
        // do your stuff
    }
}

func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion)
{
    print("locationManager didExitRegion = \(region)")
    if let beaconRegion = region as? CLBeaconRegion
    {
        // do your stuff
    }
}

// and to know if iOS woke you up when your app was asleep or terminated, you need to check the presence of the UIApplicationLaunchOptionsLocationKey in your AppDelegate :

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    if launchOptions?[UIApplicationLaunchOptionsLocationKey] != nil 
    {
        // here you know you've been woken up about region crossing... 
        // you need to restart your region monitoring as explained in the documentation*, and do your stuff... 
    }
}

* UIApplicationLaunchOptionsLocationKey doc here

这是一个非常简化的代码,除了所有这些之外,你需要处理一些事情,例如用户知识以保持位置始终在后台等等......但这是一种方法。