2013-10-02 42 views
23

當我的應用沒有運行時,我很難解決這個問題。我已經實現了locationManager:didRangeBeacons:inRegion:,它在應用程序在前臺或後臺運行時調用,但是當我退出應用程序並鎖定屏幕時,它似乎沒有任何操作。位置服務圖標消失,我永遠不知道我進入了一個燈塔範圍。 LocalNotification是否仍然有效?測距信標只適用於應用程序運行?

我有位置更新和使用在背景模式(XCode 5)中選擇的藍牙LE配件我不認爲我需要它們。

任何幫助非常感謝。

-(void)watchForEvents { // this is called from application:didFinishLaunchingWithOptions 
    id class = NSClassFromString(@"CLBeaconRegion"); 
    if (!class) { 
     return; 
    } 

    CLBeaconRegion * rflBeacon = [[CLBeaconRegion alloc] initWithProximityUUID:kBeaconUUID identifier:kBeaconString]; 
    rflBeacon.notifyOnEntry = YES; 
    rflBeacon.notifyOnExit = NO; 
    self.locationManager = [[CLLocationManager alloc] init]; 
    self.locationManager.delegate = self; 
    [self.locationManager startRangingBeaconsInRegion:rflBeacon]; 
    [self.locationManager startMonitoringForRegion:rflBeacon]; 
} 

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region { 
    if (beacons.count == 0 || eventRanged) { // breakpoint set here for testing 
     return; 
    } 

    eventRanged = YES; 
    if (backgroundMode) { // this is set in the EnterBackground/Foreground delegate calls 
     UILocalNotification *notification = [[UILocalNotification alloc] init]; 
     notification.alertBody = [NSString stringWithFormat:@"Welcome to the %@ event.",region.identifier]; 
     notification.soundName = UILocalNotificationDefaultSoundName; 
     [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 
    } 

    // normal processing here... 
} 
+0

「(。我也有在此之前的工作,它會給鎖定屏幕上的通知,現在不工作)」 ......你有什麼改變? –

+0

行..我確實瞭解瞭如何在後臺和上面的問題已更新時再次使我的徽章出現在鎖定屏幕上:[self.locationManager startMonitoringForRegion:rflBeacon]; –

+0

這可能會幫助你:http://stackoverflow.com/questions/19127282/ibeacon-notification-when-the-app-is-not-running – random

回答

1

如果您只是想在您進入燈塔區域時收到通知,那麼您的應用應當醒來。我知道的唯一背景限制實際上是在iOS設備上託管一個iBeacon。在這種情況下,應用程序需要在前臺實際打開。對於這種情況,你最好只做直線CoreBluetooth CBPeripheralManager實施。這樣你就可以在後臺獲得一些廣告能力。

+0

我弄清楚,如果我啓動監視區域使用該信標作爲區域,然後如果應用程序在後臺運行,我會在鎖定屏幕上收到通知。我認爲startMonitoringForRegion會在應用程序尚未運行時啓動。 –

+0

每個Apple的AirLocate示例代碼: 「didDetermineState():用戶可以當應用程序沒有運行時在區域內或區域外轉換。發生這種情況時,CoreLocation會立即啓動應用程序,調用此委託方法,並讓用戶知道v ia當地通知。「 – barbazoo

+0

是的,我沒有閱讀正確的問題。我只是指在後臺託管iBeacon。即如果您運行的是託管iBeacon的應用程序,則該應用程序需要在前臺運行以供其他人進入該區域。我會編輯。 –

11

監控可以啓動未運行的應用程序。測距不能。

的關鍵,其監測啓動您的應用程序是設置此不良記錄標誌您CLBeaconRegion,R egion.notifyEntryStateOnDisplay = YES; 這甚至完全後,重新啓動您的手機可以啓動你的上一個區域過渡的應用程序。但有幾個注意事項:

  1. 您的應用程序僅在幾秒鐘內啓動到後臺。 (嘗試將NSLog語句添加到applicationDidEnterBackground和其他AppDelegate中的方法以查看正在進行的操作。)
  2. iOS可以自己花時間決定是否輸入CLBeaconRegion。我已經看到它需要長達四分鐘。

儘管您不能有範圍喚醒您的應用程序,但您可以使您的應用程序同時執行監視和測距。如果監控喚醒您的應用程序並將其放入後臺幾秒鐘,則會立即啓動各種回調。這使您有機會在應用程序仍在運行時執行任何快速測距操作。

編輯:進一步的調查證明,notifyEntryStateOnDisplay對背景監測沒有影響,所以無論你是否有這個標誌,上述都應該工作。見this detailed explanation and discussion of delays you may experience

+0

的缺陷是否是受制裁的iBeacons的四分鐘範圍特性還是可能試圖模仿iBeacon的限制?四分鐘就是我們希望用戶看到的東西的幾個街區。 –

+0

我的猜測是,只是一個猜測,就是iOS試圖通過每4分鐘左右進行一次藍牙掃描來節省電量,因爲沒有應用程序處於前景測距或監控狀態時。 – davidgyoung

+0

我不確定'notifiyEntryStateOnDisplay'是否具有您認爲它具有的效果。我的理解是,當設置爲YES時,iOS會推遲通知您的區域條目通知應用,直到用戶喚醒設備的顯示,而不是立即發送。蘋果公司在WWDC演示中給出的例子是一個會員卡應用程序,你不想在有人走過商店時ping通電話,但是當用戶主動開始使用他們的電話時,它。 – Defragged

7

以下是你需要遵循的範圍在後臺進程:

  1. 對於任何CLBeaconRegion始終保持監控上,在背景或前景,並保持notifyEntryStateOnDisplay = YES
  2. notifyEntryStateOnDisplay電話locationManager:didDetermineState:forRegion:的背景下,所以實行這個代表電話...

...像這樣:

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{ 

    if (state == CLRegionStateInside) { 


     //Start Ranging 
     [manager startRangingBeaconsInRegion:region]; 
    } 

    else{ 

     //Stop Ranging 
     [manager stopRangingBeaconsInRegion:region]; 
    } 

} 

我希望這有助於。

+0

位置管理器的代表可以是任何對象還是應該由appdelegate執行?對我而言,只有在appdelegate是位置管理員的代表時才能工作......您是否看到任何原因? – rops

+2

是的,它可以使用任何對象 - 請參閱此示例https://github.com/manishnath/iBeaconCenter – manishnath

+1

小評論:您需要使用(CLBeaconRegion *)對類型進行類型轉換,因爲startRangingBeaconsInRegion需要CLBeaconRegion *,didDetermineState會傳遞一個CLRegion * – CharlesA

-2

您可以在後臺進行測量。但是,有一個問題。用戶必須將應用程序放到前臺,這是您開始測量的時間。然後,即使用戶鎖定了屏幕並且該應用程序在後臺運行,它也會繼續保持範圍,並且永遠每1秒調用一次didRangeBeacons回調。

要打開背景位置更新,請選擇您的項目,轉到信息並添加一行稱爲「所需的背景模式」。然後添加相關項目:位置更新,通過核心藍牙通信/共享數據等。

現在,一旦您在進入該區域時得到回調,您的應用將在後臺喚醒並通知用戶。用戶打開應用程序將應用程序放在前臺。此時,您可以撥打startRangingBeaconsInRegion開始測距過程。另外,請調用方法startUpdatingLocation,它將在後臺更新位置。

2

您正在這裏做兩個獨立的操作 - 「測距」信標和監測區域。您可以監視背景中的某個區域,但不監測距離信標。

因此,您的實施locationManager:didRangeBeacons:inRegion:不會在後臺調用。相反,你要startMonitoringForRegion調用將導致一個/下面的一些方法被稱爲:

– locationManager:didEnterRegion: 
– locationManager:didExitRegion: 
– locationManager:didDetermineState:forRegion: 

這些將被調用的背景。您可以在這一點觸發本地通知,就像在您的原始代碼中一樣。

6

代碼爲iOS 9範圍的信標中的背景下,通過使用位置更新

  1. 打開項目設置 - >功能 - >背景模式 - >切換Location UpdatesUses Bluetooth LE accessoriesON

  2. 創建CLLocationManager,要求Always監控授權(不要忘記添加Application does not run in backgroundNONSLocationAlwaysUsageDescription在應用程序的info.plist),並設置以下屬性:

    locationManager!.delegate = self 
    locationManager!.pausesLocationUpdatesAutomatically = false 
    locationManager!.allowsBackgroundLocationUpdates = true; 
    
  3. 開始爲信標和監測區域:

    locationManager!.startMonitoringForRegion(yourBeaconRegion) 
    locationManager!.startRangingBeaconsInRegion(yourBeaconRegion) 
    locationManager!.startUpdatingLocation() 
    
    // Optionally for notifications 
    UIApplication.sharedApplication().registerUserNotificationSettings(
        UIUserNotificationSettings(forTypes: .Alert, categories: nil)) 
    
  4. 執行CLLocationManagerDelegate d在didEnterRegiondidExitRegion

同時發送startRangingBeaconsInRegion()startUpdatingLocation()消息(可選發送通知爲好),並設置stopRangingBeaconsInRegion()stopUpdatingLocation()請注意,此解決方案,但不建議由蘋果由於電池消費和客戶隱私!

這裏更多:https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-

+0

。謝謝你,兄弟! – rmvz3

+1

我建議採取大膽的「注意」部分,這是相當嚴重的;)感謝您的答案,尤其是鏈接! – mojuba

相關問題