【问题标题】:iOS application asking the user two times to turn on location services when trying to access location with the location services turned offiOS 应用程序在位置服务关闭的情况下尝试访问位置时要求用户两次打开位置服务
【发布时间】:2014-01-08 10:29:52
【问题描述】:

我试图在我的 iOS 应用程序中单击一键获取用户位置。我正在使用下面的代码来启动位置管理器。

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
locationManager.distanceFilter = 1000;

if ([CLLocationManager locationServicesEnabled]) {
    [locationManager startUpdatingLocation];
}
else{
    UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"The location     services seems to be disabled from the settings." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
    [alert show];
    alert= nil;
}

当定位服务打开并且用户点击按钮时,它工作正常并且位置被正确获取。

但是当位置服务关闭并且用户尝试单击按钮时,根据我的代码,他的警报应该显示如上。但在它到达 else 循环之前,iOS 会显示一个系统级别的弹出窗口,如下所示。

在这个系统级别的警报视图之上,我自己的警报视图正在显示。这很令人沮丧。问题是,如果用户取消系统级弹出窗口而不是进入设置并尝试单击按钮,第二次也会发生同样的事情(两个警报场景)。但是,如果用户继续相同的步骤,则系统级警报现在不会显示。这意味着如上所示的系统级弹出窗口仅出现 2 次,之后什么也没有发生。如何处理这种情况。请帮忙。

【问题讨论】:

  • 您找到解决方案了吗?

标签: ios cllocationmanager


【解决方案1】:

通常会这样写:

if ([CLLocationManager locationServicesEnabled])
{
    [locationManager startUpdatingLocation];
}

并让 iOS 和用户自行解决。仅调用[CLLocationManager locationServicesEnabled] 将触发系统对话框(第一次)。以下代码未经测试,但应该按照您希望的方式工作:

if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized)
{
    if ([CLLocationManager locationServicesEnabled])
    {
        [locationManager startUpdatingLocation];
    }
}
else
{   
    UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"The location     services seems to be disabled from the settings." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
    [alert show];
    alert= nil;
}

编辑:

我上一个代码的结果是,用户甚至不会被提示为您的应用启用位置更新。您可以执行以下操作:

if ([[NSUserDefaults standardUserDefaults] objectForKey:@"userWasAskedForLocationOnce"])
{
    if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized)
    {
        UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error"
                                                      message:@"The location services seems to be disabled from the settings."
                                                     delegate:nil
                                            cancelButtonTitle:@"Ok"
                                            otherButtonTitles:nil];
        [alert show];
        alert= nil;
    }
}
else
{
    [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES]
                                              forKey:@"userWasAskedForLocationOnce"];

    if ([CLLocationManager locationServicesEnabled]) //this will trigger the system prompt
    {
        [locationManager startUpdatingLocation];
    }
}

在这种情况下,用户将收到系统提示以首次启用位置更新。如果他们启用它们,他们以后将不会收到任何提示。如果没有,他们会在后续启动时收到您的自定义警告 - 直到他们在设置应用中启用位置更新。

注意 1:为了测试此代码,您可能希望不时从设备中删除您的应用(用户默认设置在您删除应用之前一直存在)

注意 2:虽然此代码应该实现所需的行为,但它可能会让用户感到厌烦。你的 UI 应该安排好让用户知道位置服务被禁用 - 如果这部分代码在启动时自动执行,那么警报有点过分了。如果在某个用户的操作(点击按钮)之后执行,则可以显示警报。

【讨论】:

  • 如果我像下面这样反转 if 循环,结果会有所不同吗? if ([CLLocationManager locationServicesEnabled] == kCLAuthorizationStatusAuthorized) { if ([CLLocationManager authorizationStatus]) { [locationManager startUpdatingLocation]; } } else { UIAlertView *alert= [[UIAlertView alloc]initWithTitle:@"Error" message:@"位置服务似乎已从设置中禁用。" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [警报显示];警报=零; }
【解决方案2】:

对此我不确定。但是,每当用户接受或拒绝访问其当前位置的请求时,都会调用协议回调 locationManager:didChangeAuthorizationStatus:。详情请参考this

【讨论】:

  • 但是在这种情况下这有什么帮助呢?
猜你喜欢
  • 2014-01-28
  • 2018-03-02
  • 1970-01-01
  • 2012-03-01
  • 2014-12-10
  • 1970-01-01
  • 2016-01-19
  • 2015-10-04
  • 1970-01-01
相关资源
最近更新 更多