Kiểm tra xem dịch vụ vị trí đã được bật chưa


87

Tôi đã thực hiện một số nghiên cứu về CoreLocation. Gần đây, tôi đã gặp sự cố đã được đề cập ở những nơi khác, nhưng trong Mục tiêu C và iOS 8.

Tôi cảm thấy hơi ngớ ngẩn khi hỏi điều này, nhưng làm thế nào bạn có thể kiểm tra xem dịch vụ định vị có được bật hay không bằng cách sử dụng nhanh chóng, trên iOS 9?

Trên iOS 7 (và có thể là 8?), Bạn có thể sử dụng locationServicesEnabled(), nhưng điều đó dường như không hoạt động khi biên dịch cho iOS 9.

Vì vậy, làm thế nào tôi sẽ thực hiện điều này?

Cảm ơn!

Câu trả lời:


243

Thêm CLLocationManagerDelegatequyền thừa kế lớp của bạn và sau đó bạn có thể thực hiện kiểm tra này:

Phiên bản Swift 1.x - 2.x:

if CLLocationManager.locationServicesEnabled() {
    switch CLLocationManager.authorizationStatus() {
    case .NotDetermined, .Restricted, .Denied:
        print("No access")
    case .AuthorizedAlways, .AuthorizedWhenInUse:
        print("Access")
    }
} else {
    print("Location services are not enabled")
}

Phiên bản Swift 4.x:

if CLLocationManager.locationServicesEnabled() {
     switch CLLocationManager.authorizationStatus() {
        case .notDetermined, .restricted, .denied:
            print("No access")
        case .authorizedAlways, .authorizedWhenInUse:
            print("Access")
        }
    } else {
        print("Location services are not enabled")
}

Phiên bản Swift 5.1

if CLLocationManager.locationServicesEnabled() {
    switch CLLocationManager.authorizationStatus() {
        case .notDetermined, .restricted, .denied:
            print("No access")
        case .authorizedAlways, .authorizedWhenInUse:
            print("Access")
        @unknown default:
        break
    }
    } else {
        print("Location services are not enabled")
}

8
Đúng! Cảm ơn! Vấn đề của tôi là tôi đang cố gọi locatoinServicesEnabled trên trình quản lý của mình, tức là manager.locationServicesEnabled() thay vì CLLocationManager.loationServicesEnabled() Solved!
Brendan Chang

2
Tôi hiểu rằng mã của bạn chỉ là một ví dụ, nhưng nó hơi gây hiểu nhầm ... Tôi nghĩ tốt hơn authorizationStatuslà khi được đặt thành notDeterminedsau đó thay vì chỉ ghi nhật ký, sẽ tốt hơn nếu nhắc người dùng 'Cho phép / Không cho phép'
Honey

@Honey, chắc chắn rằng bạn có thể sử dụng nó tùy thích và như bạn đã nói mã chỉ là ví dụ để cho thấy nó có thể được sử dụng như thế nào.
Rashwan L

13

Trong mục tiêu-c

bạn nên theo dõi người dùng đã bị từ chối hoặc chưa được xác định, sau đó yêu cầu quyền hoặc gửi người dùng đến ứng dụng Cài đặt.

-(void)askEnableLocationService
{
   BOOL showAlertSetting = false;
   BOOL showInitLocation = false;

   if ([CLLocationManager locationServicesEnabled]) {

      switch ([CLLocationManager authorizationStatus]) {
        case kCLAuthorizationStatusDenied:
            showAlertSetting = true;
            NSLog(@"HH: kCLAuthorizationStatusDenied");
            break;
        case kCLAuthorizationStatusRestricted:
            showAlertSetting = true;
            NSLog(@"HH: kCLAuthorizationStatusRestricted");
            break;
        case kCLAuthorizationStatusAuthorizedAlways:
            showInitLocation = true;
            NSLog(@"HH: kCLAuthorizationStatusAuthorizedAlways");
            break;
        case kCLAuthorizationStatusAuthorizedWhenInUse:
            showInitLocation = true;
            NSLog(@"HH: kCLAuthorizationStatusAuthorizedWhenInUse");
            break;
        case kCLAuthorizationStatusNotDetermined:
            showInitLocation = true;
            NSLog(@"HH: kCLAuthorizationStatusNotDetermined");
            break;
        default:
            break;
      }
   } else {

      showAlertSetting = true;
      NSLog(@"HH: locationServicesDisabled");
  }

   if (showAlertSetting) {
       UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"Please enable location service for this app in ALLOW LOCATION ACCESS: Always, Go to Setting?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Open Setting", nil];
       alertView.tag = 199;
       [alertView show];
   }
   if (showInitLocation) {
       [self initLocationManager];
   }

}

