#import "AmapLocationPlugin.h" #import "FlutterAmapView.h" #import @interface AmapLocationPlugin() { AMapLocationManager* _aMapManager; FlutterMethodChannel* _flutterChannel; FlutterAmapViewFactory* _amapViewFactory; } @end @implementation AmapLocationPlugin -(instancetype)initWithBinaryMessager:(NSObject *)messenger { if(self == [super init]){ _flutterChannel = [FlutterMethodChannel methodChannelWithName:@"amap_location" binaryMessenger:messenger]; _amapViewFactory = [[FlutterAmapViewFactory alloc]initWithMessenger:messenger]; } return self; } + (void)registerWithRegistrar:(NSObject*)registrar { AmapLocationPlugin* instance = [[AmapLocationPlugin alloc] initWithBinaryMessager:registrar.messenger]; [registrar addMethodCallDelegate:instance channel:[instance channel]]; [registrar registerViewFactory:[instance viewFactory] withId:@"com.i2edu.mapView"]; [registrar addApplicationDelegate:instance]; } -(FlutterMethodChannel *)channel{ return _flutterChannel; } -(FlutterAmapViewFactory *)viewFactory{ return _amapViewFactory; } - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { if ([@"getPlatformVersion" isEqualToString:call.method]) { result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); } else if([@"startLocation" isEqualToString:call.method]){ [self startLocation:call result:result]; } else if([@"closeLocation" isEqualToString:call.method]){ [self closeLocation:call result:result]; } else if([@"appleNavigate" isEqualToString:call.method]){ NSNumber* lat = [call.arguments objectForKey:@"lat"]; NSNumber* lng = [call.arguments objectForKey:@"lng"]; CLLocationCoordinate2D _currentLocationCoordinate = CLLocationCoordinate2DMake(lat.doubleValue, lng.doubleValue); MKMapItem* currentLocation = [MKMapItem mapItemForCurrentLocation]; MKMapItem* toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:_currentLocationCoordinate addressDictionary:nil]]; toLocation.name = [call.arguments objectForKey:@"title"]; [MKMapItem openMapsWithItems:@[currentLocation, toLocation] launchOptions:@{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving,MKLaunchOptionsShowsTrafficKey: [NSNumber numberWithBool:YES]}]; result(nil); }else { result(FlutterMethodNotImplemented); } } - (void)startLocation:(FlutterMethodCall*)call result:(FlutterResult)result{ NSNumber* isOnceLocation = call.arguments[@"isOnceLocation"]; NSNumber* isNeedAddress = call.arguments[@"isNeedAddress"]; NSNumber* mockEnable = call.arguments[@"mockEnable"]; // NSNumber* locationInterval = call.arguments[@"locationInterval"]; NSNumber* locationTimeOut = call.arguments[@"locationTimeOut"]; NSNumber* locationMode = call.arguments[@"locationMode"]; NSLog(@"开始定位"); _aMapManager = [[AMapLocationManager alloc]init]; _aMapManager.delegate =self; _aMapManager.detectRiskOfFakeLocation=mockEnable.boolValue; [_aMapManager setLocatingWithReGeocode:isNeedAddress.boolValue]; // 定位超时时间,最低2s,此处设置为10s _aMapManager.locationTimeout = locationTimeOut.intValue; // 逆地理请求超时时间,最低2s,此处设置为10s _aMapManager.reGeocodeTimeout = locationMode.intValue; if(locationMode.intValue ==0){ [_aMapManager setDesiredAccuracy:kCLLocationAccuracyThreeKilometers]; }else if(locationMode.intValue ==1){ [_aMapManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters]; }else{ [_aMapManager setDesiredAccuracy:kCLLocationAccuracyBest]; } if(isOnceLocation.boolValue){ NSLog(@"一次定位"); [_aMapManager requestLocationWithReGeocode:isNeedAddress.boolValue completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) { [self handleResult:location regeocode:regeocode error:error]; }]; }else{ [_aMapManager startUpdatingLocation]; } result(nil); } - (void)handleResult:(CLLocation *)location regeocode:(AMapLocationReGeocode *)regeocode error:(NSError *)error{ NSLog(@"定位返回"); if(error){ NSLog(@"error:%@",error); [_flutterChannel invokeMethod:@"location" arguments:@""]; }else{ NSMutableDictionary* result = [NSMutableDictionary dictionary]; result[@"lon"] =@(location.coordinate.longitude); result[@"lat"] =@(location.coordinate.latitude); NSLog(@"location:{lat:%f; lon:%f; accuracy:%f}", location.coordinate.latitude, location.coordinate.longitude, location.horizontalAccuracy); if (regeocode) { result[@"citycode"]=regeocode.citycode; result[@"adcode"]=regeocode.adcode; result[@"country"]=regeocode.country; result[@"province"]=regeocode.province; result[@"city"]=regeocode.city; result[@"district"]=regeocode.district; // result[@"road"]=regeocode.r; result[@"street"]=regeocode.street; result[@"number"]=regeocode.number; result[@"poiname"]=regeocode.POIName; result[@"errorCode"]=error==nil?nil:@(error.code); result[@"errorInfo"]=nil; // result[@"locationType"]=location.; // result[@"locationDetail"]=location.detail; result[@"aoiname"]=regeocode.AOIName; result[@"address"]=regeocode.formattedAddress; // result[@"poiid"]=location.poi; result[@"floor"]=[[NSString alloc]initWithFormat:@"%ld",(long)location.floor.level]; result[@"description"]=regeocode.description; result[@"time"]=@(location.timestamp.timeIntervalSinceNow); result[@"provider"]=regeocode.province; // result[@"accuracy"]=location.accur; // result[@"isOffset"]=location.; NSLog(@"reGeocode:%@", regeocode); [_flutterChannel invokeMethod:@"location" arguments:[self convertToJsonData:result]]; } } } //格式化输出 - (NSString *)convertToJsonData:(NSDictionary *)userInfo { NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:userInfo options:nil error:&error]; NSString *jsonString=@""; if (!jsonData) { NSLog(@"%@", error); } else { jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; } return jsonString; } - (void)closeLocation:(FlutterMethodCall*)call result:(FlutterResult)result{ NSLog(@"结束定位"); if(_aMapManager){ _aMapManager.delegate=nil; [_aMapManager stopUpdatingLocation]; _aMapManager = nil; } result(nil); } - (void)amapLocationManager:(AMapLocationManager *)manager didFailWithError:(NSError *)error{ NSLog(@"定位出现错误:%@",error); } - (void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager*)locationManager{ NSLog(@"申请权限"); [locationManager requestAlwaysAuthorization]; } - (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{ [self handleResult:location regeocode:reGeocode error:nil]; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"]; NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithContentsOfFile:bundlePath]; NSString *gaodeAppKey = [infoDict objectForKey:@"GaoDeAppKey"]; [AMapServices sharedServices].apiKey = gaodeAppKey; NSLog(@"配置高德地图定位"); return YES; } @end