2013-03-01 118 views
43

如何检查我的应用是否启用位置服务?检查iOS上的位置服务权限

我有2个故事板,我想检查位置服务。如果为我的应用启用位置服务,我想要启动带位置的地图故事板。否则,我想推出另一个故事板。我该如何编程?

回答

127

这是正确的。

这背后
if ([CLLocationManager locationServicesEnabled]){ 

    NSLog(@"Location Services Enabled"); 

    if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){ 
     alert = [[UIAlertView alloc] initWithTitle:@"App Permission Denied"  
              message:@"To re-enable, please go to Settings and turn on Location Service for this app." 
              delegate:nil 
           cancelButtonTitle:@"OK" 
           otherButtonTitles:nil]; 
     [alert show]; 
    } 
} 
+0

谢谢,这是我需要的。 – aziz 2013-07-14 21:31:35

+0

我认为这是问题的正确答案。 – 2013-10-24 16:23:42

+0

Wonderfull Stuff – Xeieshan 2014-01-26 20:48:16

11

检查CLLocationManager的locationServicesEnabled属性来检查系统范围的可用性。使用您的CLLocationManagerDelegate的locationManager:didFailWithError:方法并检查kCLErrorDenied错误以查看用户是否拒绝了位置服务。

BOOL locationAllowed = [CLLocationManager locationServicesEnabled]; 
if (!locationAllowed) 
{ 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location Service Disabled" 
                 message:@"To re-enable, please go to Settings and turn on Location Service for this app." 
                 delegate:nil 
               cancelButtonTitle:@"OK" 
               otherButtonTitles:nil]; 
     [alert show]; 
     [alert release]; 
} 

为您的应用程序使用此代码

- (void)viewDidLoad 
{ 
    locationManager = [[CLLocationManager alloc] init]; 

    locationManager.delegate = self; 

    locationManager.desiredAccuracy = kCLLocationAccuracyKilometer; 

    // Set a movement threshold for new events. 

    locationManager.distanceFilter = 500; 

    [locationManager startUpdatingLocation]; 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
} 

- (void)locationManager:(CLLocationManager *)manager 

    didUpdateLocations:(NSArray *)locations { 

    // If it's a relatively recent event, turn off updates to save power 

} 

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error 
{ 

    NSLog(@"%@",error); 
} 

如果位置服务禁用您的应用程序,然后它给你错误

Error Domain=kCLErrorDomain Code=1 "The operation couldn’t be completed. (kCLErrorDomain error 1.)" 
+0

我需要一个示例代码,您能否提供一个关于它的帖子? – 2013-03-01 08:05:11

+0

检查我编辑的答案 – 2013-03-01 08:09:17

+0

我把这段代码放在viewDidLoad中,locationAllowed总是返回YES。 – 2013-03-01 08:19:17

20
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ 

    NSLog(@"%@",error.userInfo); 
    if([CLLocationManager locationServicesEnabled]){ 

     NSLog(@"Location Services Enabled"); 

     if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){ 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"App Permission Denied" 
               message:@"To re-enable, please go to Settings and turn on Location Service for this app." 
               delegate:nil 
            cancelButtonTitle:@"OK" 
            otherButtonTitles:nil]; 
      [alert show]; 
     } 
    } 
} 

原因,这种方法会打电话的时候你的服务将被关闭定位服务。这段代码对我很有用。

11

经过大量的调查。我建议在标签上显示此消息,而不是在警报视图中显示。因为有很多情况需要测试(用户通常禁用位置服务,或者仅用于应用程序,删除应用程序,重新安装)。

其中一种情况会导致您的警报同时显示您的消息以及苹果的警报消息。你的警报将会落后于苹果的警惕。这是一个令人困惑和不合逻辑的行为。

我提出以下建议:

斯威夫特3:

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { 

    switch status { 
     case .notDetermined: 
      Log.verbose("User still thinking granting location access!") 
      manager.startUpdatingLocation() // this will access location automatically if user granted access manually. and will not show apple's request alert twice. (Tested) 
     break 

     case .denied: 
      Log.verbose("User denied location access request!!") 
      // show text on label 
      label.text = "To re-enable, please go to Settings and turn on Location Service for this app." 

      manager.stopUpdatingLocation() 
      loadingView.stopLoading() 
     break 

     case .authorizedWhenInUse: 
      // clear text 
      label.text = "" 
      manager.startUpdatingLocation() //Will update location immediately 
     break 

     case .authorizedAlways: 
      // clear text 
      label.text = "" 
      manager.startUpdatingLocation() //Will update location immediately 
     break 
     default: 
      break 
    } 
} 

的Objective-C:

- (void)locationManager:(CLLocationManager*)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { 
    switch (status) { 
     case kCLAuthorizationStatusNotDetermined: { 
      DDLogVerbose(@"User still thinking granting location access!"); 
      [locationManager startUpdatingLocation]; // this will access location automatically if user granted access manually. and will not show apple's request alert twice. (Tested) 
     } break; 
     case kCLAuthorizationStatusDenied: { 
      DDLogVerbose(@"User denied location access request!!"); 
      // show text on label 
      label.text = @"To re-enable, please go to Settings and turn on Location Service for this app."; 

      [locationManager stopUpdatingLocation]; 
      [loadingView stopLoading]; 
     } break; 
     case kCLAuthorizationStatusAuthorizedWhenInUse: 
     case kCLAuthorizationStatusAuthorizedAlways: { 
      // clear text 
      label.text = @""; 
      [locationManager startUpdatingLocation]; //Will update location immediately 
     } break; 
     default: 
      break; 
    } 
} 
24

测试在iOS 9.2

为了得到locatio ñ更新要经常检查用户的iOS设备启用

  • 位置服务和
  • 位置服务启用特定应用