Triển khai alertView Delegate sau đó đã cử người dùng kích hoạt dịch vụ vị trí nếu người dùng đã từ chối.

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

   if (alertView.tag == 199) {
       if (buttonIndex == 1) {
           [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
       }
       return;
   }
}

Init Location Manager

-(void)initLocationManager{
   self.locationManager = [[CLLocationManager alloc] init];
   if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
       [self.locationManager requestAlwaysAuthorization];
   }
}

Xin lưu ý rằng kCLAuthorizationStatusAuthorizedAlways và kCLAuthorizationStatusAuthorizedWhenInUse là sự khác biệt.


Cảm ơn vì phiên bản obj-c này, mặc dù câu hỏi ban đầu là về nhanh. Gợi ý thêm: Cuộc gọi requestWhenInUseAuthorization nếu tình trạng không xác định, thiết lập mục plist có liên quan để mô tả việc sử dụng (có thể khu trú), và có thể thực hiện didChangeAuthorizationStatus
Giorgio Barchiesi

9

SWIFT (Kể từ ngày 24 tháng 7 năm 2018)

if CLLocationManager.locationServicesEnabled() {

}

điều này sẽ cho bạn biết nếu người dùng đã chọn một cài đặt cho yêu cầu cấp quyền vị trí của ứng dụng


8

Nó chỉ là một hàm 2 dòng trong Swift 4:

import CoreLocation

static func isLocationPermissionGranted() -> Bool
{
    guard CLLocationManager.locationServicesEnabled() else { return false }
    return [.authorizedAlways, .authorizedWhenInUse].contains(CLLocationManager.authorizationStatus())
}

6

Đây là định dạng mà Apple đề xuất.

  switch CLLocationManager.authorizationStatus() {
      case .notDetermined:
         // Request when-in-use authorization initially
         break
      case .restricted, .denied:
         // Disable location features
         break
      case .authorizedWhenInUse, .authorizedAlways:
         // Enable location features
         break
      }

Đây là một ví dụ đầy đủ.

Điều này bao gồm AlertViewmột nút có nút để đưa người dùng đến Settingsmàn hình nếu trước đó bị từ chối truy cập.

import CoreLocation
let locationManager = CLLocationManager()

class SettingsTableViewController:CLLocationManagerDelegate{

    func checkUsersLocationServicesAuthorization(){
        /// Check if user has authorized Total Plus to use Location Services
        if CLLocationManager.locationServicesEnabled() {
            switch CLLocationManager.authorizationStatus() {
            case .notDetermined:
                // Request when-in-use authorization initially
                // This is the first and the ONLY time you will be able to ask the user for permission
                self.locationManager.delegate = self
                locationManager.requestWhenInUseAuthorization()
                break

            case .restricted, .denied:
                // Disable location features
                switchAutoTaxDetection.isOn = false
                let alert = UIAlertController(title: "Allow Location Access", message: "MyApp needs access to your location. Turn on Location Services in your device settings.", preferredStyle: UIAlertController.Style.alert)

                // Button to Open Settings
                alert.addAction(UIAlertAction(title: "Settings", style: UIAlertAction.Style.default, handler: { action in
                    guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
                        return
                    }
                    if UIApplication.shared.canOpenURL(settingsUrl) {
                        UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                            print("Settings opened: \(success)") 
                        })
                    }
                }))
                alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil))
                self.present(alert, animated: true, completion: nil)

                break

            case .authorizedWhenInUse, .authorizedAlways:
                // Enable features that require location services here.
                print("Full Access")
                break
            }
        }
    }
}

5

