// LocationPlugin.mm #import #import typedef void (*ResultHandler) (const char *object); static ResultHandler gHandler; @interface LocationPlugin : NSObject // 采用CLLocationManagerDelegate协议 { CLLocationManager *locationManager; bool isReverseGeocoding; // 是否处于反地理编码处理 } + (LocationPlugin *)sharedInstance; @end // LocationPlugin类定义 @implementation LocationPlugin // 单例 static LocationPlugin *sharedInstance = nil; + (id)sharedInstance { @synchronized(self) { if(sharedInstance == nil) { sharedInstance = [[self alloc] init]; } } return sharedInstance; } // 开始获取位置信息 - (BOOL)startUpdatingLocation { if(locationManager == nil) { locationManager = [[CLLocationManager alloc] init]; } // 确认位置信息服务是否有效且被许可 BOOL isEnabledAndAuthorized = NO; if([CLLocationManager locationServicesEnabled]) { CLAuthorizationStatus status = [CLLocationManager authorizationStatus]; if(status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse) { isEnabledAndAuthorized = YES; } } if(!isEnabledAndAuthorized) { // 位置信息服务无效且未被许可时,请求用户授权 [locationManager requestWhenInUseAuthorization]; return NO; } // 开始获取位置信息 locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBest; [locationManager startUpdatingLocation]; return YES; } // 停止获取位置信息 - (void)stopUpdatingLocation { if(locationManager != nil) { [locationManager stopUpdatingLocation]; } } #pragma mark - CLLocationManagerDelegate协议的方法实现 // 更新位置信息时调用 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { if(isReverseGeocoding) { return; } // 基于获取的位置信息进行反地理编码以获取地址 isReverseGeocoding = YES; CLLocation *location = [locations lastObject]; CLGeocoder *geocoder = [[CLGeocoder alloc] init]; [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { isReverseGeocoding = NO; // 从CLPlacemark对象的FormattedAddressLines中获取地址的字符串 NSString *addressString = @""; NSString *addressOut = @""; if(placemarks.count >= 1) { CLPlacemark *placemark = [placemarks firstObject]; NSArray *addressLines = [placemark addressDictionary][@"FormattedAddressLines"]; addressString = [addressLines componentsJoinedByString:@" "]; addressOut = [NSString stringWithFormat:@"%@\t%@\t%@",placemark.country,placemark.administrativeArea,placemark.locality]; } // 创建作为参数传递的字符串 NSString *parameter = [NSString stringWithFormat:@"%f\t%f\t%f\t%f\t%@\t%@", location.coordinate.latitude, location.coordinate.longitude, location.speed, location.horizontalAccuracy, addressString,addressOut]; gHandler (parameter.UTF8String); }]; } //监听权限变化 - (void) locationManagerDidChangeAuthorization:(CLLocationManager *)manager{ CLAuthorizationStatus status = [CLLocationManager authorizationStatus]; NSLog(@"locationManagerDidChangeAuthorizatio1:%d",status); if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse) { NSLog(@"locationManagerDidChangeAuthorizatio2:%@",@"11111"); } } // 其他必须的方法 - (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {} - (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager {} - (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager {} @end #pragma mark - 接口 // 为回避C++命名粉碎,以C linkage进行声明 extern "C" { // 用于调用开始获取位置信息方法的接口 BOOL _startUpdatingLocation(ResultHandler resultHandler) { gHandler = resultHandler; LocationPlugin *instance = [LocationPlugin sharedInstance]; @synchronized(instance) { return [instance startUpdatingLocation]; } } // 用于调用停止获取位置信息方法的接口 void _stopUpdatingLocation() { LocationPlugin *instance = [LocationPlugin sharedInstance]; @synchronized(instance) { [instance stopUpdatingLocation]; } } }