,正确设置屏幕上推出用户启用

启动iOS设备位置设置页面

步骤。1转到项目设置 - >信息 - > URL类型 - >添加新的URL方案

enter image description here

Step.2使用下面的代码,推出直拨电话的位置设置页面: (注:URL计划是在iOS的不同10+,我们检查版本说明here

#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice 
currentDevice] systemVersion] compare:v options:NSNumericSearch] == 
NSOrderedAscending) 

//Usage 
NSString* url = SYSTEM_VERSION_LESS_THAN(@"10.0") ? @"prefs:root=LOCATION_SERVICES" : @"App-Prefs:root=Privacy&path=LOCATION"; 
      [[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]]; 

enter image description here

启动应用程序部位S ettings页

下面的代码用于启动直接应用程序的位置设置页面

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; 

enter image description here

以下是完整的代码示例: 的#define SYSTEM_VERSION_LESS_THAN(V)([[[的UIDevice currentDevice ] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

CLLocationManager *locationManager; 

-(void) checkLocationServicesAndStartUpdates 
{ 
    locationManager = [[CLLocationManager alloc] init]; 
    locationManager.delegate = self; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 

    if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) 
    { 
     [locationManager requestWhenInUseAuthorization]; 
    } 

    //Checking authorization status 
    if (![CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) 
    { 

     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Location Services Disabled!" 
                  message:@"Please enable Location Based Services for better results! We promise to keep your location private" 
                  delegate:self 
                cancelButtonTitle:@"Settings" 
                otherButtonTitles:@"Cancel", nil]; 

     //TODO if user has not given permission to device 
     if (![CLLocationManager locationServicesEnabled]) 
     { 
      alertView.tag = 100; 
     } 
     //TODO if user has not given permission to particular app 
     else 
     { 
      alertView.tag = 200; 
     } 

     [alertView show]; 

     return; 
    } 
    else 
    { 
     //Location Services Enabled, let's start location updates 
     [locationManager startUpdatingLocation]; 
    } 
} 

处理用户点击输入反应,并启动正确的位置设置

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 

    if(buttonIndex == 0)//Settings button pressed 
    { 
     if (alertView.tag == 100) 
     { 
      //This will open ios devices location settings 
      NSString* url = SYSTEM_VERSION_LESS_THAN(@"10.0") ? @"prefs:root=LOCATION_SERVICES" : @"App-Prefs:root=Privacy&path=LOCATION"; 
      [[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]]; 
     } 
     else if (alertView.tag == 200) 
     { 
      //This will opne particular app location settings 
      [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; 
     } 
    } 
    else if(buttonIndex == 1)//Cancel button pressed. 
    { 
     //TODO for cancel 
    } 
} 
+1

不是&&应该是OR(||)in if![CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)' – 2016-05-16 13:48:03

+1

这应该是疯狂的表决!迄今为止最快最简单的解决方案! – greenhouse 2016-06-22 10:59:02

+0

谢谢@greenhouse我很高兴它可以帮助你:) – swiftBoy 2016-06-22 11:30:38

1

最好的办法,处理所有的情况下! - >

//First, checking if the location services are enabled 
if(![CLLocationManager locationServicesEnabled]){ 
    [self showMessage:@"Please enable location services to detect location!" withTitle:@"Location not enabled"]; 
} 
else if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){ 
    //Now if the location is denied. 
    UIAlertController *alertController = [UIAlertController 
              alertControllerWithTitle:@"Enable location permission" 
              message:@"To auto detect location, please enable location services for this app" 
              preferredStyle:UIAlertControllerStyleAlert]; 

    alertController.view.tintColor = AppColor; 
    UIAlertAction *cancelAction = [UIAlertAction 
            actionWithTitle:@"Dismiss" 
            style:UIAlertActionStyleCancel 
            handler:^(UIAlertAction *action) 
            { 
             NSLog(@"Cancel action"); 
            }]; 

    UIAlertAction *goToSettings = [UIAlertAction 
           actionWithTitle:@"Settings" 
           style:UIAlertActionStyleDefault 
           handler:^(UIAlertAction *action) 
           { 
            //Simple way to open settings module 
            NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; 
            [[UIApplication sharedApplication] openURL:url]; 
           }]; 

    [alertController addAction:cancelAction]; 
    [alertController addAction:goToSettings]; 
    [self presentViewController:alertController animated:YES completion:^{ 
     alertController.view.tintColor = AppColor; 
    }]; 
} 
else{ 
    //Do whatever you want here 
} 
2

Swift 3.0 & iOS 10 Solution:


self.locationManager?.requestWhenInUseAuthorization() 
if CLLocationManager.locationServicesEnabled() && CLLocationManager.authorizationStatus() != CLAuthorizationStatus.denied { 
      locationManager?.delegate = self 
      locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation 
      locationManager?.distanceFilter = distanceFiler 
      locationManager?.startUpdatingLocation() 
     }else{ 
      let alertView = UIAlertView(title: "Location Services Disabled!", message: "Please enable Location Based Services for better results! We promise to keep your location private", delegate: self, cancelButtonTitle: "Settings", otherButtonTitles: "Cancel") 
      alertView.delegate = self 
      alertView.show() 
      return 
     } 


@objc(alertView:clickedButtonAtIndex:) func alertView(_ alertView: UIAlertView, clickedButtonAt buttonIndex: Int) { 
    if buttonIndex == 0 { 
      if let url = URL(string: "App-Prefs:root=LOCATION_SERVICES") { 
       UIApplication.shared.open(url, completionHandler: .none) 
      } 
    } 
    else if buttonIndex == 1 { 
     //TODO for cancel 
    } 

}