Đối với swift3.0 trở lên, nếu thường xuyên kiểm tra tính khả dụng của các dịch vụ định vị, hãy tạo một lớp như bên dưới,

    import CoreLocation

    open class Reachability {
        class func isLocationServiceEnabled() -> Bool {
            if CLLocationManager.locationServicesEnabled() {
                switch(CLLocationManager.authorizationStatus()) {
                    case .notDetermined, .restricted, .denied:
                    return false
                    case .authorizedAlways, .authorizedWhenInUse:
                    return true
                    default:
                    print("Something wrong with Location services")
                    return false
                }
            } else {
                    print("Location services are not enabled")
                    return false
              }
            }
         }

và sau đó sử dụng nó như thế này trong VC của bạn

    if Reachability.isLocationServiceEnabled() == true {
    // Do what you want to do.
    } else {
    //You could show an alert like this.
        let alertController = UIAlertController(title: "Location 
        Services Disabled", message: "Please enable location services 
        for this app.", preferredStyle: .alert)
        let OKAction = UIAlertAction(title: "OK", style: .default, 
        handler: nil)
        alertController.addAction(OKAction)
        OperationQueue.main.addOperation {
            self.present(alertController, animated: true, 
            completion:nil)
        }
    }

3

Khi bạn gọi -startLocation, nếu dịch vụ vị trí bị người dùng từ chối, đại diện trình quản lý vị trí sẽ nhận được cuộc gọi tới - locationManager:didFailWithError: với kCLErrorDeniedmã lỗi. Điều này hoạt động cả trên tất cả các phiên bản iOS.


Cảm ơn. Thật không may, khi tôi cố gắng đó, nó cho thấy: Use of unresolved identifier 'kCLErrorDenied'. Suy nghĩ?
Brendan Chang

1

Trong Swift 3.0

if (CLLocationManager.locationServicesEnabled())
            {
                locationManager.delegate = self
                locationManager.desiredAccuracy = kCLLocationAccuracyBest
                if ((UIDevice.current.systemVersion as NSString).floatValue >= 8)
                {
                    locationManager.requestWhenInUseAuthorization()
                }

                locationManager.startUpdatingLocation()
            }
            else
            {
                #if debug
                    println("Location services are not enabled");
                #endif
            }

1

Để xin phép các dịch vụ vị trí bạn sử dụng:

yourSharedLocationManager.requestWhenInUseAuthorization()

Nếu trạng thái hiện chưa được xác định, một cảnh báo sẽ hiển thị nhắc người dùng cho phép truy cập. Nếu quyền truy cập bị từ chối, ứng dụng của bạn sẽ được thông báo trong CLLocationManagerDelegate, tương tự như vậy nếu quyền bị từ chối vào bất kỳ thời điểm nào, bạn sẽ được cập nhật tại đây.

Có hai trạng thái riêng biệt bạn cần kiểm tra để xác định các quyền hiện tại.

  • Nếu người dùng có bật các dịch vụ vị trí chung hay không

CLLocationManager.locationServicesEnabled()

  • Nếu người dùng đã cấp quyền chính xác cho ứng dụng của bạn ..

CLLocationManager.authorizationStatus() == .authorizedWhenInUse

Bạn có thể thêm tiện ích mở rộng là một tùy chọn hữu ích:

extension CLLocationManager {
static func authorizedToRequestLocation() -> Bool {
    return CLLocationManager.locationServicesEnabled() &&
        (CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse)
}

}

Ở đây nó đang được truy cập khi người dùng yêu cầu chỉ đường lần đầu tiên:

 private func requestUserLocation() {
    //when status is not determined this method runs to request location access
    locationManager.requestWhenInUseAuthorization()

    if CLLocationManager.authorizedToRequestLocation() {

        //have accuracy set to best for navigation - accuracy is not guaranteed it 'does it's best'
        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation

        //find out current location, using this one time request location will start the location services and then stop once have the location within the desired accuracy -
        locationManager.requestLocation()
    } else {
        //show alert for no location permission
        showAlertNoLocation(locationError: .invalidPermissions)
    }
}

Đây là đại biểu:

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

    if !CLLocationManager.authorizedToRequestLocation() {
        showAlertNoLocation(locationError: .invalidPermissions)
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.