2012-04-06 73 views
2

我把放在一起的應用程序在用戶離開房屋時發出通知。所以我實施了半徑爲25的區域監控。 我遇到的問題是模擬(iPhone模擬器5.0)時,我設置了自定義位置(主頁)設置區域邊界。然後在區域邊界之外輸入另一個自定義位置,即在街道的盡頭。但該應用程序不會註冊該區域的退出。只有當我設置家庭地點和地區時,然後更改爲Apple總部纔會註冊併發出通知。 在後臺模式下,應用程序切換到重要的位置更改。但是在前景或背景中它有相同的問題。 即時消息尋找,如「提醒」應用程序,讓應用程序在退出/離開區域邊界後即刻發出通知,即走到街道盡頭。我如何使它更準確?如何提高區域邊界穿越的準確性(模擬)(地理圍牆)

這裏是我的一些viewcontroller.m文件:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // Create empty array to add region events to. 
    updateEvents = [[NSMutableArray alloc] initWithCapacity:0]; 

    // Create location manager with filters set for battery efficiency. 
    locationManager = [[CLLocationManager alloc] init]; 
    locationManager.delegate = self; 
    locationManager.distanceFilter = kCLLocationAccuracyBest; //could try KLDistanceFilterNone; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 

    // Start updating location changes. 
      [locationManager startUpdatingLocation]; 
} 

- (void)viewDidAppear:(BOOL)animated { 
    // Get all regions being monitored for this application. 
    NSArray *regions = [[locationManager monitoredRegions] allObjects]; 

    // Iterate through the regions and add annotations to the map for each of them. 
      for (int i = 0; i < [regions count]; i++) { 
        CLRegion *region = [regions objectAtIndex:i]; 
    RegionAnnotation *annotation = [[RegionAnnotation alloc] initWithCLRegion:region]; 
        [regionsMapView addAnnotation:annotation]; 
        [annotation release]; 
      } 
} 

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { 
    NSLog(@"didFailWithError: %@", error); 
} 


- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 
    NSLog(@"didUpdateToLocation %@ from %@", newLocation, oldLocation); 

    // Work around a bug in MapKit where user location is not initially zoomed to. 
      if (oldLocation == nil) { 
    // Zoom to the current user location. 
        MKCoordinateRegion userLocation = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 100.0, 100.0); 
        [regionsMapView setRegion:userLocation animated:YES]; 
      } 
} 


- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { 
    NSString *event = [NSString stringWithFormat:@"didEnterRegion %@ at %@", region.identifier, [NSDate date]]; 

      [self updateWithEvent:event]; 
} 


- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { 
    NSString *event = [NSString stringWithFormat:@"didExitRegion %@ at %@", region.identifier, [NSDate date]]; 
      [self updateWithEvent:event]; 
//implement local notification: 
    UIApplication *app    = [UIApplication sharedApplication]; 
    UILocalNotification *notification = [[UILocalNotification alloc] init]; 
    [[UIApplication sharedApplication] cancelAllLocalNotifications]; 

    if (notification == nil) 
     return; 
    notification.alertBody = [NSString stringWithFormat:@"Did You Lock Your House?"]; 
    notification.alertAction = @"Lock House"; 
    notification.soundName = UILocalNotificationDefaultSoundName; 
    notification.applicationIconBadgeNumber = 1; 
    [app presentLocalNotificationNow:notification]; 

    [notification release]; 
// ends here 

//following is an alert for the case of exiting boundary whilst app is in foreground 
    UIAlertView *alr=[[UIAlertView alloc] initWithTitle:@"Reminder didExitRegion" message:region.identifier delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Ok",nil]; 

    [alr show]; 

    [alr release]; 
    //ends here 
} 

- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error { 
    NSString *event = [NSString stringWithFormat:@"monitoringDidFailForRegion %@: %@", region.identifier, error]; 

      [self updateWithEvent:event]; 
} 

- (IBAction)addRegion { 
    if ([CLLocationManager regionMonitoringAvailable]) { 
    // Create a new region based on the center of the map view. 
    CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(regionsMapView.centerCoordinate.latitude, regionsMapView.centerCoordinate.longitude); 
    CLRegion *newRegion = [[CLRegion alloc] initCircularRegionWithCenter:coord 
                                               radius:25.0 
                                            identifier:[NSString stringWithFormat:@"%f, %f", regionsMapView.centerCoordinate.latitude, regionsMapView.centerCoordinate.longitude]]; 

    // Create an annotation to show where the region is located on the map. 
        RegionAnnotation *myRegionAnnotation = [[RegionAnnotation alloc] initWithCLRegion:newRegion]; 
        myRegionAnnotation.coordinate = newRegion.center; 
        myRegionAnnotation.radius = newRegion.radius; 

        [regionsMapView addAnnotation:myRegionAnnotation]; 

        [myRegionAnnotation release]; 

    // Start monitoring the newly created region. 
        [locationManager startMonitoringForRegion:newRegion desiredAccuracy:kCLLocationAccuracyBest]; 

        [newRegion release]; 
      } 
    else { 
    NSLog(@"Region monitoring is not available."); 
      } 
} 

這項工作已經從「區域」模板的。

+0

我在iPhone上部署了應用程序,設置了一個15-25米之間的區域,並在該區域外走了一個很好的50米,沒有任何東西。任何建議? – 2012-04-06 20:07:04

回答

1

這就是您將獲得的最佳準確度。該區域匹配只使用細胞塔三角測量,因此在密集區域可能觸發50-100米,而稀疏區域可能需要100米。

如果你想要更精細的細節,那麼你會ned使用直接的位置服務。但那會吃電池,所以選擇你的毒藥。

6

iOS模擬器對於退出/輸入的geofence更新而言是非常糟糕的。你可以通過這種方式來設置你的應用的地理圍欄作爲你當前的位置。然後,從iOS模擬器的調試菜單中,按位置,然後選擇Freeway Drive。您的設備現在將模擬沿高速公路行駛,如果您的模擬器與我的模擬器相似,則它不會註冊didExitRegion事件。

爲什麼?地區主要取決於蘋果公司使用Wi-Fi,手機信號塔以及手機上其他應用程序請求位置的隱藏算法。看到模擬器不使用Wi-Fi或手機塔...區域監控將是不可能的。

要測試你的代碼的其餘部分是該地區出口工作後,你可以創建一個按鈕或一些手動觸發您的LocationManager:didExitRegion:方法。我也強烈建議您在設備上編譯項目,方法是將其插入iPhone模擬器並更改爲iOS設備。然後,您可以拔下設備並從手機運行您的應用程序進行測試。

相關問題