From 4166d15eeaf28ba152a1ce9e89bf142f16b5b706 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 27 Jun 2024 13:30:23 -0400 Subject: [PATCH 01/16] have ios working --- CHANGELOG.md | 5 + android/build.gradle | 2 +- .../io/radar/flutter/RadarFlutterPlugin.java | 2 +- example/android/app/build.gradle | 2 +- example/ios/Flutter/AppFrameworkInfo.plist | 2 +- example/ios/Podfile | 2 +- example/ios/Runner.xcodeproj/project.pbxproj | 25 ++++- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- example/ios/Runner/Info.plist | 2 + example/lib/main.dart | 79 +++++++++---- ios/Classes/RadarFlutterPlugin.m | 106 ++++++++++-------- ios/flutter_radar.podspec | 4 +- lib/flutter_radar.dart | 74 ++++++++++-- pubspec.yaml | 2 +- 14 files changed, 220 insertions(+), 89 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c81afbe..93574c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 3.10.0 + +- Bump iOS version from 3.9.14 to 3.13.5 +- Bump Android version from 3.9.0 to 3.13.2 + # 3.9.1 - Bump iOS version from 3.9.7 to 3.9.14 diff --git a/android/build.gradle b/android/build.gradle index 11eef99..700e6f2 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -34,7 +34,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.9.8' + implementation 'io.radar:sdk:3.13.2' implementation 'com.google.android.gms:play-services-location:21.0.1' implementation 'com.google.code.gson:gson:2.8.6' } diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index 0ab9c9f..9b64869 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -324,7 +324,7 @@ private void initialize(MethodCall call, Result result) { String publishableKey = call.argument("publishableKey"); SharedPreferences.Editor editor = mContext.getSharedPreferences("RadarSDK", Context.MODE_PRIVATE).edit(); editor.putString("x_platform_sdk_type", "Flutter"); - editor.putString("x_platform_sdk_version", "3.9.1"); + editor.putString("x_platform_sdk_version", "3.10.0"); editor.apply(); Radar.initialize(mContext, publishableKey); result.success(true); diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index fb4140f..750378f 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -49,7 +49,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.9.8' + implementation 'io.radar:sdk:3.13.2' implementation "com.google.android.play:integrity:1.2.0" } } diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 4f8d4d2..8c6e561 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/example/ios/Podfile b/example/ios/Podfile index bfd60c4..b331c7b 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '11.0' +platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 3c16ff9..9e54d3c 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -149,6 +149,7 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 717FBB0054865DEA34CA9827 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -165,7 +166,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -208,10 +209,12 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -220,6 +223,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; }; + 717FBB0054865DEA34CA9827 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 8AED107CD2EAE06C6755A899 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -244,6 +264,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 3db53b6..e67b280 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ + UIApplicationSupportsIndirectInputEvents + diff --git a/example/lib/main.dart b/example/lib/main.dart index 4cbeaaa..dcd0298 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -67,6 +67,11 @@ class _MyAppState extends State with WidgetsBindingObserver { print('📍📍 onToken: $res'); } + @pragma('vm:entry-point') + static void onLocationPermissionStatus(Map res) { + print('📍📍 onLocationPermissionStatus: $res'); + } + Future initRadar() async { Radar.initialize('prj_test_pk_0000000000000000000000000000000000000000'); Radar.setUserId('flutter'); @@ -83,21 +88,25 @@ class _MyAppState extends State with WidgetsBindingObserver { Radar.onEvents(onEvents); Radar.onLog(onLog); Radar.onToken(onToken); + Radar.onLocationPermissionStatus(onLocationPermissionStatus); - await Radar.requestPermissions(false); + //await Radar.requestPermissions(false); - await Radar.requestPermissions(true); - var permissionStatus = await Radar.getPermissionsStatus(); - if (permissionStatus != "DENIED") { - var b = await Radar.startTrackingCustom({ - ... Radar.presetResponsive, - "showBlueBar": true, - }); - //Radar.startTracking('continuous'); - - var c = await Radar.getTrackingOptions(); - print("Tracking options $c"); - } + //await Radar.requestPermissions(true); + // var permissionStatus = await Radar.getPermissionsStatus(); + // if (permissionStatus != "DENIED") { + // var b = await Radar.startTrackingCustom({ + // ... Radar.presetResponsive, + // "showBlueBar": true, + // }); + // //Radar.startTracking('continuous'); + + // var c = await Radar.getTrackingOptions(); + // print("Tracking options $c"); + // } + var permissionStatus = await Radar.getLocationPermissionStatus(); + print(permissionStatus); + //await Radar.requestForegroundLocationPermission(); } @override @@ -179,6 +188,30 @@ class _MyAppState extends State with WidgetsBindingObserver { print("completeTrip: $resp"); }, child: Text('completeTrip'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + Radar.requestForegroundLocationPermission(); + + }, + child: Text('get foreground'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + Radar.requestBackgroundLocationPermission(); + + }, + child: Text('get background'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + Radar.openAppSettings(); + + }, + child: Text('openAppSettings'), ), ElevatedButton( style: raisedButtonStyle, @@ -339,9 +372,16 @@ class _MyAppState extends State with WidgetsBindingObserver { ElevatedButton( style: raisedButtonStyle, onPressed: () { - Radar.startTrackingVerified(token: true); + Radar.startTrackingVerified(); }, - child: Text('startTrackingVerified(token: true)'), + child: Text('startTrackingVerified()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () { + Radar.stopTrackingVerified(); + }, + child: Text('stopTrackingVerified()'), ), ElevatedButton( style: raisedButtonStyle, @@ -378,14 +418,7 @@ class _MyAppState extends State with WidgetsBindingObserver { }, child: Text('trackVerified'), ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - Map? resp = await Radar.trackVerifiedToken(); - print("trackVerifiedToken: $resp"); - }, - child: Text('trackVerifiedToken'), - ), + ElevatedButton( style: raisedButtonStyle, onPressed: () async { diff --git a/ios/Classes/RadarFlutterPlugin.m b/ios/Classes/RadarFlutterPlugin.m index 487b8fe..1b0e4bd 100644 --- a/ios/Classes/RadarFlutterPlugin.m +++ b/ios/Classes/RadarFlutterPlugin.m @@ -74,6 +74,8 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self startTrackingCustom:call withResult:result]; } else if ([@"startTrackingVerified" isEqualToString:call.method]) { [self startTrackingVerified:call withResult:result]; + } else if ([@"stopTrackingVerified" isEqualToString:call.method]) { + [self stopTrackingVerified:call withResult:result]; } else if ([@"stopTracking" isEqualToString:call.method]) { [self stopTracking:call withResult:result]; } else if ([@"isTracking" isEqualToString:call.method]) { @@ -124,12 +126,18 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { // do nothing } else if ([@"trackVerified" isEqualToString:call.method]) { [self trackVerified:call withResult:result]; - } else if ([@"trackVerifiedToken" isEqualToString:call.method]) { - [self trackVerifiedToken:call withResult:result]; } else if ([@"isUsingRemoteTrackingOptions" isEqualToString:call.method]) { [self isUsingRemoteTrackingOptions:call withResult:result]; } else if ([@"validateAddress" isEqualToString:call.method]) { - [self validateAddress:call withResult:result]; + [self validateAddress:call withResult:result]; + } else if ([@"getLocationPermissionStatus" isEqualToString:call.method]) { + [self getLocationPermissionStatus:result]; + } else if ([@"requestForegroundLocationPermission" isEqualToString:call.method]) { + [self requestForegroundLocationPermission:result]; + } else if ([@"requestBackgroundLocationPermission" isEqualToString:call.method]) { + [self requestBackgroundLocationPermission:result]; + } else if ([@"openAppSettings" isEqualToString:call.method]) { + [self openAppSettings:result]; } else if ([@"attachListeners" isEqualToString:call.method]) { [self attachListeners:call withResult:result]; } else if ([@"detachListeners" isEqualToString:call.method]) { @@ -148,7 +156,7 @@ - (void)initialize:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSString *publishableKey = argsDict[@"publishableKey"]; [[NSUserDefaults standardUserDefaults] setObject:@"Flutter" forKey:@"radar-xPlatformSDKType"]; - [[NSUserDefaults standardUserDefaults] setObject:@"3.9.1" forKey:@"radar-xPlatformSDKVersion"]; + [[NSUserDefaults standardUserDefaults] setObject:@"3.10.0" forKey:@"radar-xPlatformSDKVersion"]; [Radar initializeWithPublishableKey:publishableKey]; result(nil); } @@ -379,12 +387,6 @@ - (void)startTrackingCustom:(FlutterMethodCall *)call withResult:(FlutterResult) - (void)startTrackingVerified:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - BOOL token = NO; - NSNumber *tokenNumber = argsDict[@"token"]; - if (tokenNumber != nil && [tokenNumber isKindOfClass:[NSNumber class]]) { - token = [tokenNumber boolValue]; - } - BOOL beacons = NO; NSNumber *beaconsNumber = argsDict[@"beacons"]; if (beaconsNumber != nil && [beaconsNumber isKindOfClass:[NSNumber class]]) { @@ -397,7 +399,12 @@ - (void)startTrackingVerified:(FlutterMethodCall *)call withResult:(FlutterResul interval = [intervalNumber doubleValue]; } - [Radar startTrackingVerified:token interval:interval beacons:beacons]; + [Radar startTrackingVerifiedWithInterval:interval beacons:beacons]; + result(nil); +} + +- (void)stopTrackingVerified:(FlutterMethodCall *)call withResult:(FlutterResult)result { + [Radar stopTrackingVerified]; result(nil); } @@ -639,11 +646,17 @@ - (void)searchGeofences:(FlutterMethodCall *)call withResult:(FlutterResult)resu } else { limit = 10; } + BOOL includeGeometry = NO; + NSNumber *includeGeometryNumber = argsDict[@"includeGeometry"]; + if (includeGeometryNumber != nil && [includeGeometryNumber isKindOfClass:[NSNumber class]]) { + includeGeometry = [includeGeometryNumber boolValue]; + } + if (near != nil) { - [Radar searchGeofencesNear:near radius:radius tags:tags metadata:metadata limit:limit completionHandler:completionHandler]; + [Radar searchGeofencesNear:near radius:radius tags:tags metadata:metadata limit:limit includeGeometry:includeGeometry completionHandler:completionHandler]; } else { - [Radar searchGeofencesWithRadius:radius tags:tags metadata:metadata limit:limit completionHandler:completionHandler]; + [Radar searchGeofences:completionHandler]; } } @@ -956,19 +969,11 @@ - (void)trackVerified:(FlutterMethodCall *)call withResult:(FlutterResult)result beacons = [beaconsNumber boolValue]; } - RadarTrackCompletionHandler completionHandler = ^(RadarStatus status, CLLocation *location, NSArray *events, RadarUser *user) { + RadarTrackVerifiedCompletionHandler completionHandler = ^(RadarStatus status, RadarVerifiedLocationToken* token) { if (status == RadarStatusSuccess) { NSMutableDictionary *dict = [NSMutableDictionary new]; [dict setObject:[Radar stringForStatus:status] forKey:@"status"]; - if (location) { - [dict setObject:[Radar dictionaryForLocation:location] forKey:@"location"]; - } - if (events) { - [dict setObject:[RadarEvent arrayForEvents:events] forKey:@"events"]; - } - if (user) { - [dict setObject:[user dictionaryValue] forKey:@"user"]; - } + [dict setObject:[token dictionaryValue] forKey:@"token"]; result(dict); } }; @@ -976,27 +981,6 @@ - (void)trackVerified:(FlutterMethodCall *)call withResult:(FlutterResult)result [Radar trackVerifiedWithBeacons:beacons completionHandler:completionHandler]; } -- (void)trackVerifiedToken:(FlutterMethodCall *)call withResult:(FlutterResult)result { - NSDictionary *argsDict = call.arguments; - - BOOL beacons = NO; - NSNumber *beaconsNumber = argsDict[@"beacons"]; - if (beaconsNumber != nil && [beaconsNumber isKindOfClass:[NSNumber class]]) { - beacons = [beaconsNumber boolValue]; - } - - RadarTrackTokenCompletionHandler completionHandler = ^(RadarStatus status, NSString* token) { - if (status == RadarStatusSuccess) { - NSMutableDictionary *dict = [NSMutableDictionary new]; - [dict setObject:[Radar stringForStatus:status] forKey:@"status"]; - [dict setObject:token forKey:@"token"]; - result(dict); - } - }; - - [Radar trackVerifiedTokenWithBeacons:beacons completionHandler:completionHandler]; -} - - (void)validateAddress:(FlutterMethodCall *)call withResult:(FlutterResult)result { RadarValidateAddressCompletionHandler completionHandler = ^(RadarStatus status, RadarAddress * _Nullable address, RadarAddressVerificationStatus verificationStatus) { NSMutableDictionary *dict = [NSMutableDictionary new]; @@ -1015,6 +999,26 @@ - (void)validateAddress:(FlutterMethodCall *)call withResult:(FlutterResult)resu [Radar validateAddress:address completionHandler:completionHandler]; } +-(void)requestForegroundLocationPermission:(FlutterResult)result { + [Radar requestForegroundLocationPermission]; + result(nil); +} + +-(void)requestBackgroundLocationPermission:(FlutterResult)result { + [Radar requestBackgroundLocationPermission]; + result(nil); +} + +-(void)getLocationPermissionStatus:(FlutterResult)result { + RadarLocationPermissionStatus *status = [Radar getLocationPermissionStatus]; + result([status dictionaryValue]); +} + +-(void)openAppSettings:(FlutterResult)result { + [Radar openAppSettings]; + result(nil); +} + -(void)attachListeners:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSNumber* callbackDispatcherHandle = call.arguments[@"callbackDispatcherHandle"]; @@ -1122,6 +1126,20 @@ - (void)didUpdateToken:(NSString *)token { [self.backgroundChannel invokeMethod:@"" arguments:args]; } +- (void)didUpdateLocationPermissionStatus:(RadarLocationPermissionStatus *)status { + NSDictionary *dict = @{@"status": [status dictionaryValue]}; + NSLog(@"didUpdateLocationPermissionStatus"); + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + NSNumber* callbackHandle = [userDefaults objectForKey:@"locationPermissionStatus"]; + if (callbackHandle == 0) { + NSLog(@"callbackHandle is 0"); + return; + } + NSLog(@"calling background channel"); + NSArray* args = @[callbackHandle, dict]; + [self.backgroundChannel invokeMethod:@"" arguments:args]; +} + @end @implementation RadarStreamHandler diff --git a/ios/flutter_radar.podspec b/ios/flutter_radar.podspec index 63f63da..cd36ca3 100644 --- a/ios/flutter_radar.podspec +++ b/ios/flutter_radar.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'flutter_radar' - s.version = '3.9.1' + s.version = '3.10.0' s.summary = 'Flutter package for Radar, the leading geofencing and location tracking platform' s.description = 'Flutter package for Radar, the leading geofencing and location tracking platform' s.homepage = 'http://example.com' @@ -10,7 +10,7 @@ Pod::Spec.new do |s| s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' - s.dependency 'RadarSDK', '3.9.14' + s.dependency 'RadarSDK', '3.13.5' s.platform = :ios, '10.0' s.static_framework = true diff --git a/lib/flutter_radar.dart b/lib/flutter_radar.dart index c344a86..81326c5 100644 --- a/lib/flutter_radar.dart +++ b/lib/flutter_radar.dart @@ -163,10 +163,10 @@ class Radar { } static Future startTrackingVerified( - {bool? token, int? interval, bool? beacons}) async { + {int? interval, bool? beacons}) async { try { await _channel.invokeMethod('startTrackingVerified', - {'token': token, 'interval': interval, 'beacons': beacons}); + {'interval': interval, 'beacons': beacons}); } on PlatformException catch (e) { print(e); } @@ -180,6 +180,14 @@ class Radar { } } + static Future stopTrackingVerified() async { + try { + await _channel.invokeMethod('stopTrackingVerified'); + } on PlatformException catch (e) { + print(e); + } + } + static Future isTracking() async { return await _channel.invokeMethod('isTracking'); } @@ -272,14 +280,16 @@ class Radar { int? radius, List? tags, Map? metadata, - int? limit}) async { + int? limit, + bool? includeGeometry}) async { try { return await _channel.invokeMethod('searchGeofences', { 'near': near, 'radius': radius, 'limit': limit, 'tags': tags, - 'metadata': metadata + 'metadata': metadata, + 'includeGeometry': includeGeometry }); } on PlatformException catch (e) { print(e); @@ -467,24 +477,47 @@ class Radar { } } - static Future trackVerifiedToken({bool? beacons}) async { + static Future isUsingRemoteTrackingOptions() async { + return await _channel.invokeMethod('isUsingRemoteTrackingOptions'); + } + + static Future validateAddress(Map address) async { try { return await _channel - .invokeMethod('trackVerifiedToken', {'beacons': beacons}); + .invokeMethod('validateAddress', {'address': address}); } on PlatformException catch (e) { print(e); return {'error': e.code}; } } - static Future isUsingRemoteTrackingOptions() async { - return await _channel.invokeMethod('isUsingRemoteTrackingOptions'); + static Future requestForegroundLocationPermission() async { + try { + await _channel.invokeMethod('requestForegroundLocationPermission'); + } on PlatformException catch (e) { + print(e); + } } - static Future validateAddress(Map address) async { + static Future requestBackgroundLocationPermission() async { try { - return await _channel - .invokeMethod('validateAddress', {'address': address}); + await _channel.invokeMethod('requestBackgroundLocationPermission'); + } on PlatformException catch (e) { + print(e); + } + } + + static Future openAppSettings() async { + try { + await _channel.invokeMethod('openAppSettings'); + } on PlatformException catch (e) { + print(e); + } + } + + static Future getLocationPermissionStatus() async { + try { + return await _channel.invokeMethod('getLocationPermissionStatus'); } on PlatformException catch (e) { print(e); return {'error': e.code}; @@ -607,6 +640,25 @@ class Radar { } } + static onLocationPermissionStatus(Function(Map res) callback) async { + try { + final CallbackHandle handle = + PluginUtilities.getCallbackHandle(callback)!; + await _channel.invokeMethod( + 'on', {'listener': 'locationPermissionStatus', 'callbackHandle': handle.toRawHandle()}); + } on PlatformException catch (e) { + print(e); + } + } + + static offLocationPermissionStatus() async { + try { + await _channel.invokeMethod('off', {'listener': 'locationPermissionStatus'}); + } on PlatformException catch (e) { + print(e); + } + } + static Map presetContinuousIOS = { "desiredStoppedUpdateInterval": 30, "desiredMovingUpdateInterval": 30, diff --git a/pubspec.yaml b/pubspec.yaml index 482f01e..2b48bb1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_radar description: Flutter package for Radar, the leading geofencing and location tracking platform -version: 3.9.1 +version: 3.10.0 homepage: https://github.com/radarlabs/flutter-radar environment: From 3f200d94eadab97f5c0c3c4874a9b64c25fbb6a7 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 27 Jun 2024 15:00:06 -0400 Subject: [PATCH 02/16] draft android --- CHANGELOG.md | 2 +- android/build.gradle | 2 +- .../io/radar/flutter/RadarFlutterPlugin.java | 131 ++++++++++++------ example/android/app/build.gradle | 4 +- example/android/build.gradle | 2 +- example/lib/main.dart | 10 +- lib/flutter_radar.dart | 3 +- 7 files changed, 100 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93574c5..bc2bb82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # 3.10.0 - Bump iOS version from 3.9.14 to 3.13.5 -- Bump Android version from 3.9.0 to 3.13.2 +- Bump Android version from 3.9.8 to 3.13.2 # 3.9.1 diff --git a/android/build.gradle b/android/build.gradle index 700e6f2..5ceee60 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -34,7 +34,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.13.2' + implementation 'io.radar:sdk:3.13.1' implementation 'com.google.android.gms:play-services-location:21.0.1' implementation 'com.google.code.gson:gson:2.8.6' } diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index 9b64869..c9175c3 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -57,7 +57,9 @@ import io.radar.sdk.model.RadarUser; import io.radar.sdk.model.RadarTrip; import io.radar.sdk.model.RadarRouteMatrix; +import io.radar.sdk.model.RadarLocationPermissionStatus; import io.radar.sdk.RadarTrackingOptions.RadarTrackingOptionsForegroundService; +import io.radar.sdk.model.RadarVerifiedLocationToken; import io.flutter.embedding.engine.dart.DartExecutor; import io.flutter.embedding.engine.dart.DartExecutor.DartCallback; @@ -215,6 +217,9 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) case "startTrackingVerified": startTrackingVerified(call, result); break; + case "stopTrackingVerified": + stopTrackingVerified(call, result); + break; case "stopTracking": stopTracking(result); break; @@ -293,12 +298,21 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) case "trackVerified": trackVerified(call, result); break; - case "trackVerifiedToken": - trackVerifiedToken(call, result); - break; case "validateAddress": validateAddress(call, result); break; + case "requestForegroundLocationPermission": + requestForegroundLocationPermission(result); + break; + case "requestBackgroundLocationPermission": + requestBackgroundLocationPermission(result); + break; + case "openAppSettings": + openAppSettings(result); + break; + case "getLocationPermissionStatus": + getLocationPermissionStatus(result); + break; case "attachListeners": attachListeners(call, result); break; @@ -569,10 +583,14 @@ private void startTrackingCustom(MethodCall call, Result result) { } private void startTrackingVerified(MethodCall call, Result result) { - Boolean token = call.hasArgument("token") ? call.argument("token") : false; int interval = call.hasArgument("interval") && call.argument("interval") != null ? (int)call.argument("interval") : 1; Boolean beacons = call.hasArgument("beacons") ? call.argument("beacons") : false; - Radar.startTrackingVerified(token, interval, beacons); + Radar.startTrackingVerified(interval, beacons); + result.success(true); + } + + private void stopTrackingVerified(MethodCall call, Result result) { + Radar.stopTrackingVerified(); result.success(true); } @@ -848,11 +866,12 @@ public void run() { HashMap metadataMap = (HashMap)call.argument("metadata"); JSONObject metadata = jsonForMap(metadataMap); int limit = call.hasArgument("limit") ? (int)call.argument("limit") : 10; + boolean includeGeometry = call.hasArgument("includeGeometry") ? call.argument("includeGeometry") : false; if (near != null) { - Radar.searchGeofences(near, radius, tags, metadata, limit, callback); + Radar.searchGeofences(near, radius, tags, metadata, limit, includeGeometry, callback); } else { - Radar.searchGeofences(radius, tags, metadata, limit, callback); + Radar.searchGeofences(radius, tags, metadata, limit, includeGeometry, callback); } } @@ -942,7 +961,7 @@ public void run() { public void geocode(MethodCall call, final Result result) { String query = call.argument("query"); - Radar.geocode(query, new Radar.RadarGeocodeCallback() { + Radar.geocode(query, null, null, new Radar.RadarGeocodeCallback() { @Override public void onComplete(final Radar.RadarStatus status, final RadarAddress[] addresses) { runOnMainThread(new Runnable() { @@ -993,9 +1012,9 @@ public void run() { if (call.hasArgument("location")) { HashMap locationMap = (HashMap)call.argument("location"); Location location = locationForMap(locationMap); - Radar.reverseGeocode(location, callback); + Radar.reverseGeocode(location, null, callback); } else { - Radar.reverseGeocode(callback); + Radar.reverseGeocode(null ,callback); } } @@ -1182,22 +1201,16 @@ public void run() { public void trackVerified(MethodCall call, final Result result) { Boolean beacons = call.hasArgument("beacons") ? call.argument("beacons") : false; - Radar.RadarTrackCallback callback = new Radar.RadarTrackCallback() { + Radar.RadarTrackVerifiedCallback callback = new Radar.RadarTrackVerifiedCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final Location location, final RadarEvent[] events, final RadarUser user) { + public void onComplete(final Radar.RadarStatus status, final RadarVerifiedLocationToken token) { runOnMainThread(new Runnable() { @Override public void run() { try { JSONObject obj = new JSONObject(); obj.put("status", status.toString()); - if (location != null) { - obj.put("location", Radar.jsonForLocation(location)); - } - obj.put("events", RadarEvent.toJson(events)); - if ( user != null) { - obj.put("user", user.toJson()); - } + obj.put("token", token.toJson()); HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); result.success(map); @@ -1212,36 +1225,31 @@ public void run() { Radar.trackVerified(beacons, callback); } - public void trackVerifiedToken(MethodCall call, final Result result) { - Boolean beacons = call.hasArgument("beacons") ? call.argument("beacons") : false; + private void isUsingRemoteTrackingOptions(Result result) { + Boolean isRemoteTracking = Radar.isUsingRemoteTrackingOptions(); + result.success(isRemoteTracking); + } - Radar.RadarTrackTokenCallback callback = new Radar.RadarTrackTokenCallback() { - @Override - public void onComplete(final Radar.RadarStatus status, final String token) { - runOnMainThread(new Runnable() { - @Override - public void run() { - try { - JSONObject obj = new JSONObject(); - obj.put("status", status.toString()); - obj.put("token", token); + private void requestForegroundLocationPermission (Result result) { + Radar.requestForegroundLocationPermission(); + result.success(true); + } - HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); - result.success(map); - } catch (Exception e) { - result.error(e.toString(), e.getMessage(), e.getMessage()); - } - } - }); - } - }; + private void requestBackgroundLocationPermission (Result result) { + Radar.requestBackgroundLocationPermission(); + result.success(true); + } - Radar.trackVerifiedToken(beacons, callback); + private void openAppSettings (Result result) { + Radar.openAppSettings(); + result.success(true); } - private void isUsingRemoteTrackingOptions(Result result) { - Boolean isRemoteTracking = Radar.isUsingRemoteTrackingOptions(); - result.success(isRemoteTracking); + private void getLocationPermissionStatus (Result result) { + RadarLocationPermissionStatus status = Radar.getLocationPermissionStatus(); + JSONObject obj = status.toJson(); + HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); + result.success(map); } public void validateAddress(MethodCall call, final Result result) throws JSONException { @@ -1471,12 +1479,43 @@ public void run() { } } + @Override + public void onLocationPermissionStatusUpdated(Context context, RadarLocationPermissionStatus status) { + try { + SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); + long callbackHandle = sharedPrefs.getLong("locationPermissionStatus", 0L); + + if (callbackHandle == 0L) { + return; + } + + RadarFlutterPlugin.initializeBackgroundEngine(context); + + JSONObject obj = status.toJson(); + + HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); + synchronized(lock) { + final ArrayList args = new ArrayList(); + args.add(callbackHandle); + args.add(res); + runOnMainThread(new Runnable() { + @Override + public void run() { + sBackgroundChannel.invokeMethod("", args); + } + }); + } + } catch (Exception e) { + Log.e(TAG, e.toString()); + } + } + } public static class RadarFlutterVerifiedReceiver extends RadarVerifiedReceiver { @Override - public void onTokenUpdated(Context context, String token) { + public void onTokenUpdated(Context context, RadarVerifiedLocationToken token) { try { SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); long callbackHandle = sharedPrefs.getLong("token", 0L); @@ -1488,7 +1527,7 @@ public void onTokenUpdated(Context context, String token) { RadarFlutterPlugin.initializeBackgroundEngine(context); JSONObject obj = new JSONObject(); - obj.put("token", token); + obj.put("token", token.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); synchronized(lock) { diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 750378f..bcfe3b3 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -34,7 +34,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "io.radar.example" - minSdkVersion 16 + minSdkVersion flutter.minSdkVersion targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -49,7 +49,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.13.2' + implementation 'io.radar:sdk:3.13.1' implementation "com.google.android.play:integrity:1.2.0" } } diff --git a/example/android/build.gradle b/example/android/build.gradle index 21d7749..9881192 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -24,6 +24,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/example/lib/main.dart b/example/lib/main.dart index dcd0298..1c7f274 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -213,6 +213,14 @@ class _MyAppState extends State with WidgetsBindingObserver { }, child: Text('openAppSettings'), ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.getLocationPermissionStatus(); + print("status: $resp"); + }, + child: Text('getLocationPermissionStatus'), + ), ElevatedButton( style: raisedButtonStyle, onPressed: () async { @@ -372,7 +380,7 @@ class _MyAppState extends State with WidgetsBindingObserver { ElevatedButton( style: raisedButtonStyle, onPressed: () { - Radar.startTrackingVerified(); + Radar.startTrackingVerified(30, false); }, child: Text('startTrackingVerified()'), ), diff --git a/lib/flutter_radar.dart b/lib/flutter_radar.dart index 81326c5..e33c7aa 100644 --- a/lib/flutter_radar.dart +++ b/lib/flutter_radar.dart @@ -162,8 +162,7 @@ class Radar { } } - static Future startTrackingVerified( - {int? interval, bool? beacons}) async { + static Future startTrackingVerified(int interval, bool beacons) async { try { await _channel.invokeMethod('startTrackingVerified', {'interval': interval, 'beacons': beacons}); From f34746cef6339a631cc956cba19a27c8eabd68f9 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 16 Jul 2024 11:41:08 -0400 Subject: [PATCH 03/16] remove location permissions stuff --- android/build.gradle | 2 +- .../io/radar/flutter/RadarFlutterPlugin.java | 70 +----------------- example/android/app/build.gradle | 2 +- example/lib/main.dart | 71 ++++--------------- ios/Classes/RadarFlutterPlugin.m | 42 ----------- ios/flutter_radar.podspec | 2 +- 6 files changed, 19 insertions(+), 170 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 5ceee60..d305e1a 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -34,7 +34,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.13.1' + implementation 'io.radar:sdk:3.14.0' implementation 'com.google.android.gms:play-services-location:21.0.1' implementation 'com.google.code.gson:gson:2.8.6' } diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index c9175c3..f515b29 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -57,7 +57,6 @@ import io.radar.sdk.model.RadarUser; import io.radar.sdk.model.RadarTrip; import io.radar.sdk.model.RadarRouteMatrix; -import io.radar.sdk.model.RadarLocationPermissionStatus; import io.radar.sdk.RadarTrackingOptions.RadarTrackingOptionsForegroundService; import io.radar.sdk.model.RadarVerifiedLocationToken; @@ -106,7 +105,7 @@ private static void initializeBackgroundEngine(Context context) { } } } - + @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { Radar.setReceiver(new RadarFlutterReceiver()); @@ -301,18 +300,6 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) case "validateAddress": validateAddress(call, result); break; - case "requestForegroundLocationPermission": - requestForegroundLocationPermission(result); - break; - case "requestBackgroundLocationPermission": - requestBackgroundLocationPermission(result); - break; - case "openAppSettings": - openAppSettings(result); - break; - case "getLocationPermissionStatus": - getLocationPermissionStatus(result); - break; case "attachListeners": attachListeners(call, result); break; @@ -1230,28 +1217,6 @@ private void isUsingRemoteTrackingOptions(Result result) { result.success(isRemoteTracking); } - private void requestForegroundLocationPermission (Result result) { - Radar.requestForegroundLocationPermission(); - result.success(true); - } - - private void requestBackgroundLocationPermission (Result result) { - Radar.requestBackgroundLocationPermission(); - result.success(true); - } - - private void openAppSettings (Result result) { - Radar.openAppSettings(); - result.success(true); - } - - private void getLocationPermissionStatus (Result result) { - RadarLocationPermissionStatus status = Radar.getLocationPermissionStatus(); - JSONObject obj = status.toJson(); - HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); - result.success(map); - } - public void validateAddress(MethodCall call, final Result result) throws JSONException { Radar.RadarValidateAddressCallback callback = new Radar.RadarValidateAddressCallback() { @Override @@ -1348,39 +1313,6 @@ public void run() { } } - @Override - public void onLocationUpdated(Context context, Location location, RadarUser user) { - try { - SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("location", 0L); - - if (callbackHandle == 0L) { - Log.e(TAG, "callback handle is empty"); - return; - } - - RadarFlutterPlugin.initializeBackgroundEngine(context); - - JSONObject obj = new JSONObject(); - obj.put("location", Radar.jsonForLocation(location)); - obj.put("user", user.toJson()); - - HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { - final ArrayList args = new ArrayList(); - args.add(callbackHandle); - args.add(res); - runOnMainThread(new Runnable() { - @Override - public void run() { - sBackgroundChannel.invokeMethod("", args); - } - }); - } - } catch (Exception e) { - Log.e(TAG, e.toString()); - } - } public void onClientLocationUpdated(Context context, Location location, boolean stopped, Radar.RadarLocationSource source) { try { diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index bcfe3b3..59d7f02 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -49,7 +49,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.13.1' + implementation 'io.radar:sdk:3.14.0' implementation "com.google.android.play:integrity:1.2.0" } } diff --git a/example/lib/main.dart b/example/lib/main.dart index 1c7f274..61bb9b7 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -67,11 +67,6 @@ class _MyAppState extends State with WidgetsBindingObserver { print('📍📍 onToken: $res'); } - @pragma('vm:entry-point') - static void onLocationPermissionStatus(Map res) { - print('📍📍 onLocationPermissionStatus: $res'); - } - Future initRadar() async { Radar.initialize('prj_test_pk_0000000000000000000000000000000000000000'); Radar.setUserId('flutter'); @@ -88,25 +83,21 @@ class _MyAppState extends State with WidgetsBindingObserver { Radar.onEvents(onEvents); Radar.onLog(onLog); Radar.onToken(onToken); - Radar.onLocationPermissionStatus(onLocationPermissionStatus); - - //await Radar.requestPermissions(false); - - //await Radar.requestPermissions(true); - // var permissionStatus = await Radar.getPermissionsStatus(); - // if (permissionStatus != "DENIED") { - // var b = await Radar.startTrackingCustom({ - // ... Radar.presetResponsive, - // "showBlueBar": true, - // }); - // //Radar.startTracking('continuous'); - - // var c = await Radar.getTrackingOptions(); - // print("Tracking options $c"); - // } - var permissionStatus = await Radar.getLocationPermissionStatus(); - print(permissionStatus); - //await Radar.requestForegroundLocationPermission(); + + await Radar.requestPermissions(false); + + await Radar.requestPermissions(true); + var permissionStatus = await Radar.getPermissionsStatus(); + if (permissionStatus != "DENIED") { + var b = await Radar.startTrackingCustom({ + ... Radar.presetResponsive, + "showBlueBar": true, + }); + //Radar.startTracking('continuous'); + + var c = await Radar.getTrackingOptions(); + print("Tracking options $c"); + } } @override @@ -188,38 +179,6 @@ class _MyAppState extends State with WidgetsBindingObserver { print("completeTrip: $resp"); }, child: Text('completeTrip'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - Radar.requestForegroundLocationPermission(); - - }, - child: Text('get foreground'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - Radar.requestBackgroundLocationPermission(); - - }, - child: Text('get background'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - Radar.openAppSettings(); - - }, - child: Text('openAppSettings'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.getLocationPermissionStatus(); - print("status: $resp"); - }, - child: Text('getLocationPermissionStatus'), ), ElevatedButton( style: raisedButtonStyle, diff --git a/ios/Classes/RadarFlutterPlugin.m b/ios/Classes/RadarFlutterPlugin.m index 1b0e4bd..16dfa22 100644 --- a/ios/Classes/RadarFlutterPlugin.m +++ b/ios/Classes/RadarFlutterPlugin.m @@ -130,14 +130,6 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self isUsingRemoteTrackingOptions:call withResult:result]; } else if ([@"validateAddress" isEqualToString:call.method]) { [self validateAddress:call withResult:result]; - } else if ([@"getLocationPermissionStatus" isEqualToString:call.method]) { - [self getLocationPermissionStatus:result]; - } else if ([@"requestForegroundLocationPermission" isEqualToString:call.method]) { - [self requestForegroundLocationPermission:result]; - } else if ([@"requestBackgroundLocationPermission" isEqualToString:call.method]) { - [self requestBackgroundLocationPermission:result]; - } else if ([@"openAppSettings" isEqualToString:call.method]) { - [self openAppSettings:result]; } else if ([@"attachListeners" isEqualToString:call.method]) { [self attachListeners:call withResult:result]; } else if ([@"detachListeners" isEqualToString:call.method]) { @@ -999,26 +991,6 @@ - (void)validateAddress:(FlutterMethodCall *)call withResult:(FlutterResult)resu [Radar validateAddress:address completionHandler:completionHandler]; } --(void)requestForegroundLocationPermission:(FlutterResult)result { - [Radar requestForegroundLocationPermission]; - result(nil); -} - --(void)requestBackgroundLocationPermission:(FlutterResult)result { - [Radar requestBackgroundLocationPermission]; - result(nil); -} - --(void)getLocationPermissionStatus:(FlutterResult)result { - RadarLocationPermissionStatus *status = [Radar getLocationPermissionStatus]; - result([status dictionaryValue]); -} - --(void)openAppSettings:(FlutterResult)result { - [Radar openAppSettings]; - result(nil); -} - -(void)attachListeners:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSNumber* callbackDispatcherHandle = call.arguments[@"callbackDispatcherHandle"]; @@ -1126,20 +1098,6 @@ - (void)didUpdateToken:(NSString *)token { [self.backgroundChannel invokeMethod:@"" arguments:args]; } -- (void)didUpdateLocationPermissionStatus:(RadarLocationPermissionStatus *)status { - NSDictionary *dict = @{@"status": [status dictionaryValue]}; - NSLog(@"didUpdateLocationPermissionStatus"); - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSNumber* callbackHandle = [userDefaults objectForKey:@"locationPermissionStatus"]; - if (callbackHandle == 0) { - NSLog(@"callbackHandle is 0"); - return; - } - NSLog(@"calling background channel"); - NSArray* args = @[callbackHandle, dict]; - [self.backgroundChannel invokeMethod:@"" arguments:args]; -} - @end @implementation RadarStreamHandler diff --git a/ios/flutter_radar.podspec b/ios/flutter_radar.podspec index cd36ca3..f9173c3 100644 --- a/ios/flutter_radar.podspec +++ b/ios/flutter_radar.podspec @@ -10,7 +10,7 @@ Pod::Spec.new do |s| s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' - s.dependency 'RadarSDK', '3.13.5' + s.dependency 'RadarSDK', '3.14.0' s.platform = :ios, '10.0' s.static_framework = true From 87d68d1eb785127fa940fe018bf496c85c7cc888 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 16 Jul 2024 12:08:14 -0400 Subject: [PATCH 04/16] bump version --- android/build.gradle | 2 +- .../io/radar/flutter/RadarFlutterPlugin.java | 44 ++++++++++--------- example/android/app/build.gradle | 2 +- ios/flutter_radar.podspec | 2 +- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index d305e1a..77e9a78 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -34,7 +34,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.14.0' + implementation 'io.radar:sdk:3.15.0' implementation 'com.google.android.gms:play-services-location:21.0.1' implementation 'com.google.code.gson:gson:2.8.6' } diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index f515b29..6cafeb1 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -1312,23 +1312,23 @@ public void run() { Log.e(TAG, e.toString()); } } - - public void onClientLocationUpdated(Context context, Location location, boolean stopped, Radar.RadarLocationSource source) { + @Override + public void onLocationUpdated(Context context, Location location, RadarUser user) { try { SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("clientLocation", 0L); + long callbackHandle = sharedPrefs.getLong("location", 0L); if (callbackHandle == 0L) { + Log.e(TAG, "callback handle is empty"); return; } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("location", Radar.jsonForLocation(location)); - obj.put("stopped", stopped); - obj.put("source", source.toString()); + obj.put("user", user.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); synchronized(lock) { @@ -1347,11 +1347,11 @@ public void run() { } } - @Override - public void onError(Context context, Radar.RadarStatus status) { + + public void onClientLocationUpdated(Context context, Location location, boolean stopped, Radar.RadarLocationSource source) { try { SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("error", 0L); + long callbackHandle = sharedPrefs.getLong("clientLocation", 0L); if (callbackHandle == 0L) { return; @@ -1360,7 +1360,9 @@ public void onError(Context context, Radar.RadarStatus status) { RadarFlutterPlugin.initializeBackgroundEngine(context); JSONObject obj = new JSONObject(); - obj.put("status", status.toString()); + obj.put("location", Radar.jsonForLocation(location)); + obj.put("stopped", stopped); + obj.put("source", source.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); synchronized(lock) { @@ -1380,10 +1382,10 @@ public void run() { } @Override - public void onLog(Context context, String message) { + public void onError(Context context, Radar.RadarStatus status) { try { SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("log", 0L); + long callbackHandle = sharedPrefs.getLong("error", 0L); if (callbackHandle == 0L) { return; @@ -1392,7 +1394,7 @@ public void onLog(Context context, String message) { RadarFlutterPlugin.initializeBackgroundEngine(context); JSONObject obj = new JSONObject(); - obj.put("message", message); + obj.put("status", status.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); synchronized(lock) { @@ -1410,12 +1412,12 @@ public void run() { Log.e(TAG, e.toString()); } } - - @Override - public void onLocationPermissionStatusUpdated(Context context, RadarLocationPermissionStatus status) { + + @Override + public void onLog(Context context, String message) { try { SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("locationPermissionStatus", 0L); + long callbackHandle = sharedPrefs.getLong("log", 0L); if (callbackHandle == 0L) { return; @@ -1423,8 +1425,9 @@ public void onLocationPermissionStatusUpdated(Context context, RadarLocationPerm RadarFlutterPlugin.initializeBackgroundEngine(context); - JSONObject obj = status.toJson(); - + JSONObject obj = new JSONObject(); + obj.put("message", message); + HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); synchronized(lock) { final ArrayList args = new ArrayList(); @@ -1441,9 +1444,8 @@ public void run() { Log.e(TAG, e.toString()); } } - } - + public static class RadarFlutterVerifiedReceiver extends RadarVerifiedReceiver { @Override diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 59d7f02..aa55010 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -49,7 +49,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.14.0' + implementation 'io.radar:sdk:3.15.0' implementation "com.google.android.play:integrity:1.2.0" } } diff --git a/ios/flutter_radar.podspec b/ios/flutter_radar.podspec index f9173c3..9749451 100644 --- a/ios/flutter_radar.podspec +++ b/ios/flutter_radar.podspec @@ -10,7 +10,7 @@ Pod::Spec.new do |s| s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' - s.dependency 'RadarSDK', '3.14.0' + s.dependency 'RadarSDK', '3.15.0' s.platform = :ios, '10.0' s.static_framework = true From e8ce64e45f03c6fcddea41a2817f433c7dde1d6b Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 16 Jul 2024 12:17:07 -0400 Subject: [PATCH 05/16] remove xplatform listeners --- lib/flutter_radar.dart | 43 ------------------------------------------ 1 file changed, 43 deletions(-) diff --git a/lib/flutter_radar.dart b/lib/flutter_radar.dart index e33c7aa..77c43f0 100644 --- a/lib/flutter_radar.dart +++ b/lib/flutter_radar.dart @@ -498,30 +498,6 @@ class Radar { } } - static Future requestBackgroundLocationPermission() async { - try { - await _channel.invokeMethod('requestBackgroundLocationPermission'); - } on PlatformException catch (e) { - print(e); - } - } - - static Future openAppSettings() async { - try { - await _channel.invokeMethod('openAppSettings'); - } on PlatformException catch (e) { - print(e); - } - } - - static Future getLocationPermissionStatus() async { - try { - return await _channel.invokeMethod('getLocationPermissionStatus'); - } on PlatformException catch (e) { - print(e); - return {'error': e.code}; - } - } static onLocation(Function(Map res) callback) async { try { @@ -639,25 +615,6 @@ class Radar { } } - static onLocationPermissionStatus(Function(Map res) callback) async { - try { - final CallbackHandle handle = - PluginUtilities.getCallbackHandle(callback)!; - await _channel.invokeMethod( - 'on', {'listener': 'locationPermissionStatus', 'callbackHandle': handle.toRawHandle()}); - } on PlatformException catch (e) { - print(e); - } - } - - static offLocationPermissionStatus() async { - try { - await _channel.invokeMethod('off', {'listener': 'locationPermissionStatus'}); - } on PlatformException catch (e) { - print(e); - } - } - static Map presetContinuousIOS = { "desiredStoppedUpdateInterval": 30, "desiredMovingUpdateInterval": 30, From b36f7123b3d99b11a3561343ef22c5a7b939d857 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 16 Jul 2024 13:02:15 -0400 Subject: [PATCH 06/16] add to example and fix ios delegate --- example/lib/main.dart | 32 ++++++++++++++++++++++++++++++-- ios/Classes/RadarFlutterPlugin.m | 4 ++-- lib/flutter_radar.dart | 2 +- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 61bb9b7..8dd34d8 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -249,7 +249,35 @@ class _MyAppState extends State with WidgetsBindingObserver { ); print("searchPlaces: $resp"); }, - child: Text('searchPlaces'), + child: Text('searchPlaces()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.searchGeofences( + near: { + 'latitude': 40.783826, + 'longitude': -73.975363, + }, + radius: 1000, + limit: 10, + includeGeometry: true, + tags: List.empty(), + metadata: {}, + ); + print("searchGeofences: $resp"); + }, + child: Text('searchGeofences()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.geocode( + '20 jay st brooklyn', + ); + print("geocode: $resp"); + }, + child: Text('geocode()'), ), ElevatedButton( style: raisedButtonStyle, @@ -383,7 +411,7 @@ class _MyAppState extends State with WidgetsBindingObserver { Map? resp = await Radar.trackVerified(); print("trackVerified: $resp"); }, - child: Text('trackVerified'), + child: Text('trackVerified()'), ), ElevatedButton( diff --git a/ios/Classes/RadarFlutterPlugin.m b/ios/Classes/RadarFlutterPlugin.m index 16dfa22..33785e3 100644 --- a/ios/Classes/RadarFlutterPlugin.m +++ b/ios/Classes/RadarFlutterPlugin.m @@ -1087,8 +1087,8 @@ - (void)didLogMessage:(NSString *)message { [self.backgroundChannel invokeMethod:@"" arguments:args]; } -- (void)didUpdateToken:(NSString *)token { - NSDictionary *dict = @{@"token": token}; +- (void)didUpdateToken:(RadarVerifiedLocationToken *)token { + NSDictionary *dict = [token dictionaryValue]; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSNumber* callbackHandle = [userDefaults objectForKey:@"token"]; if (callbackHandle == 0) { diff --git a/lib/flutter_radar.dart b/lib/flutter_radar.dart index 77c43f0..c6033fa 100644 --- a/lib/flutter_radar.dart +++ b/lib/flutter_radar.dart @@ -469,7 +469,7 @@ class Radar { static Future trackVerified({bool? beacons}) async { try { - return await _channel.invokeMethod('trackVerified', {'beacons': beacons}); + return await _channel.invokeMethod('trackVerified', {'beacons': beacons != null ? beacons : false}); } on PlatformException catch (e) { print(e); return {'error': e.code}; From 21e3ed404829156af9d5dfaaa8b8936f1628b5ee Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 16 Jul 2024 13:14:57 -0400 Subject: [PATCH 07/16] update change log --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc2bb82..c3a6f19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # 3.10.0 -- Bump iOS version from 3.9.14 to 3.13.5 -- Bump Android version from 3.9.8 to 3.13.2 +- Bump iOS version from 3.9.14 to 3.15.0 +- Bump Android version from 3.9.8 to 3.15.0 # 3.9.1 From d399bc523db492093e93164752058efbaf5f6c26 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 16 Jul 2024 15:04:09 -0400 Subject: [PATCH 08/16] update reverse geocoding and add reverse geocoding to example --- .../io/radar/flutter/RadarFlutterPlugin.java | 252 ++++++++++-------- example/lib/main.dart | 8 + ios/Classes/RadarFlutterPlugin.m | 29 +- lib/flutter_radar.dart | 192 ++++++------- 4 files changed, 269 insertions(+), 212 deletions(-) diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index 6cafeb1..dcdaa3e 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -67,7 +67,8 @@ import io.flutter.view.FlutterRunArguments; import io.flutter.view.FlutterCallbackInformation; -public class RadarFlutterPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware, RequestPermissionsResultListener { +public class RadarFlutterPlugin + implements FlutterPlugin, MethodCallHandler, ActivityAware, RequestPermissionsResultListener { private static FlutterEngine sBackgroundFlutterEngine; @@ -82,9 +83,9 @@ public class RadarFlutterPlugin implements FlutterPlugin, MethodCallHandler, Act private static final int PERMISSIONS_REQUEST_CODE = 20160525; private Result mPermissionsRequestResult; - + private static void initializeBackgroundEngine(Context context) { - synchronized(lock) { + synchronized (lock) { if (sBackgroundFlutterEngine == null) { FlutterMain.startInitialization(context.getApplicationContext()); FlutterMain.ensureInitializationComplete(context.getApplicationContext(), null); @@ -96,12 +97,15 @@ private static void initializeBackgroundEngine(Context context) { return; } - FlutterCallbackInformation callbackInfo = FlutterCallbackInformation.lookupCallbackInformation(callbackDispatcherHandle); + FlutterCallbackInformation callbackInfo = FlutterCallbackInformation + .lookupCallbackInformation(callbackDispatcherHandle); sBackgroundFlutterEngine = new FlutterEngine(context.getApplicationContext()); - DartCallback callback = new DartCallback(context.getAssets(), FlutterMain.findAppBundlePath(context), callbackInfo); + DartCallback callback = new DartCallback(context.getAssets(), FlutterMain.findAppBundlePath(context), + callbackInfo); sBackgroundFlutterEngine.getDartExecutor().executeDartCallback(callback); - sBackgroundChannel = new MethodChannel(sBackgroundFlutterEngine.getDartExecutor().getBinaryMessenger(), "flutter_radar_background"); + sBackgroundChannel = new MethodChannel(sBackgroundFlutterEngine.getDartExecutor().getBinaryMessenger(), + "flutter_radar_background"); } } } @@ -260,7 +264,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) break; case "autocomplete": autocomplete(call, result); - break; + break; case "forwardGeocode": geocode(call, result); break; @@ -332,7 +336,7 @@ private void initialize(MethodCall call, Result result) { } private void setNotificationOptions(MethodCall call, Result result) { - HashMap notificationOptionsMap = (HashMap)call.arguments; + HashMap notificationOptionsMap = (HashMap) call.arguments; JSONObject notificationOptionsJson = new JSONObject(notificationOptionsMap); RadarNotificationOptions options = RadarNotificationOptions.fromJson(notificationOptionsJson); Radar.setNotificationOptions(options); @@ -340,9 +344,10 @@ private void setNotificationOptions(MethodCall call, Result result) { } private void setForegroundServiceOptions(MethodCall call, Result result) { - HashMap foregroundServiceOptionsMap = (HashMap)call.arguments; + HashMap foregroundServiceOptionsMap = (HashMap) call.arguments; JSONObject foregroundServiceOptionsJson = new JSONObject(foregroundServiceOptionsMap); - RadarTrackingOptionsForegroundService options = RadarTrackingOptionsForegroundService.fromJson(foregroundServiceOptionsJson); + RadarTrackingOptionsForegroundService options = RadarTrackingOptionsForegroundService + .fromJson(foregroundServiceOptionsJson); Radar.setForegroundServiceOptions(options); result.success(true); } @@ -365,20 +370,21 @@ private void setLogLevel(MethodCall call, Result result) { result.success(true); } - private void getPermissionStatus(Result result) { String status = "NOT_DETERMINED"; - + if (mActivity == null || result == null) { result.success(status); return; } - boolean foreground = ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; + boolean foreground = ActivityCompat.checkSelfPermission(mActivity, + Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; if (Build.VERSION.SDK_INT >= 29) { if (foreground) { - boolean background = ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED; + boolean background = ActivityCompat.checkSelfPermission(mActivity, + Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED; status = background ? "GRANTED_BACKGROUND" : "GRANTED_FOREGROUND"; } else { status = "DENIED"; @@ -396,9 +402,15 @@ private void requestPermissions(MethodCall call, Result result) { if (mActivity != null) { if (Build.VERSION.SDK_INT >= 23) { if (background && Build.VERSION.SDK_INT >= 29) { - ActivityCompat.requestPermissions(mActivity, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION }, PERMISSIONS_REQUEST_CODE); + ActivityCompat.requestPermissions(mActivity, + new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_BACKGROUND_LOCATION }, + PERMISSIONS_REQUEST_CODE); } else { - ActivityCompat.requestPermissions(mActivity, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }, PERMISSIONS_REQUEST_CODE); + ActivityCompat.requestPermissions(mActivity, new String[] { + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }, + PERMISSIONS_REQUEST_CODE); } } } @@ -427,7 +439,7 @@ private void getDescription(Result result) { } private void setMetadata(MethodCall call, Result result) { - HashMap metadataMap = (HashMap)call.arguments; + HashMap metadataMap = (HashMap) call.arguments; JSONObject metadata = new JSONObject(metadataMap); Radar.setMetadata(metadata); result.success(true); @@ -437,7 +449,7 @@ private void getMetadata(Result result) { JSONObject metadata = Radar.getMetadata(); HashMap metadataMap = null; if (metadata != null) { - metadataMap = new Gson().fromJson(metadata.toString(), HashMap.class); + metadataMap = new Gson().fromJson(metadata.toString(), HashMap.class); } result.success(metadataMap); } @@ -490,7 +502,8 @@ public void run() { private void trackOnce(MethodCall call, final Result result) { Radar.RadarTrackCallback callback = new Radar.RadarTrackCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final Location location, final RadarEvent[] events, final RadarUser user) { + public void onComplete(final Radar.RadarStatus status, final Location location, final RadarEvent[] events, + final RadarUser user) { runOnMainThread(new Runnable() { @Override public void run() { @@ -506,7 +519,7 @@ public void run() { if (user != null) { obj.put("user", user.toJson()); } - + HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); result.success(map); } catch (Exception e) { @@ -516,17 +529,17 @@ public void run() { }); } }; - + if (call.hasArgument("location") && call.argument("location") != null) { - HashMap locationMap = (HashMap)call.argument("location"); + HashMap locationMap = (HashMap) call.argument("location"); Location location = locationForMap(locationMap); Radar.trackOnce(location, callback); } else { RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.MEDIUM; boolean beaconsTrackingOption = false; - + if (call.hasArgument("desiredAccuracy") && call.argument("desiredAccuracy") != null) { - String desiredAccuracy = ((String)call.argument("desiredAccuracy")).toLowerCase(); + String desiredAccuracy = ((String) call.argument("desiredAccuracy")).toLowerCase(); if (desiredAccuracy.equals("none")) { accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.NONE; } else if (desiredAccuracy.equals("low")) { @@ -540,10 +553,10 @@ public void run() { if (call.hasArgument("beacons") && call.argument("beacons") != null) { beaconsTrackingOption = call.argument("beacons"); } - + Radar.trackOnce(accuracyLevel, beaconsTrackingOption, callback); } - } + } private void startTracking(MethodCall call, Result result) { String preset = call.argument("preset"); @@ -562,7 +575,7 @@ private void startTracking(MethodCall call, Result result) { } private void startTrackingCustom(MethodCall call, Result result) { - HashMap optionsMap = (HashMap)call.arguments; + HashMap optionsMap = (HashMap) call.arguments; JSONObject optionsJson = new JSONObject(optionsMap); RadarTrackingOptions options = RadarTrackingOptions.fromJson(optionsJson); Radar.startTracking(options); @@ -570,7 +583,9 @@ private void startTrackingCustom(MethodCall call, Result result) { } private void startTrackingVerified(MethodCall call, Result result) { - int interval = call.hasArgument("interval") && call.argument("interval") != null ? (int)call.argument("interval") : 1; + int interval = call.hasArgument("interval") && call.argument("interval") != null + ? (int) call.argument("interval") + : 1; Boolean beacons = call.hasArgument("beacons") ? call.argument("beacons") : false; Radar.startTrackingVerified(interval, beacons); result.success(true); @@ -582,9 +597,9 @@ private void stopTrackingVerified(MethodCall call, Result result) { } public void mockTracking(MethodCall call, final Result result) { - HashMap originMap = (HashMap)call.argument("origin"); + HashMap originMap = (HashMap) call.argument("origin"); Location origin = locationForMap(originMap); - HashMap destinationMap = (HashMap)call.argument("destination"); + HashMap destinationMap = (HashMap) call.argument("destination"); Location destination = locationForMap(destinationMap); String modeStr = call.argument("mode"); Radar.RadarRouteMode mode = Radar.RadarRouteMode.CAR; @@ -595,13 +610,13 @@ public void mockTracking(MethodCall call, final Result result) { } else if (modeStr.equals("CAR") || modeStr.equals("car")) { mode = Radar.RadarRouteMode.CAR; } - int steps = call.hasArgument("steps") ? (int)call.argument("steps") : 10; - int interval = call.hasArgument("interval") ? (int)call.argument("interval") : 1; + int steps = call.hasArgument("steps") ? (int) call.argument("steps") : 10; + int interval = call.hasArgument("interval") ? (int) call.argument("interval") : 1; Radar.mockTracking(origin, destination, mode, steps, interval, new Radar.RadarTrackCallback() { @Override public void onComplete(Radar.RadarStatus status, Location location, RadarEvent[] events, RadarUser user) { - + } }); } @@ -616,21 +631,21 @@ private void isTracking(Result result) { result.success(isTracking); } - private void getTrackingOptions(Result result) throws JSONException { - RadarTrackingOptions options = Radar.getTrackingOptions(); + private void getTrackingOptions(Result result) throws JSONException { + RadarTrackingOptions options = Radar.getTrackingOptions(); JSONObject optionsJson = options.toJson(); HashMap optionsMap = null; if (optionsJson != null) { - optionsMap = new Gson().fromJson(optionsJson.toString(), HashMap.class); + optionsMap = new Gson().fromJson(optionsJson.toString(), HashMap.class); } result.success(optionsMap); } public void startTrip(MethodCall call, Result result) throws JSONException { - HashMap tripOptionsMap = (HashMap)call.argument("tripOptions"); + HashMap tripOptionsMap = (HashMap) call.argument("tripOptions"); JSONObject tripOptionsJson = jsonForMap(tripOptionsMap); RadarTripOptions tripOptions = RadarTripOptions.fromJson(tripOptionsJson); - HashMap trackingOptionsMap = (HashMap)call.argument("trackingOptions"); + HashMap trackingOptionsMap = (HashMap) call.argument("trackingOptions"); JSONObject trackingOptionsJson = jsonForMap(trackingOptionsMap); RadarTrackingOptions trackingOptions = null; if (trackingOptionsJson != null) { @@ -639,8 +654,8 @@ public void startTrip(MethodCall call, Result result) throws JSONException { Radar.startTrip(tripOptions, trackingOptions, new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -666,7 +681,7 @@ public void run() { } public void updateTrip(MethodCall call, Result result) throws JSONException { - HashMap tripOptionsMap = (HashMap)call.argument("tripOptions"); + HashMap tripOptionsMap = (HashMap) call.argument("tripOptions"); JSONObject tripOptionsJson = jsonForMap(tripOptionsMap); RadarTripOptions tripOptions = RadarTripOptions.fromJson(tripOptionsJson); String statusStr = call.argument("status"); @@ -683,12 +698,12 @@ public void updateTrip(MethodCall call, Result result) throws JSONException { } else if (statusStr.equals("canceled")) { status = RadarTrip.RadarTripStatus.CANCELED; } - + Radar.updateTrip(tripOptions, status, new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -715,7 +730,7 @@ public void run() { public void getTripOptions(Result result) { RadarTripOptions tripOptions = Radar.getTripOptions(); - HashMap map = new Gson().fromJson(tripOptions.toJson().toString(), HashMap.class); + HashMap map = new Gson().fromJson(tripOptions.toJson().toString(), HashMap.class); result.success(map); } @@ -723,8 +738,8 @@ public void completeTrip(Result result) { Radar.completeTrip(new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -753,8 +768,8 @@ public void cancelTrip(Result result) { Radar.cancelTrip(new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -782,7 +797,8 @@ public void run() { public void getContext(MethodCall call, final Result result) { Radar.RadarContextCallback callback = new Radar.RadarContextCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final Location location, final RadarContext context) { + public void onComplete(final Radar.RadarStatus status, final Location location, + final RadarContext context) { runOnMainThread(new Runnable() { @Override public void run() { @@ -807,7 +823,7 @@ public void run() { }; if (call.hasArgument("location")) { - HashMap locationMap = (HashMap)call.argument("location"); + HashMap locationMap = (HashMap) call.argument("location"); Location location = locationForMap(locationMap); Radar.getContext(location, callback); } else { @@ -818,7 +834,8 @@ public void run() { private void searchGeofences(MethodCall call, final Result result) throws JSONException { Radar.RadarSearchGeofencesCallback callback = new Radar.RadarSearchGeofencesCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final Location location, final RadarGeofence[] geofences) { + public void onComplete(final Radar.RadarStatus status, final Location location, + final RadarGeofence[] geofences) { runOnMainThread(new Runnable() { @Override public void run() { @@ -844,15 +861,15 @@ public void run() { Location near = null; if (call.hasArgument("near")) { - HashMap nearMap = (HashMap)call.argument("near"); + HashMap nearMap = (HashMap) call.argument("near"); near = locationForMap(nearMap); } - int radius = call.hasArgument("radius") ? (int)call.argument("radius") : 1000; - ArrayList tagsList = (ArrayList)call.argument("tags"); - String[] tags = (String[])tagsList.toArray(new String[0]); - HashMap metadataMap = (HashMap)call.argument("metadata"); + int radius = call.hasArgument("radius") ? (int) call.argument("radius") : 1000; + ArrayList tagsList = (ArrayList) call.argument("tags"); + String[] tags = (String[]) tagsList.toArray(new String[0]); + HashMap metadataMap = (HashMap) call.argument("metadata"); JSONObject metadata = jsonForMap(metadataMap); - int limit = call.hasArgument("limit") ? (int)call.argument("limit") : 10; + int limit = call.hasArgument("limit") ? (int) call.argument("limit") : 10; boolean includeGeometry = call.hasArgument("includeGeometry") ? call.argument("includeGeometry") : false; if (near != null) { @@ -891,18 +908,18 @@ public void run() { Location near = null; if (call.hasArgument("near")) { - HashMap nearMap = (HashMap)call.argument("near"); + HashMap nearMap = (HashMap) call.argument("near"); near = locationForMap(nearMap); } - int radius = call.hasArgument("radius") ? (int)call.argument("radius") : 1000; - ArrayList chainsList = (ArrayList)call.argument("chains"); - String[] chains = (String[])chainsList.toArray(new String[0]); - Map chainMetadata = (Map)call.argument("chainMetadata"); - ArrayList categoriesList = (ArrayList)call.argument("categories"); - String[] categories = categoriesList != null ? (String[])categoriesList.toArray(new String[0]) : new String[0]; - ArrayList groupsList = (ArrayList)call.argument("groups"); - String[] groups = groupsList != null ? (String[])groupsList.toArray(new String[0]) : new String[0]; - int limit = call.hasArgument("limit") ? (int)call.argument("limit") : 10; + int radius = call.hasArgument("radius") ? (int) call.argument("radius") : 1000; + ArrayList chainsList = (ArrayList) call.argument("chains"); + String[] chains = (String[]) chainsList.toArray(new String[0]); + Map chainMetadata = (Map) call.argument("chainMetadata"); + ArrayList categoriesList = (ArrayList) call.argument("categories"); + String[] categories = categoriesList != null ? (String[]) categoriesList.toArray(new String[0]) : new String[0]; + ArrayList groupsList = (ArrayList) call.argument("groups"); + String[] groups = groupsList != null ? (String[]) groupsList.toArray(new String[0]) : new String[0]; + int limit = call.hasArgument("limit") ? (int) call.argument("limit") : 10; if (near != null) { Radar.searchPlaces(near, radius, chains, chainMetadata, categories, groups, limit, callback); @@ -913,12 +930,12 @@ public void run() { public void autocomplete(MethodCall call, final Result result) { String query = call.argument("query"); - HashMap nearMap = (HashMap)call.argument("near"); + HashMap nearMap = (HashMap) call.argument("near"); Location near = locationForMap(nearMap); - int limit = call.hasArgument("limit") ? (int)call.argument("limit") : 10; + int limit = call.hasArgument("limit") ? (int) call.argument("limit") : 10; String country = call.argument("country"); - ArrayList layersList = (ArrayList)call.argument("layers"); - String[] layers = layersList != null ? (String[])layersList.toArray(new String[0]) : new String[0]; + ArrayList layersList = (ArrayList) call.argument("layers"); + String[] layers = layersList != null ? (String[]) layersList.toArray(new String[0]) : new String[0]; Boolean mailable = call.argument("mailable"); Radar.autocomplete(query, near, layers, limit, country, true, mailable, new Radar.RadarGeocodeCallback() { @@ -948,7 +965,7 @@ public void run() { public void geocode(MethodCall call, final Result result) { String query = call.argument("query"); - Radar.geocode(query, null, null, new Radar.RadarGeocodeCallback() { + Radar.geocode(query, null, null, new Radar.RadarGeocodeCallback() { @Override public void onComplete(final Radar.RadarStatus status, final RadarAddress[] addresses) { runOnMainThread(new Runnable() { @@ -960,7 +977,7 @@ public void run() { if (addresses != null) { obj.put("addresses", RadarAddress.toJson(addresses)); } - + HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); result.success(map); } catch (Exception e) { @@ -996,12 +1013,14 @@ public void run() { } }; - if (call.hasArgument("location")) { - HashMap locationMap = (HashMap)call.argument("location"); + String[] layers = call.hasArgument("layers") && call.argument("layers") != null ? call.argument("layers") + : null; + if (call.hasArgument("location") && call.argument("location") != null) { + HashMap locationMap = (HashMap) call.argument("location"); Location location = locationForMap(locationMap); - Radar.reverseGeocode(location, null, callback); + Radar.reverseGeocode(location, layers, callback); } else { - Radar.reverseGeocode(null ,callback); + Radar.reverseGeocode(layers, callback); } } @@ -1057,14 +1076,14 @@ public void run() { Location origin = null; if (call.hasArgument("origin")) { - HashMap originMap = (HashMap)call.argument("origin"); + HashMap originMap = (HashMap) call.argument("origin"); origin = locationForMap(originMap); } - HashMap destinationMap = (HashMap)call.argument("destination"); + HashMap destinationMap = (HashMap) call.argument("destination"); Location destination = locationForMap(destinationMap); EnumSet modes = EnumSet.noneOf(Radar.RadarRouteMode.class); ArrayList modesList = call.argument("modes"); - String[] modesArr = (String[])(new String[0]); + String[] modesArr = (String[]) (new String[0]); for (String modeStr : modesArr) { if (modeStr.equals("FOOT") || modeStr.equals("foot")) { modes.add(Radar.RadarRouteMode.FOOT); @@ -1077,7 +1096,9 @@ public void run() { } } String unitsStr = call.argument("units"); - Radar.RadarRouteUnits units = unitsStr.equals("METRIC") || unitsStr.equals("metric") ? Radar.RadarRouteUnits.METRIC : Radar.RadarRouteUnits.IMPERIAL; + Radar.RadarRouteUnits units = unitsStr.equals("METRIC") || unitsStr.equals("metric") + ? Radar.RadarRouteUnits.METRIC + : Radar.RadarRouteUnits.IMPERIAL; if (origin != null) { Radar.getDistance(origin, destination, modes, units, callback); @@ -1086,7 +1107,7 @@ public void run() { } } - public void logConversion(MethodCall call, final Result result) throws JSONException { + public void logConversion(MethodCall call, final Result result) throws JSONException { Radar.RadarLogConversionCallback callback = new Radar.RadarLogConversionCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, @Nullable RadarEvent event) { @@ -1099,7 +1120,7 @@ public void run() { if (event != null) { obj.put("event", event.toJson()); } - + HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); result.success(map); } catch (Exception e) { @@ -1111,10 +1132,10 @@ public void run() { }; String name = call.argument("name"); - HashMap metadataMap= call.argument("metadata"); - JSONObject metadataJson = jsonForMap(metadataMap); + HashMap metadataMap = call.argument("metadata"); + JSONObject metadataJson = jsonForMap(metadataMap); if (call.hasArgument("revenue") && call.argument("revenue") != null) { - double revenue = (Double)call.argument("revenue"); + double revenue = (Double) call.argument("revenue"); Radar.logConversion(name, revenue, metadataJson, callback); } else { Radar.logConversion(name, metadataJson, callback); @@ -1132,7 +1153,7 @@ public void logResigningActive(Result result) { } public void getMatrix(MethodCall call, final Result result) throws JSONException { - ArrayList originsArr = call.argument("origins"); + ArrayList originsArr = call.argument("origins"); Location[] origins = new Location[originsArr.size()]; for (int i = 0; i < originsArr.size(); i++) { origins[i] = locationForMap(originsArr.get(i)); @@ -1146,7 +1167,7 @@ public void getMatrix(MethodCall call, final Result result) throws JSONException Radar.RadarRouteMode mode = Radar.RadarRouteMode.CAR; if (modeStr != null) { modeStr = modeStr.toLowerCase(); - if ( modeStr.equals("foot")) { + if (modeStr.equals("foot")) { mode = Radar.RadarRouteMode.FOOT; } else if (modeStr.equals("bike")) { mode = Radar.RadarRouteMode.BIKE; @@ -1159,7 +1180,9 @@ public void getMatrix(MethodCall call, final Result result) throws JSONException } } String unitsStr = call.argument("units"); - Radar.RadarRouteUnits units = unitsStr != null && unitsStr.toLowerCase().equals("metric") ? Radar.RadarRouteUnits.METRIC : Radar.RadarRouteUnits.IMPERIAL; + Radar.RadarRouteUnits units = unitsStr != null && unitsStr.toLowerCase().equals("metric") + ? Radar.RadarRouteUnits.METRIC + : Radar.RadarRouteUnits.IMPERIAL; Radar.getMatrix(origins, destinations, mode, units, new Radar.RadarMatrixCallback() { @Override @@ -1220,7 +1243,8 @@ private void isUsingRemoteTrackingOptions(Result result) { public void validateAddress(MethodCall call, final Result result) throws JSONException { Radar.RadarValidateAddressCallback callback = new Radar.RadarValidateAddressCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final RadarAddress address, final Radar.RadarAddressVerificationStatus verificationStatus) { + public void onComplete(final Radar.RadarStatus status, final RadarAddress address, + final Radar.RadarAddressVerificationStatus verificationStatus) { runOnMainThread(new Runnable() { @Override public void run() { @@ -1244,21 +1268,21 @@ public void run() { } }; - HashMap addressMap= call.argument("address"); + HashMap addressMap = call.argument("address"); JSONObject addressJSON = jsonForMap(addressMap); RadarAddress address = RadarAddress.fromJson(addressJSON); Radar.validateAddress(address, callback); } private Location locationForMap(HashMap locationMap) { - double latitude = (Double)locationMap.get("latitude"); - double longitude = (Double)locationMap.get("longitude"); + double latitude = (Double) locationMap.get("latitude"); + double longitude = (Double) locationMap.get("longitude"); Location location = new Location("RadarSDK"); location.setLatitude(latitude); location.setLongitude(longitude); if (locationMap.containsKey("accuracy")) { - double accuracyDouble = (Double)locationMap.get("accuracy"); - float accuracy = (float)accuracyDouble; + double accuracyDouble = (Double) locationMap.get("accuracy"); + float accuracy = (float) accuracyDouble; location.setAccuracy(accuracy); } return location; @@ -1291,13 +1315,13 @@ public void onEventsReceived(Context context, RadarEvent[] events, RadarUser use } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("events", RadarEvent.toJson(events)); obj.put("user", user.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1331,7 +1355,7 @@ public void onLocationUpdated(Context context, Location location, RadarUser user obj.put("user", user.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1346,9 +1370,9 @@ public void run() { Log.e(TAG, e.toString()); } } - - public void onClientLocationUpdated(Context context, Location location, boolean stopped, Radar.RadarLocationSource source) { + public void onClientLocationUpdated(Context context, Location location, boolean stopped, + Radar.RadarLocationSource source) { try { SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); long callbackHandle = sharedPrefs.getLong("clientLocation", 0L); @@ -1358,14 +1382,14 @@ public void onClientLocationUpdated(Context context, Location location, boolean } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("location", Radar.jsonForLocation(location)); obj.put("stopped", stopped); obj.put("source", source.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1380,7 +1404,7 @@ public void run() { Log.e(TAG, e.toString()); } } - + @Override public void onError(Context context, Radar.RadarStatus status) { try { @@ -1392,12 +1416,12 @@ public void onError(Context context, Radar.RadarStatus status) { } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("status", status.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1412,7 +1436,7 @@ public void run() { Log.e(TAG, e.toString()); } } - + @Override public void onLog(Context context, String message) { try { @@ -1424,12 +1448,12 @@ public void onLog(Context context, String message) { } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("message", message); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1445,7 +1469,7 @@ public void run() { } } } - + public static class RadarFlutterVerifiedReceiver extends RadarVerifiedReceiver { @Override @@ -1459,12 +1483,12 @@ public void onTokenUpdated(Context context, RadarVerifiedLocationToken token) { } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("token", token.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1484,7 +1508,7 @@ public void run() { public void attachListeners(MethodCall call, Result result) { SharedPreferences sharedPrefs = mContext.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackDispatcherHandle = ((Number)call.argument("callbackDispatcherHandle")).longValue(); + long callbackDispatcherHandle = ((Number) call.argument("callbackDispatcherHandle")).longValue(); sharedPrefs.edit().putLong(CALLBACK_DISPATCHER_HANDLE_KEY, callbackDispatcherHandle).commit(); result.success(true); } @@ -1499,7 +1523,7 @@ public void detachListeners(MethodCall call, Result result) { public void on(MethodCall call, Result result) { SharedPreferences sharedPrefs = mContext.getSharedPreferences(TAG, Context.MODE_PRIVATE); String listener = call.argument("listener"); - long callbackHandle = ((Number)call.argument("callbackHandle")).longValue(); + long callbackHandle = ((Number) call.argument("callbackHandle")).longValue(); sharedPrefs.edit().putLong(listener, callbackHandle).commit(); result.success(true); } diff --git a/example/lib/main.dart b/example/lib/main.dart index 8dd34d8..fc5f88d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -279,6 +279,14 @@ class _MyAppState extends State with WidgetsBindingObserver { }, child: Text('geocode()'), ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.reverseGeocode(); + print("reverseGeocode: $resp"); + }, + child: Text('reverseGeocode()'), + ), ElevatedButton( style: raisedButtonStyle, onPressed: () async { diff --git a/ios/Classes/RadarFlutterPlugin.m b/ios/Classes/RadarFlutterPlugin.m index 33785e3..c505483 100644 --- a/ios/Classes/RadarFlutterPlugin.m +++ b/ios/Classes/RadarFlutterPlugin.m @@ -770,9 +770,30 @@ - (void)reverseGeocode:(FlutterMethodCall *)call withResult:(FlutterResult)resul result(dict); }; - NSDictionary *argsDict = call.arguments; + NSDictionary *argsDict = call.arguments; + + NSArray *layers = nil; + id layersValue = argsDict[@"layers"]; + if (layersValue != nil && [layersValue isKindOfClass:[NSArray class]]) { + NSArray *tempLayers = (NSArray *)layersValue; + // Further check if the array contains only NSString objects + BOOL allStrings = YES; + for (id item in tempLayers) { + if (![item isKindOfClass:[NSString class]]) { + allStrings = NO; + break; + } + } + if (allStrings) { + layers = tempLayers; + } + } - NSDictionary *locationDict = argsDict[@"location"]; + NSDictionary *locationDict = nil; + id locationDictValue = argsDict[@"location"]; + if (locationDictValue != nil && [locationDictValue isKindOfClass:[NSDictionary class]]) { + locationDict = (NSDictionary *)locationDictValue; + } if (locationDict) { NSNumber *latitudeNumber = locationDict[@"latitude"]; NSNumber *longitudeNumber = locationDict[@"longitude"]; @@ -780,9 +801,9 @@ - (void)reverseGeocode:(FlutterMethodCall *)call withResult:(FlutterResult)resul double longitude = [longitudeNumber doubleValue]; CLLocation *location = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) altitude:-1 horizontalAccuracy:5 verticalAccuracy:-1 timestamp:[NSDate date]]; - [Radar reverseGeocodeLocation:location completionHandler:completionHandler]; + [Radar reverseGeocodeLocation:location layers:layers completionHandler:completionHandler]; } else { - [Radar reverseGeocodeWithCompletionHandler:completionHandler]; + [Radar reverseGeocodeWithLayers:layers completionHandler:completionHandler]; } } diff --git a/lib/flutter_radar.dart b/lib/flutter_radar.dart index c6033fa..7eabb41 100644 --- a/lib/flutter_radar.dart +++ b/lib/flutter_radar.dart @@ -164,8 +164,8 @@ class Radar { static Future startTrackingVerified(int interval, bool beacons) async { try { - await _channel.invokeMethod('startTrackingVerified', - {'interval': interval, 'beacons': beacons}); + await _channel.invokeMethod( + 'startTrackingVerified', {'interval': interval, 'beacons': beacons}); } on PlatformException catch (e) { print(e); } @@ -353,10 +353,14 @@ class Radar { } } - static Future reverseGeocode(Map location) async { + static Future reverseGeocode( + {Map? location, List? layers}) async { try { - return await _channel - .invokeMethod('reverseGeocode', {'location': location}); + final Map arguments = { + 'location': location != null ? location : null, + 'layers': layers != null ? layers : null + }; + return await _channel.invokeMethod('reverseGeocode', arguments); } on PlatformException catch (e) { print(e); return {'error': e.code}; @@ -469,7 +473,8 @@ class Radar { static Future trackVerified({bool? beacons}) async { try { - return await _channel.invokeMethod('trackVerified', {'beacons': beacons != null ? beacons : false}); + return await _channel.invokeMethod( + 'trackVerified', {'beacons': beacons != null ? beacons : false}); } on PlatformException catch (e) { print(e); return {'error': e.code}; @@ -498,7 +503,6 @@ class Radar { } } - static onLocation(Function(Map res) callback) async { try { final CallbackHandle handle = @@ -616,49 +620,49 @@ class Radar { } static Map presetContinuousIOS = { - "desiredStoppedUpdateInterval": 30, - "desiredMovingUpdateInterval": 30, - "desiredSyncInterval": 20, - "desiredAccuracy":'high', - "stopDuration": 140, - "stopDistance": 70, - "replay": 'none', - "useStoppedGeofence": false, - "showBlueBar": true, - "startTrackingAfter": null, - "stopTrackingAfter": null, - "stoppedGeofenceRadius": 0, - "useMovingGeofence": false, - "movingGeofenceRadius": 0, - "syncGeofences": true, - "useVisits": false, - "useSignificantLocationChanges": false, - "beacons": false, - "sync": 'all', -}; - - static Map presetContinuousAndroid = { - "desiredStoppedUpdateInterval": 30, - "fastestStoppedUpdateInterval": 30, - "desiredMovingUpdateInterval": 30, - "fastestMovingUpdateInterval": 30, - "desiredSyncInterval": 20, - "desiredAccuracy": 'high', - "stopDuration": 140, - "stopDistance": 70, - "replay": 'none', - "sync": 'all', - "useStoppedGeofence": false, - "stoppedGeofenceRadius": 0, - "useMovingGeofence": false, - "movingGeofenceRadius": 0, - "syncGeofences": true, - "syncGeofencesLimit": 0, - "foregroundServiceEnabled": true, - "beacons": false, - "startTrackingAfter": null, - "stopTrackingAfter": null, -}; + "desiredStoppedUpdateInterval": 30, + "desiredMovingUpdateInterval": 30, + "desiredSyncInterval": 20, + "desiredAccuracy": 'high', + "stopDuration": 140, + "stopDistance": 70, + "replay": 'none', + "useStoppedGeofence": false, + "showBlueBar": true, + "startTrackingAfter": null, + "stopTrackingAfter": null, + "stoppedGeofenceRadius": 0, + "useMovingGeofence": false, + "movingGeofenceRadius": 0, + "syncGeofences": true, + "useVisits": false, + "useSignificantLocationChanges": false, + "beacons": false, + "sync": 'all', + }; + + static Map presetContinuousAndroid = { + "desiredStoppedUpdateInterval": 30, + "fastestStoppedUpdateInterval": 30, + "desiredMovingUpdateInterval": 30, + "fastestMovingUpdateInterval": 30, + "desiredSyncInterval": 20, + "desiredAccuracy": 'high', + "stopDuration": 140, + "stopDistance": 70, + "replay": 'none', + "sync": 'all', + "useStoppedGeofence": false, + "stoppedGeofenceRadius": 0, + "useMovingGeofence": false, + "movingGeofenceRadius": 0, + "syncGeofences": true, + "syncGeofencesLimit": 0, + "foregroundServiceEnabled": true, + "beacons": false, + "startTrackingAfter": null, + "stopTrackingAfter": null, + }; static Map presetResponsiveIOS = { "desiredStoppedUpdateInterval": 0, @@ -706,54 +710,54 @@ class Radar { }; static Map presetEfficientIOS = { - "desiredStoppedUpdateInterval": 0, - "desiredMovingUpdateInterval": 0, - "desiredSyncInterval": 0, - "desiredAccuracy": "medium", - "stopDuration": 0, - "stopDistance": 0, - "replay": 'stops', - "useStoppedGeofence": false, - "showBlueBar": false, - "startTrackingAfter": null, - "stopTrackingAfter": null, - "stoppedGeofenceRadius": 0, - "useMovingGeofence": false, - "movingGeofenceRadius": 0, - "syncGeofences": true, - "useVisits": true, - "useSignificantLocationChanges": false, - "beacons": false, - "sync": 'all', -}; - - static Map presetEfficientAndroid ={ - "desiredStoppedUpdateInterval": 3600, - "fastestStoppedUpdateInterval": 1200, - "desiredMovingUpdateInterval": 1200, - "fastestMovingUpdateInterval": 360, - "desiredSyncInterval": 140, - "desiredAccuracy": 'medium', - "stopDuration": 140, - "stopDistance": 70, - "replay": 'stops', - "sync": 'all', - "useStoppedGeofence": false, - "stoppedGeofenceRadius": 0, - "useMovingGeofence": false, - "movingGeofenceRadius": 0, - "syncGeofences": true, - "syncGeofencesLimit": 10, - "foregroundServiceEnabled": false, - "beacons": false, - "startTrackingAfter": null, - "stopTrackingAfter": null, -}; + "desiredStoppedUpdateInterval": 0, + "desiredMovingUpdateInterval": 0, + "desiredSyncInterval": 0, + "desiredAccuracy": "medium", + "stopDuration": 0, + "stopDistance": 0, + "replay": 'stops', + "useStoppedGeofence": false, + "showBlueBar": false, + "startTrackingAfter": null, + "stopTrackingAfter": null, + "stoppedGeofenceRadius": 0, + "useMovingGeofence": false, + "movingGeofenceRadius": 0, + "syncGeofences": true, + "useVisits": true, + "useSignificantLocationChanges": false, + "beacons": false, + "sync": 'all', + }; + + static Map presetEfficientAndroid = { + "desiredStoppedUpdateInterval": 3600, + "fastestStoppedUpdateInterval": 1200, + "desiredMovingUpdateInterval": 1200, + "fastestMovingUpdateInterval": 360, + "desiredSyncInterval": 140, + "desiredAccuracy": 'medium', + "stopDuration": 140, + "stopDistance": 70, + "replay": 'stops', + "sync": 'all', + "useStoppedGeofence": false, + "stoppedGeofenceRadius": 0, + "useMovingGeofence": false, + "movingGeofenceRadius": 0, + "syncGeofences": true, + "syncGeofencesLimit": 10, + "foregroundServiceEnabled": false, + "beacons": false, + "startTrackingAfter": null, + "stopTrackingAfter": null, + }; static Map presetResponsive = Platform.isIOS ? presetResponsiveIOS : presetResponsiveAndroid; static Map presetContinuous = Platform.isIOS ? presetContinuousIOS : presetContinuousAndroid; - static Map presetEfficient= + static Map presetEfficient = Platform.isIOS ? presetEfficientIOS : presetEfficientAndroid; } From 4ca50749e3302f978ecafae1bde4f25dafc64d3a Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Tue, 16 Jul 2024 15:10:49 -0400 Subject: [PATCH 09/16] revert lining changes --- .../io/radar/flutter/RadarFlutterPlugin.java | 242 ++++++++---------- 1 file changed, 110 insertions(+), 132 deletions(-) diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index dcdaa3e..266776f 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -67,8 +67,7 @@ import io.flutter.view.FlutterRunArguments; import io.flutter.view.FlutterCallbackInformation; -public class RadarFlutterPlugin - implements FlutterPlugin, MethodCallHandler, ActivityAware, RequestPermissionsResultListener { +public class RadarFlutterPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware, RequestPermissionsResultListener { private static FlutterEngine sBackgroundFlutterEngine; @@ -83,9 +82,9 @@ public class RadarFlutterPlugin private static final int PERMISSIONS_REQUEST_CODE = 20160525; private Result mPermissionsRequestResult; - + private static void initializeBackgroundEngine(Context context) { - synchronized (lock) { + synchronized(lock) { if (sBackgroundFlutterEngine == null) { FlutterMain.startInitialization(context.getApplicationContext()); FlutterMain.ensureInitializationComplete(context.getApplicationContext(), null); @@ -97,15 +96,12 @@ private static void initializeBackgroundEngine(Context context) { return; } - FlutterCallbackInformation callbackInfo = FlutterCallbackInformation - .lookupCallbackInformation(callbackDispatcherHandle); + FlutterCallbackInformation callbackInfo = FlutterCallbackInformation.lookupCallbackInformation(callbackDispatcherHandle); sBackgroundFlutterEngine = new FlutterEngine(context.getApplicationContext()); - DartCallback callback = new DartCallback(context.getAssets(), FlutterMain.findAppBundlePath(context), - callbackInfo); + DartCallback callback = new DartCallback(context.getAssets(), FlutterMain.findAppBundlePath(context), callbackInfo); sBackgroundFlutterEngine.getDartExecutor().executeDartCallback(callback); - sBackgroundChannel = new MethodChannel(sBackgroundFlutterEngine.getDartExecutor().getBinaryMessenger(), - "flutter_radar_background"); + sBackgroundChannel = new MethodChannel(sBackgroundFlutterEngine.getDartExecutor().getBinaryMessenger(), "flutter_radar_background"); } } } @@ -264,7 +260,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) break; case "autocomplete": autocomplete(call, result); - break; + break; case "forwardGeocode": geocode(call, result); break; @@ -336,7 +332,7 @@ private void initialize(MethodCall call, Result result) { } private void setNotificationOptions(MethodCall call, Result result) { - HashMap notificationOptionsMap = (HashMap) call.arguments; + HashMap notificationOptionsMap = (HashMap)call.arguments; JSONObject notificationOptionsJson = new JSONObject(notificationOptionsMap); RadarNotificationOptions options = RadarNotificationOptions.fromJson(notificationOptionsJson); Radar.setNotificationOptions(options); @@ -344,10 +340,9 @@ private void setNotificationOptions(MethodCall call, Result result) { } private void setForegroundServiceOptions(MethodCall call, Result result) { - HashMap foregroundServiceOptionsMap = (HashMap) call.arguments; + HashMap foregroundServiceOptionsMap = (HashMap)call.arguments; JSONObject foregroundServiceOptionsJson = new JSONObject(foregroundServiceOptionsMap); - RadarTrackingOptionsForegroundService options = RadarTrackingOptionsForegroundService - .fromJson(foregroundServiceOptionsJson); + RadarTrackingOptionsForegroundService options = RadarTrackingOptionsForegroundService.fromJson(foregroundServiceOptionsJson); Radar.setForegroundServiceOptions(options); result.success(true); } @@ -370,21 +365,20 @@ private void setLogLevel(MethodCall call, Result result) { result.success(true); } + private void getPermissionStatus(Result result) { String status = "NOT_DETERMINED"; - + if (mActivity == null || result == null) { result.success(status); return; } - boolean foreground = ActivityCompat.checkSelfPermission(mActivity, - Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; + boolean foreground = ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; if (Build.VERSION.SDK_INT >= 29) { if (foreground) { - boolean background = ActivityCompat.checkSelfPermission(mActivity, - Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED; + boolean background = ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED; status = background ? "GRANTED_BACKGROUND" : "GRANTED_FOREGROUND"; } else { status = "DENIED"; @@ -402,15 +396,9 @@ private void requestPermissions(MethodCall call, Result result) { if (mActivity != null) { if (Build.VERSION.SDK_INT >= 23) { if (background && Build.VERSION.SDK_INT >= 29) { - ActivityCompat.requestPermissions(mActivity, - new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_BACKGROUND_LOCATION }, - PERMISSIONS_REQUEST_CODE); + ActivityCompat.requestPermissions(mActivity, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION }, PERMISSIONS_REQUEST_CODE); } else { - ActivityCompat.requestPermissions(mActivity, new String[] { - Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }, - PERMISSIONS_REQUEST_CODE); + ActivityCompat.requestPermissions(mActivity, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }, PERMISSIONS_REQUEST_CODE); } } } @@ -439,7 +427,7 @@ private void getDescription(Result result) { } private void setMetadata(MethodCall call, Result result) { - HashMap metadataMap = (HashMap) call.arguments; + HashMap metadataMap = (HashMap)call.arguments; JSONObject metadata = new JSONObject(metadataMap); Radar.setMetadata(metadata); result.success(true); @@ -449,7 +437,7 @@ private void getMetadata(Result result) { JSONObject metadata = Radar.getMetadata(); HashMap metadataMap = null; if (metadata != null) { - metadataMap = new Gson().fromJson(metadata.toString(), HashMap.class); + metadataMap = new Gson().fromJson(metadata.toString(), HashMap.class); } result.success(metadataMap); } @@ -502,8 +490,7 @@ public void run() { private void trackOnce(MethodCall call, final Result result) { Radar.RadarTrackCallback callback = new Radar.RadarTrackCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final Location location, final RadarEvent[] events, - final RadarUser user) { + public void onComplete(final Radar.RadarStatus status, final Location location, final RadarEvent[] events, final RadarUser user) { runOnMainThread(new Runnable() { @Override public void run() { @@ -519,7 +506,7 @@ public void run() { if (user != null) { obj.put("user", user.toJson()); } - + HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); result.success(map); } catch (Exception e) { @@ -529,17 +516,17 @@ public void run() { }); } }; - + if (call.hasArgument("location") && call.argument("location") != null) { - HashMap locationMap = (HashMap) call.argument("location"); + HashMap locationMap = (HashMap)call.argument("location"); Location location = locationForMap(locationMap); Radar.trackOnce(location, callback); } else { RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.MEDIUM; boolean beaconsTrackingOption = false; - + if (call.hasArgument("desiredAccuracy") && call.argument("desiredAccuracy") != null) { - String desiredAccuracy = ((String) call.argument("desiredAccuracy")).toLowerCase(); + String desiredAccuracy = ((String)call.argument("desiredAccuracy")).toLowerCase(); if (desiredAccuracy.equals("none")) { accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.NONE; } else if (desiredAccuracy.equals("low")) { @@ -553,10 +540,10 @@ public void run() { if (call.hasArgument("beacons") && call.argument("beacons") != null) { beaconsTrackingOption = call.argument("beacons"); } - + Radar.trackOnce(accuracyLevel, beaconsTrackingOption, callback); } - } + } private void startTracking(MethodCall call, Result result) { String preset = call.argument("preset"); @@ -575,7 +562,7 @@ private void startTracking(MethodCall call, Result result) { } private void startTrackingCustom(MethodCall call, Result result) { - HashMap optionsMap = (HashMap) call.arguments; + HashMap optionsMap = (HashMap)call.arguments; JSONObject optionsJson = new JSONObject(optionsMap); RadarTrackingOptions options = RadarTrackingOptions.fromJson(optionsJson); Radar.startTracking(options); @@ -583,9 +570,7 @@ private void startTrackingCustom(MethodCall call, Result result) { } private void startTrackingVerified(MethodCall call, Result result) { - int interval = call.hasArgument("interval") && call.argument("interval") != null - ? (int) call.argument("interval") - : 1; + int interval = call.hasArgument("interval") && call.argument("interval") != null ? (int)call.argument("interval") : 1; Boolean beacons = call.hasArgument("beacons") ? call.argument("beacons") : false; Radar.startTrackingVerified(interval, beacons); result.success(true); @@ -597,9 +582,9 @@ private void stopTrackingVerified(MethodCall call, Result result) { } public void mockTracking(MethodCall call, final Result result) { - HashMap originMap = (HashMap) call.argument("origin"); + HashMap originMap = (HashMap)call.argument("origin"); Location origin = locationForMap(originMap); - HashMap destinationMap = (HashMap) call.argument("destination"); + HashMap destinationMap = (HashMap)call.argument("destination"); Location destination = locationForMap(destinationMap); String modeStr = call.argument("mode"); Radar.RadarRouteMode mode = Radar.RadarRouteMode.CAR; @@ -610,13 +595,13 @@ public void mockTracking(MethodCall call, final Result result) { } else if (modeStr.equals("CAR") || modeStr.equals("car")) { mode = Radar.RadarRouteMode.CAR; } - int steps = call.hasArgument("steps") ? (int) call.argument("steps") : 10; - int interval = call.hasArgument("interval") ? (int) call.argument("interval") : 1; + int steps = call.hasArgument("steps") ? (int)call.argument("steps") : 10; + int interval = call.hasArgument("interval") ? (int)call.argument("interval") : 1; Radar.mockTracking(origin, destination, mode, steps, interval, new Radar.RadarTrackCallback() { @Override public void onComplete(Radar.RadarStatus status, Location location, RadarEvent[] events, RadarUser user) { - + } }); } @@ -631,21 +616,21 @@ private void isTracking(Result result) { result.success(isTracking); } - private void getTrackingOptions(Result result) throws JSONException { - RadarTrackingOptions options = Radar.getTrackingOptions(); + private void getTrackingOptions(Result result) throws JSONException { + RadarTrackingOptions options = Radar.getTrackingOptions(); JSONObject optionsJson = options.toJson(); HashMap optionsMap = null; if (optionsJson != null) { - optionsMap = new Gson().fromJson(optionsJson.toString(), HashMap.class); + optionsMap = new Gson().fromJson(optionsJson.toString(), HashMap.class); } result.success(optionsMap); } public void startTrip(MethodCall call, Result result) throws JSONException { - HashMap tripOptionsMap = (HashMap) call.argument("tripOptions"); + HashMap tripOptionsMap = (HashMap)call.argument("tripOptions"); JSONObject tripOptionsJson = jsonForMap(tripOptionsMap); RadarTripOptions tripOptions = RadarTripOptions.fromJson(tripOptionsJson); - HashMap trackingOptionsMap = (HashMap) call.argument("trackingOptions"); + HashMap trackingOptionsMap = (HashMap)call.argument("trackingOptions"); JSONObject trackingOptionsJson = jsonForMap(trackingOptionsMap); RadarTrackingOptions trackingOptions = null; if (trackingOptionsJson != null) { @@ -654,8 +639,8 @@ public void startTrip(MethodCall call, Result result) throws JSONException { Radar.startTrip(tripOptions, trackingOptions, new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -681,7 +666,7 @@ public void run() { } public void updateTrip(MethodCall call, Result result) throws JSONException { - HashMap tripOptionsMap = (HashMap) call.argument("tripOptions"); + HashMap tripOptionsMap = (HashMap)call.argument("tripOptions"); JSONObject tripOptionsJson = jsonForMap(tripOptionsMap); RadarTripOptions tripOptions = RadarTripOptions.fromJson(tripOptionsJson); String statusStr = call.argument("status"); @@ -698,12 +683,12 @@ public void updateTrip(MethodCall call, Result result) throws JSONException { } else if (statusStr.equals("canceled")) { status = RadarTrip.RadarTripStatus.CANCELED; } - + Radar.updateTrip(tripOptions, status, new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -730,7 +715,7 @@ public void run() { public void getTripOptions(Result result) { RadarTripOptions tripOptions = Radar.getTripOptions(); - HashMap map = new Gson().fromJson(tripOptions.toJson().toString(), HashMap.class); + HashMap map = new Gson().fromJson(tripOptions.toJson().toString(), HashMap.class); result.success(map); } @@ -738,8 +723,8 @@ public void completeTrip(Result result) { Radar.completeTrip(new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -768,8 +753,8 @@ public void cancelTrip(Result result) { Radar.cancelTrip(new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -797,8 +782,7 @@ public void run() { public void getContext(MethodCall call, final Result result) { Radar.RadarContextCallback callback = new Radar.RadarContextCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final Location location, - final RadarContext context) { + public void onComplete(final Radar.RadarStatus status, final Location location, final RadarContext context) { runOnMainThread(new Runnable() { @Override public void run() { @@ -823,7 +807,7 @@ public void run() { }; if (call.hasArgument("location")) { - HashMap locationMap = (HashMap) call.argument("location"); + HashMap locationMap = (HashMap)call.argument("location"); Location location = locationForMap(locationMap); Radar.getContext(location, callback); } else { @@ -834,8 +818,7 @@ public void run() { private void searchGeofences(MethodCall call, final Result result) throws JSONException { Radar.RadarSearchGeofencesCallback callback = new Radar.RadarSearchGeofencesCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final Location location, - final RadarGeofence[] geofences) { + public void onComplete(final Radar.RadarStatus status, final Location location, final RadarGeofence[] geofences) { runOnMainThread(new Runnable() { @Override public void run() { @@ -861,15 +844,15 @@ public void run() { Location near = null; if (call.hasArgument("near")) { - HashMap nearMap = (HashMap) call.argument("near"); + HashMap nearMap = (HashMap)call.argument("near"); near = locationForMap(nearMap); } - int radius = call.hasArgument("radius") ? (int) call.argument("radius") : 1000; - ArrayList tagsList = (ArrayList) call.argument("tags"); - String[] tags = (String[]) tagsList.toArray(new String[0]); - HashMap metadataMap = (HashMap) call.argument("metadata"); + int radius = call.hasArgument("radius") ? (int)call.argument("radius") : 1000; + ArrayList tagsList = (ArrayList)call.argument("tags"); + String[] tags = (String[])tagsList.toArray(new String[0]); + HashMap metadataMap = (HashMap)call.argument("metadata"); JSONObject metadata = jsonForMap(metadataMap); - int limit = call.hasArgument("limit") ? (int) call.argument("limit") : 10; + int limit = call.hasArgument("limit") ? (int)call.argument("limit") : 10; boolean includeGeometry = call.hasArgument("includeGeometry") ? call.argument("includeGeometry") : false; if (near != null) { @@ -908,18 +891,18 @@ public void run() { Location near = null; if (call.hasArgument("near")) { - HashMap nearMap = (HashMap) call.argument("near"); + HashMap nearMap = (HashMap)call.argument("near"); near = locationForMap(nearMap); } - int radius = call.hasArgument("radius") ? (int) call.argument("radius") : 1000; - ArrayList chainsList = (ArrayList) call.argument("chains"); - String[] chains = (String[]) chainsList.toArray(new String[0]); - Map chainMetadata = (Map) call.argument("chainMetadata"); - ArrayList categoriesList = (ArrayList) call.argument("categories"); - String[] categories = categoriesList != null ? (String[]) categoriesList.toArray(new String[0]) : new String[0]; - ArrayList groupsList = (ArrayList) call.argument("groups"); - String[] groups = groupsList != null ? (String[]) groupsList.toArray(new String[0]) : new String[0]; - int limit = call.hasArgument("limit") ? (int) call.argument("limit") : 10; + int radius = call.hasArgument("radius") ? (int)call.argument("radius") : 1000; + ArrayList chainsList = (ArrayList)call.argument("chains"); + String[] chains = (String[])chainsList.toArray(new String[0]); + Map chainMetadata = (Map)call.argument("chainMetadata"); + ArrayList categoriesList = (ArrayList)call.argument("categories"); + String[] categories = categoriesList != null ? (String[])categoriesList.toArray(new String[0]) : new String[0]; + ArrayList groupsList = (ArrayList)call.argument("groups"); + String[] groups = groupsList != null ? (String[])groupsList.toArray(new String[0]) : new String[0]; + int limit = call.hasArgument("limit") ? (int)call.argument("limit") : 10; if (near != null) { Radar.searchPlaces(near, radius, chains, chainMetadata, categories, groups, limit, callback); @@ -930,12 +913,12 @@ public void run() { public void autocomplete(MethodCall call, final Result result) { String query = call.argument("query"); - HashMap nearMap = (HashMap) call.argument("near"); + HashMap nearMap = (HashMap)call.argument("near"); Location near = locationForMap(nearMap); - int limit = call.hasArgument("limit") ? (int) call.argument("limit") : 10; + int limit = call.hasArgument("limit") ? (int)call.argument("limit") : 10; String country = call.argument("country"); - ArrayList layersList = (ArrayList) call.argument("layers"); - String[] layers = layersList != null ? (String[]) layersList.toArray(new String[0]) : new String[0]; + ArrayList layersList = (ArrayList)call.argument("layers"); + String[] layers = layersList != null ? (String[])layersList.toArray(new String[0]) : new String[0]; Boolean mailable = call.argument("mailable"); Radar.autocomplete(query, near, layers, limit, country, true, mailable, new Radar.RadarGeocodeCallback() { @@ -965,7 +948,7 @@ public void run() { public void geocode(MethodCall call, final Result result) { String query = call.argument("query"); - Radar.geocode(query, null, null, new Radar.RadarGeocodeCallback() { + Radar.geocode(query, null, null, new Radar.RadarGeocodeCallback() { @Override public void onComplete(final Radar.RadarStatus status, final RadarAddress[] addresses) { runOnMainThread(new Runnable() { @@ -977,7 +960,7 @@ public void run() { if (addresses != null) { obj.put("addresses", RadarAddress.toJson(addresses)); } - + HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); result.success(map); } catch (Exception e) { @@ -1076,14 +1059,14 @@ public void run() { Location origin = null; if (call.hasArgument("origin")) { - HashMap originMap = (HashMap) call.argument("origin"); + HashMap originMap = (HashMap)call.argument("origin"); origin = locationForMap(originMap); } - HashMap destinationMap = (HashMap) call.argument("destination"); + HashMap destinationMap = (HashMap)call.argument("destination"); Location destination = locationForMap(destinationMap); EnumSet modes = EnumSet.noneOf(Radar.RadarRouteMode.class); ArrayList modesList = call.argument("modes"); - String[] modesArr = (String[]) (new String[0]); + String[] modesArr = (String[])(new String[0]); for (String modeStr : modesArr) { if (modeStr.equals("FOOT") || modeStr.equals("foot")) { modes.add(Radar.RadarRouteMode.FOOT); @@ -1096,9 +1079,7 @@ public void run() { } } String unitsStr = call.argument("units"); - Radar.RadarRouteUnits units = unitsStr.equals("METRIC") || unitsStr.equals("metric") - ? Radar.RadarRouteUnits.METRIC - : Radar.RadarRouteUnits.IMPERIAL; + Radar.RadarRouteUnits units = unitsStr.equals("METRIC") || unitsStr.equals("metric") ? Radar.RadarRouteUnits.METRIC : Radar.RadarRouteUnits.IMPERIAL; if (origin != null) { Radar.getDistance(origin, destination, modes, units, callback); @@ -1107,7 +1088,7 @@ public void run() { } } - public void logConversion(MethodCall call, final Result result) throws JSONException { + public void logConversion(MethodCall call, final Result result) throws JSONException { Radar.RadarLogConversionCallback callback = new Radar.RadarLogConversionCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, @Nullable RadarEvent event) { @@ -1120,7 +1101,7 @@ public void run() { if (event != null) { obj.put("event", event.toJson()); } - + HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); result.success(map); } catch (Exception e) { @@ -1132,10 +1113,10 @@ public void run() { }; String name = call.argument("name"); - HashMap metadataMap = call.argument("metadata"); - JSONObject metadataJson = jsonForMap(metadataMap); + HashMap metadataMap= call.argument("metadata"); + JSONObject metadataJson = jsonForMap(metadataMap); if (call.hasArgument("revenue") && call.argument("revenue") != null) { - double revenue = (Double) call.argument("revenue"); + double revenue = (Double)call.argument("revenue"); Radar.logConversion(name, revenue, metadataJson, callback); } else { Radar.logConversion(name, metadataJson, callback); @@ -1153,7 +1134,7 @@ public void logResigningActive(Result result) { } public void getMatrix(MethodCall call, final Result result) throws JSONException { - ArrayList originsArr = call.argument("origins"); + ArrayList originsArr = call.argument("origins"); Location[] origins = new Location[originsArr.size()]; for (int i = 0; i < originsArr.size(); i++) { origins[i] = locationForMap(originsArr.get(i)); @@ -1167,7 +1148,7 @@ public void getMatrix(MethodCall call, final Result result) throws JSONException Radar.RadarRouteMode mode = Radar.RadarRouteMode.CAR; if (modeStr != null) { modeStr = modeStr.toLowerCase(); - if (modeStr.equals("foot")) { + if ( modeStr.equals("foot")) { mode = Radar.RadarRouteMode.FOOT; } else if (modeStr.equals("bike")) { mode = Radar.RadarRouteMode.BIKE; @@ -1180,9 +1161,7 @@ public void getMatrix(MethodCall call, final Result result) throws JSONException } } String unitsStr = call.argument("units"); - Radar.RadarRouteUnits units = unitsStr != null && unitsStr.toLowerCase().equals("metric") - ? Radar.RadarRouteUnits.METRIC - : Radar.RadarRouteUnits.IMPERIAL; + Radar.RadarRouteUnits units = unitsStr != null && unitsStr.toLowerCase().equals("metric") ? Radar.RadarRouteUnits.METRIC : Radar.RadarRouteUnits.IMPERIAL; Radar.getMatrix(origins, destinations, mode, units, new Radar.RadarMatrixCallback() { @Override @@ -1243,8 +1222,7 @@ private void isUsingRemoteTrackingOptions(Result result) { public void validateAddress(MethodCall call, final Result result) throws JSONException { Radar.RadarValidateAddressCallback callback = new Radar.RadarValidateAddressCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final RadarAddress address, - final Radar.RadarAddressVerificationStatus verificationStatus) { + public void onComplete(final Radar.RadarStatus status, final RadarAddress address, final Radar.RadarAddressVerificationStatus verificationStatus) { runOnMainThread(new Runnable() { @Override public void run() { @@ -1268,21 +1246,21 @@ public void run() { } }; - HashMap addressMap = call.argument("address"); + HashMap addressMap= call.argument("address"); JSONObject addressJSON = jsonForMap(addressMap); RadarAddress address = RadarAddress.fromJson(addressJSON); Radar.validateAddress(address, callback); } private Location locationForMap(HashMap locationMap) { - double latitude = (Double) locationMap.get("latitude"); - double longitude = (Double) locationMap.get("longitude"); + double latitude = (Double)locationMap.get("latitude"); + double longitude = (Double)locationMap.get("longitude"); Location location = new Location("RadarSDK"); location.setLatitude(latitude); location.setLongitude(longitude); if (locationMap.containsKey("accuracy")) { - double accuracyDouble = (Double) locationMap.get("accuracy"); - float accuracy = (float) accuracyDouble; + double accuracyDouble = (Double)locationMap.get("accuracy"); + float accuracy = (float)accuracyDouble; location.setAccuracy(accuracy); } return location; @@ -1315,13 +1293,13 @@ public void onEventsReceived(Context context, RadarEvent[] events, RadarUser use } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("events", RadarEvent.toJson(events)); obj.put("user", user.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized (lock) { + synchronized(lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1355,7 +1333,7 @@ public void onLocationUpdated(Context context, Location location, RadarUser user obj.put("user", user.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized (lock) { + synchronized(lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1370,9 +1348,9 @@ public void run() { Log.e(TAG, e.toString()); } } + - public void onClientLocationUpdated(Context context, Location location, boolean stopped, - Radar.RadarLocationSource source) { + public void onClientLocationUpdated(Context context, Location location, boolean stopped, Radar.RadarLocationSource source) { try { SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); long callbackHandle = sharedPrefs.getLong("clientLocation", 0L); @@ -1382,14 +1360,14 @@ public void onClientLocationUpdated(Context context, Location location, boolean } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("location", Radar.jsonForLocation(location)); obj.put("stopped", stopped); obj.put("source", source.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized (lock) { + synchronized(lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1404,7 +1382,7 @@ public void run() { Log.e(TAG, e.toString()); } } - + @Override public void onError(Context context, Radar.RadarStatus status) { try { @@ -1416,12 +1394,12 @@ public void onError(Context context, Radar.RadarStatus status) { } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("status", status.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized (lock) { + synchronized(lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1436,7 +1414,7 @@ public void run() { Log.e(TAG, e.toString()); } } - + @Override public void onLog(Context context, String message) { try { @@ -1448,12 +1426,12 @@ public void onLog(Context context, String message) { } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("message", message); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized (lock) { + synchronized(lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1469,7 +1447,7 @@ public void run() { } } } - + public static class RadarFlutterVerifiedReceiver extends RadarVerifiedReceiver { @Override @@ -1483,12 +1461,12 @@ public void onTokenUpdated(Context context, RadarVerifiedLocationToken token) { } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("token", token.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized (lock) { + synchronized(lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1508,7 +1486,7 @@ public void run() { public void attachListeners(MethodCall call, Result result) { SharedPreferences sharedPrefs = mContext.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackDispatcherHandle = ((Number) call.argument("callbackDispatcherHandle")).longValue(); + long callbackDispatcherHandle = ((Number)call.argument("callbackDispatcherHandle")).longValue(); sharedPrefs.edit().putLong(CALLBACK_DISPATCHER_HANDLE_KEY, callbackDispatcherHandle).commit(); result.success(true); } @@ -1523,7 +1501,7 @@ public void detachListeners(MethodCall call, Result result) { public void on(MethodCall call, Result result) { SharedPreferences sharedPrefs = mContext.getSharedPreferences(TAG, Context.MODE_PRIVATE); String listener = call.argument("listener"); - long callbackHandle = ((Number) call.argument("callbackHandle")).longValue(); + long callbackHandle = ((Number)call.argument("callbackHandle")).longValue(); sharedPrefs.edit().putLong(listener, callbackHandle).commit(); result.success(true); } From 8f8deca3b8d5691216e154fb7df38f8621adbffe Mon Sep 17 00:00:00 2001 From: KennyHuRadar <139801512+KennyHuRadar@users.noreply.github.com> Date: Thu, 18 Jul 2024 16:28:03 -0400 Subject: [PATCH 10/16] Foreground tracking into version bump (#57) * added foreground location tracking * added back accidental deletion * added nil checks * fixed foreground handler only called when a background handler existed as well * added foreground location passing in android * little restructure * removed log * remove old listerns and replace them with new format * remove attach listern from example --------- Co-authored-by: Parker Stromberg --- .../io/radar/flutter/RadarFlutterPlugin.java | 193 +++++------------ example/lib/main.dart | 2 - ios/Classes/RadarFlutterPlugin.m | 109 ++-------- lib/flutter_radar.dart | 195 ++++++++---------- 4 files changed, 152 insertions(+), 347 deletions(-) diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index 266776f..66cf30f 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -77,40 +77,19 @@ public class RadarFlutterPlugin implements FlutterPlugin, MethodCallHandler, Act private static final String TAG = "RadarFlutterPlugin"; private static final String CALLBACK_DISPATCHER_HANDLE_KEY = "callbackDispatcherHandle"; private static MethodChannel sBackgroundChannel; + private MethodChannel channel; private static final Object lock = new Object(); private static final int PERMISSIONS_REQUEST_CODE = 20160525; private Result mPermissionsRequestResult; - private static void initializeBackgroundEngine(Context context) { - synchronized(lock) { - if (sBackgroundFlutterEngine == null) { - FlutterMain.startInitialization(context.getApplicationContext()); - FlutterMain.ensureInitializationComplete(context.getApplicationContext(), null); - - SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackDispatcherHandle = sharedPrefs.getLong(CALLBACK_DISPATCHER_HANDLE_KEY, 0); - if (callbackDispatcherHandle == 0) { - Log.e(TAG, "Error looking up callback dispatcher handle"); - return; - } - - FlutterCallbackInformation callbackInfo = FlutterCallbackInformation.lookupCallbackInformation(callbackDispatcherHandle); - sBackgroundFlutterEngine = new FlutterEngine(context.getApplicationContext()); - - DartCallback callback = new DartCallback(context.getAssets(), FlutterMain.findAppBundlePath(context), callbackInfo); - sBackgroundFlutterEngine.getDartExecutor().executeDartCallback(callback); - sBackgroundChannel = new MethodChannel(sBackgroundFlutterEngine.getDartExecutor().getBinaryMessenger(), "flutter_radar_background"); - } - } - } - @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { - Radar.setReceiver(new RadarFlutterReceiver()); mContext = binding.getApplicationContext(); - MethodChannel channel = new MethodChannel(binding.getFlutterEngine().getDartExecutor(), "flutter_radar"); + channel = new MethodChannel(binding.getFlutterEngine().getDartExecutor(), "flutter_radar"); + Radar.setReceiver(new RadarFlutterReceiver(channel)); + Radar.setVerifiedReceiver(new RadarFlutterVerifiedReceiver(channel)); channel.setMethodCallHandler(this); } @@ -300,18 +279,6 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) case "validateAddress": validateAddress(call, result); break; - case "attachListeners": - attachListeners(call, result); - break; - case "detachListeners": - detachListeners(call, result); - break; - case "on": - on(call, result); - break; - case "off": - off(call, result); - break; default: result.notImplemented(); break; @@ -328,6 +295,8 @@ private void initialize(MethodCall call, Result result) { editor.putString("x_platform_sdk_version", "3.10.0"); editor.apply(); Radar.initialize(mContext, publishableKey); + Radar.setReceiver(new RadarFlutterReceiver(channel)); + Radar.setVerifiedReceiver(new RadarFlutterVerifiedReceiver(channel)); result.success(true); } @@ -1282,31 +1251,28 @@ private JSONObject jsonForMap(HashMap map) throws JSONException { public static class RadarFlutterReceiver extends RadarReceiver { + private MethodChannel channel; + + RadarFlutterReceiver(MethodChannel channel) { + this.channel = channel; + } + @Override public void onEventsReceived(Context context, RadarEvent[] events, RadarUser user) { try { - SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("events", 0L); - - if (callbackHandle == 0L) { - return; - } - - RadarFlutterPlugin.initializeBackgroundEngine(context); - JSONObject obj = new JSONObject(); obj.put("events", RadarEvent.toJson(events)); obj.put("user", user.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); + final ArrayList eventsArgs = new ArrayList(); + eventsArgs.add(0); + eventsArgs.add(res); synchronized(lock) { - final ArrayList args = new ArrayList(); - args.add(callbackHandle); - args.add(res); runOnMainThread(new Runnable() { @Override public void run() { - sBackgroundChannel.invokeMethod("", args); + channel.invokeMethod("events", eventsArgs); } }); } @@ -1318,29 +1284,20 @@ public void run() { @Override public void onLocationUpdated(Context context, Location location, RadarUser user) { try { - SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("location", 0L); - - if (callbackHandle == 0L) { - Log.e(TAG, "callback handle is empty"); - return; - } - - RadarFlutterPlugin.initializeBackgroundEngine(context); - JSONObject obj = new JSONObject(); obj.put("location", Radar.jsonForLocation(location)); obj.put("user", user.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); + + final ArrayList locationArgs = new ArrayList(); + locationArgs.add(0); + locationArgs.add(res); synchronized(lock) { - final ArrayList args = new ArrayList(); - args.add(callbackHandle); - args.add(res); runOnMainThread(new Runnable() { @Override public void run() { - sBackgroundChannel.invokeMethod("", args); + channel.invokeMethod("location", locationArgs); } }); } @@ -1352,29 +1309,21 @@ public void run() { public void onClientLocationUpdated(Context context, Location location, boolean stopped, Radar.RadarLocationSource source) { try { - SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("clientLocation", 0L); - - if (callbackHandle == 0L) { - return; - } - - RadarFlutterPlugin.initializeBackgroundEngine(context); - JSONObject obj = new JSONObject(); obj.put("location", Radar.jsonForLocation(location)); obj.put("stopped", stopped); obj.put("source", source.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { - final ArrayList args = new ArrayList(); - args.add(callbackHandle); - args.add(res); + + final ArrayList clientLocationArgs = new ArrayList(); + clientLocationArgs.add(0); + clientLocationArgs.add(res); + synchronized(lock){ runOnMainThread(new Runnable() { @Override public void run() { - sBackgroundChannel.invokeMethod("", args); + channel.invokeMethod("clientLocation", clientLocationArgs); } }); } @@ -1386,27 +1335,18 @@ public void run() { @Override public void onError(Context context, Radar.RadarStatus status) { try { - SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("error", 0L); - - if (callbackHandle == 0L) { - return; - } - - RadarFlutterPlugin.initializeBackgroundEngine(context); - JSONObject obj = new JSONObject(); obj.put("status", status.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { - final ArrayList args = new ArrayList(); - args.add(callbackHandle); - args.add(res); + final ArrayList errorArgs = new ArrayList(); + errorArgs.add(0); + errorArgs.add(res); + synchronized(lock){ runOnMainThread(new Runnable() { @Override public void run() { - sBackgroundChannel.invokeMethod("", args); + channel.invokeMethod("error", errorArgs); } }); } @@ -1418,27 +1358,18 @@ public void run() { @Override public void onLog(Context context, String message) { try { - SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("log", 0L); - - if (callbackHandle == 0L) { - return; - } - - RadarFlutterPlugin.initializeBackgroundEngine(context); - JSONObject obj = new JSONObject(); obj.put("message", message); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); + final ArrayList logArgs = new ArrayList(); + logArgs.add(0); + logArgs.add(res); synchronized(lock) { - final ArrayList args = new ArrayList(); - args.add(callbackHandle); - args.add(res); runOnMainThread(new Runnable() { @Override public void run() { - sBackgroundChannel.invokeMethod("", args); + channel.invokeMethod("log", logArgs); } }); } @@ -1450,33 +1381,32 @@ public void run() { public static class RadarFlutterVerifiedReceiver extends RadarVerifiedReceiver { + private MethodChannel channel; + + RadarFlutterVerifiedReceiver(MethodChannel channel) { + this.channel = channel; + } + @Override public void onTokenUpdated(Context context, RadarVerifiedLocationToken token) { try { - SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackHandle = sharedPrefs.getLong("token", 0L); - - if (callbackHandle == 0L) { - return; - } - - RadarFlutterPlugin.initializeBackgroundEngine(context); JSONObject obj = new JSONObject(); obj.put("token", token.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); + final ArrayList tokenArgs = new ArrayList(); + tokenArgs.add(0); + tokenArgs.add(res); synchronized(lock) { - final ArrayList args = new ArrayList(); - args.add(callbackHandle); - args.add(res); runOnMainThread(new Runnable() { @Override public void run() { - sBackgroundChannel.invokeMethod("", args); + channel.invokeMethod("token", tokenArgs); } }); } + } catch (Exception e) { Log.e(TAG, e.toString()); } @@ -1484,33 +1414,4 @@ public void run() { } - public void attachListeners(MethodCall call, Result result) { - SharedPreferences sharedPrefs = mContext.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackDispatcherHandle = ((Number)call.argument("callbackDispatcherHandle")).longValue(); - sharedPrefs.edit().putLong(CALLBACK_DISPATCHER_HANDLE_KEY, callbackDispatcherHandle).commit(); - result.success(true); - } - - public void detachListeners(MethodCall call, Result result) { - SharedPreferences sharedPrefs = mContext.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackDispatcherHandle = call.argument("callbackDispatcherHandle"); - sharedPrefs.edit().putLong(CALLBACK_DISPATCHER_HANDLE_KEY, 0L).commit(); - result.success(true); - } - - public void on(MethodCall call, Result result) { - SharedPreferences sharedPrefs = mContext.getSharedPreferences(TAG, Context.MODE_PRIVATE); - String listener = call.argument("listener"); - long callbackHandle = ((Number)call.argument("callbackHandle")).longValue(); - sharedPrefs.edit().putLong(listener, callbackHandle).commit(); - result.success(true); - } - - public void off(MethodCall call, Result result) { - SharedPreferences sharedPrefs = mContext.getSharedPreferences(TAG, Context.MODE_PRIVATE); - String listener = call.argument("listener"); - sharedPrefs.edit().putLong(listener, 0L).commit(); - result.success(true); - } - }; diff --git a/example/lib/main.dart b/example/lib/main.dart index fc5f88d..b56d490 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -75,8 +75,6 @@ class _MyAppState extends State with WidgetsBindingObserver { Radar.setLogLevel('info'); Radar.setAnonymousTrackingEnabled(false); - Radar.attachListeners(); - Radar.onLocation(onLocation); Radar.onClientLocation(onClientLocation); Radar.onError(onError); diff --git a/ios/Classes/RadarFlutterPlugin.m b/ios/Classes/RadarFlutterPlugin.m index c505483..28941e8 100644 --- a/ios/Classes/RadarFlutterPlugin.m +++ b/ios/Classes/RadarFlutterPlugin.m @@ -129,15 +129,7 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { } else if ([@"isUsingRemoteTrackingOptions" isEqualToString:call.method]) { [self isUsingRemoteTrackingOptions:call withResult:result]; } else if ([@"validateAddress" isEqualToString:call.method]) { - [self validateAddress:call withResult:result]; - } else if ([@"attachListeners" isEqualToString:call.method]) { - [self attachListeners:call withResult:result]; - } else if ([@"detachListeners" isEqualToString:call.method]) { - [self detachListeners:call withResult:result]; - } else if ([@"on" isEqualToString:call.method]) { - [self on:call withResult:result]; - } else if ([@"off" isEqualToString:call.method]) { - [self off:call withResult:result]; + [self validateAddress:call withResult:result]; } else { result(FlutterMethodNotImplemented); } @@ -1012,111 +1004,52 @@ - (void)validateAddress:(FlutterMethodCall *)call withResult:(FlutterResult)resu [Radar validateAddress:address completionHandler:completionHandler]; } --(void)attachListeners:(FlutterMethodCall *)call withResult:(FlutterResult)result { - NSNumber* callbackDispatcherHandle = call.arguments[@"callbackDispatcherHandle"]; - - // Retrieve the callback information - FlutterCallbackInformation *callbackInfo = [FlutterCallbackCache lookupCallbackInformation:[callbackDispatcherHandle longValue]]; - - // Create the background Flutter engine - FlutterEngine *sBackgroundFlutterEngine; - sBackgroundFlutterEngine = [[FlutterEngine alloc] init]; - self.sBackgroundFlutterEngine = sBackgroundFlutterEngine; - - FlutterMethodChannel *backgroundChannel = [FlutterMethodChannel methodChannelWithName:@"flutter_radar_background" binaryMessenger:[sBackgroundFlutterEngine binaryMessenger]]; - self.backgroundChannel = backgroundChannel; - - [self.sBackgroundFlutterEngine runWithEntrypoint:callbackInfo.callbackName libraryURI: callbackInfo.callbackLibraryPath] ; - result(nil); -} - --(void)detachListeners:(FlutterMethodCall *)call withResult:(FlutterResult)result { - self.backgroundChannel = nil; - result(nil); -} - --(void)on:(FlutterMethodCall *)call withResult:(FlutterResult)result { - NSDictionary *argsDict = call.arguments; - NSString* listener = argsDict[@"listener"]; - NSNumber *callbackHandleNumber = argsDict[@"callbackHandle"]; - long callbackHandle = [callbackHandleNumber longValue]; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:callbackHandleNumber forKey:listener]; - result(nil); -} - --(void)off:(FlutterMethodCall *)call withResult:(FlutterResult)result { - NSDictionary *argsDict = call.arguments; - NSString* listener = argsDict[@"listener"]; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setObject:nil forKey:listener]; - result(nil); -} - - (void)didReceiveEvents:(NSArray *)events user:(RadarUser *)user { NSDictionary *dict = @{@"events": [RadarEvent arrayForEvents:events], @"user": user ? [user dictionaryValue] : @""}; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSInteger callbackHandle = [userDefaults integerForKey:@"events"]; - if (callbackHandle == 0) { - return; + NSArray* args = @[@0, dict]; + if (self.channel != nil) { + [self.channel invokeMethod:@"events" arguments:args]; } - NSArray* args = @[[NSNumber numberWithInteger:callbackHandle], dict]; - [self.backgroundChannel invokeMethod:@"" arguments:args]; } - (void)didUpdateLocation:(CLLocation *)location user:(RadarUser *)user { NSDictionary *dict = @{@"location": [Radar dictionaryForLocation:location], @"user": [user dictionaryValue]}; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSInteger callbackHandle = [userDefaults integerForKey:@"location"]; - if (callbackHandle == 0) { - return; + NSArray* args = @[@0, dict]; + if (self.channel != nil) { + [self.channel invokeMethod:@"location" arguments:args]; } - NSArray* args = @[[NSNumber numberWithInteger:callbackHandle], dict]; - [self.backgroundChannel invokeMethod:@"" arguments:args]; } - (void)didUpdateClientLocation:(CLLocation *)location stopped:(BOOL)stopped source:(RadarLocationSource)source { NSDictionary *dict = @{@"location": [Radar dictionaryForLocation:location], @"stopped": @(stopped), @"source": [Radar stringForLocationSource:source]}; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSInteger callbackHandle = [userDefaults integerForKey:@"clientLocation"]; - if (callbackHandle == 0) { - return; + NSArray* args = @[@0, dict]; + if (self.channel != nil) { + [self.channel invokeMethod:@"clientLocation" arguments:args]; } - NSArray* args = @[[NSNumber numberWithInteger:callbackHandle], dict]; - [self.backgroundChannel invokeMethod:@"" arguments:args]; } - (void)didFailWithStatus:(RadarStatus)status { NSDictionary *dict = @{@"status": [Radar stringForStatus:status]}; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSInteger callbackHandle = [userDefaults integerForKey:@"error"]; - if (callbackHandle == 0) { - return; + NSArray* args = @[@0, dict]; + if (self.channel != nil) { + [self.channel invokeMethod:@"error" arguments:args]; } - NSArray* args = @[[NSNumber numberWithInteger:callbackHandle], dict]; - [self.backgroundChannel invokeMethod:@"" arguments:args]; } - (void)didLogMessage:(NSString *)message { NSDictionary *dict = @{@"message": message}; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSNumber* callbackHandle = [userDefaults objectForKey:@"log"]; - if (callbackHandle == 0) { - return; + NSArray* args = @[@0, dict]; + if (self.channel != nil) { + [self.channel invokeMethod:@"log" arguments:args]; } - NSArray* args = @[callbackHandle, dict]; - [self.backgroundChannel invokeMethod:@"" arguments:args]; } -- (void)didUpdateToken:(RadarVerifiedLocationToken *)token { - NSDictionary *dict = [token dictionaryValue]; - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSNumber* callbackHandle = [userDefaults objectForKey:@"token"]; - if (callbackHandle == 0) { - return; +- (void)didUpdateToken:(NSString *)token { + NSDictionary *dict = @{@"token": token}; + NSArray* args = @[@0, dict]; + if (self.channel != nil) { + [self.channel invokeMethod:@"token" arguments:args]; } - NSArray* args = @[callbackHandle, dict]; - [self.backgroundChannel invokeMethod:@"" arguments:args]; } @end diff --git a/lib/flutter_radar.dart b/lib/flutter_radar.dart index 7eabb41..2477bd0 100644 --- a/lib/flutter_radar.dart +++ b/lib/flutter_radar.dart @@ -20,35 +20,59 @@ void callbackDispatcher() { }); } +typedef LocationCallback = void Function(Map locationEvent); +typedef ClientLocationCallback = void Function( + Map locationEvent, +); +typedef ErrorCallback = void Function(Map errorEvent); +typedef LogCallback = void Function(Map logEvent); +typedef EventsCallback = void Function(Map eventsEvent); +typedef TokenCallback = void Function(Map tokenEvent); + class Radar { static const MethodChannel _channel = const MethodChannel('flutter_radar'); + static LocationCallback? foregroundLocationCallback; + static ClientLocationCallback? foregroundClientLocationCallback; + static ErrorCallback? foregroundErrorCallback; + static LogCallback? foregroundLogCallback; + static EventsCallback? foregroundEventsCallback; + static TokenCallback? foregroundTokenCallback; + static Future initialize(String publishableKey) async { try { await _channel.invokeMethod('initialize', { 'publishableKey': publishableKey, }); + _channel.setMethodCallHandler(_handleMethodCall); } on PlatformException catch (e) { print(e); } } - static attachListeners() async { - try { - await _channel.invokeMethod('attachListeners', { - 'callbackDispatcherHandle': - PluginUtilities.getCallbackHandle(callbackDispatcher)?.toRawHandle() - }); - } on PlatformException catch (e) { - print(e); - } - } - - static Future detachListeners() async { - try { - await _channel.invokeMethod('detachListeners'); - } on PlatformException catch (e) { - print(e); + static Future _handleMethodCall(MethodCall call) async { + final args = call.arguments; + switch (call.method) { + case 'location': + foregroundLocationCallback?.call(args[1] as Map); + break; + case 'clientLocation': + foregroundClientLocationCallback?.call( + args[1] as Map, + ); + break; + case 'error': + foregroundErrorCallback?.call(args[1] as Map); + break; + case 'log': + foregroundLogCallback?.call(args[1] as Map); + break; + case 'events': + foregroundEventsCallback?.call(args[1] as Map); + break; + case 'token': + foregroundTokenCallback?.call(args[1] as Map); + break; } } @@ -495,128 +519,70 @@ class Radar { } } - static Future requestForegroundLocationPermission() async { - try { - await _channel.invokeMethod('requestForegroundLocationPermission'); - } on PlatformException catch (e) { - print(e); + static onLocation(LocationCallback callback) { + if (foregroundLocationCallback != null) { + throw RadarExistingCallbackException(); } + foregroundLocationCallback = callback; } - static onLocation(Function(Map res) callback) async { - try { - final CallbackHandle handle = - PluginUtilities.getCallbackHandle(callback)!; - await _channel.invokeMethod('on', - {'listener': 'location', 'callbackHandle': handle.toRawHandle()}); - } on PlatformException catch (e) { - print(e); - } + static offLocation() { + foregroundLocationCallback = null; } - static offLocation() async { - try { - await _channel.invokeMethod('off', {'listener': 'location'}); - } on PlatformException catch (e) { - print(e); + static void onClientLocation(ClientLocationCallback callback) { + if (foregroundClientLocationCallback != null) { + throw RadarExistingCallbackException(); } + foregroundClientLocationCallback = callback; } - static onClientLocation(Function(Map res) callback) async { - try { - final CallbackHandle handle = - PluginUtilities.getCallbackHandle(callback)!; - await _channel.invokeMethod('on', { - 'listener': 'clientLocation', - 'callbackHandle': handle.toRawHandle() - }); - } on PlatformException catch (e) { - print(e); - } - } - - static offClientLocation() async { - try { - await _channel.invokeMethod('off', {'listener': 'clientLocation'}); - } on PlatformException catch (e) { - print(e); - } + static offClientLocation() { + foregroundClientLocationCallback = null; } - static onError(Function(Map res) callback) async { - try { - final CallbackHandle handle = - PluginUtilities.getCallbackHandle(callback)!; - await _channel.invokeMethod( - 'on', {'listener': 'error', 'callbackHandle': handle.toRawHandle()}); - } on PlatformException catch (e) { - print(e); + static onError(ErrorCallback callback) { + if (foregroundErrorCallback != null) { + throw RadarExistingCallbackException(); } + foregroundErrorCallback = callback; } - static offError() async { - try { - await _channel.invokeMethod('off', {'listener': 'error'}); - } on PlatformException catch (e) { - print(e); - } + static offError() { + foregroundErrorCallback = null; } - static onLog(Function(Map res) callback) async { - try { - final CallbackHandle handle = - PluginUtilities.getCallbackHandle(callback)!; - await _channel.invokeMethod( - 'on', {'listener': 'log', 'callbackHandle': handle.toRawHandle()}); - } on PlatformException catch (e) { - print(e); + static onLog(LogCallback callback) { + if (foregroundLogCallback != null) { + throw RadarExistingCallbackException(); } + foregroundLogCallback = callback; } - static offLog() async { - try { - await _channel.invokeMethod('off', {'listener': 'log'}); - } on PlatformException catch (e) { - print(e); - } + static offLog() { + foregroundLogCallback = null; } - - static onEvents(Function(Map res) callback) async { - try { - final CallbackHandle handle = - PluginUtilities.getCallbackHandle(callback)!; - await _channel.invokeMethod( - 'on', {'listener': 'events', 'callbackHandle': handle.toRawHandle()}); - } on PlatformException catch (e) { - print(e); + + static onEvents(EventsCallback callback) { + if (foregroundEventsCallback != null) { + throw RadarExistingCallbackException(); } + foregroundEventsCallback = callback; } - static offEvents() async { - try { - await _channel.invokeMethod('off', {'listener': 'events'}); - } on PlatformException catch (e) { - print(e); - } + static offEvents() { + foregroundEventsCallback = null; } - static onToken(Function(Map res) callback) async { - try { - final CallbackHandle handle = - PluginUtilities.getCallbackHandle(callback)!; - await _channel.invokeMethod( - 'on', {'listener': 'token', 'callbackHandle': handle.toRawHandle()}); - } on PlatformException catch (e) { - print(e); + static onToken(TokenCallback callback) { + if (foregroundTokenCallback != null) { + throw RadarExistingCallbackException(); } + foregroundTokenCallback = callback; } - static offToken() async { - try { - await _channel.invokeMethod('off', {'listener': 'token'}); - } on PlatformException catch (e) { - print(e); - } + static offToken() { + foregroundTokenCallback = null; } static Map presetContinuousIOS = { @@ -761,3 +727,10 @@ class Radar { static Map presetEfficient = Platform.isIOS ? presetEfficientIOS : presetEfficientAndroid; } + +class RadarExistingCallbackException implements Exception { + @override + String toString() { + return 'Existing callback already exists for this event. Please call the corresponding `off` method first.'; + } +} From c15ab463d5746497126c612d3a1d4e1a1c3473f5 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 18 Jul 2024 16:31:06 -0400 Subject: [PATCH 11/16] add beta version --- android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java | 2 +- ios/Classes/RadarFlutterPlugin.m | 2 +- ios/flutter_radar.podspec | 2 +- pubspec.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index 66cf30f..26289d7 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -292,7 +292,7 @@ private void initialize(MethodCall call, Result result) { String publishableKey = call.argument("publishableKey"); SharedPreferences.Editor editor = mContext.getSharedPreferences("RadarSDK", Context.MODE_PRIVATE).edit(); editor.putString("x_platform_sdk_type", "Flutter"); - editor.putString("x_platform_sdk_version", "3.10.0"); + editor.putString("x_platform_sdk_version", "3.10.0-beta.1"); editor.apply(); Radar.initialize(mContext, publishableKey); Radar.setReceiver(new RadarFlutterReceiver(channel)); diff --git a/ios/Classes/RadarFlutterPlugin.m b/ios/Classes/RadarFlutterPlugin.m index 28941e8..fd6a396 100644 --- a/ios/Classes/RadarFlutterPlugin.m +++ b/ios/Classes/RadarFlutterPlugin.m @@ -140,7 +140,7 @@ - (void)initialize:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSString *publishableKey = argsDict[@"publishableKey"]; [[NSUserDefaults standardUserDefaults] setObject:@"Flutter" forKey:@"radar-xPlatformSDKType"]; - [[NSUserDefaults standardUserDefaults] setObject:@"3.10.0" forKey:@"radar-xPlatformSDKVersion"]; + [[NSUserDefaults standardUserDefaults] setObject:@"3.10.0-beta.1" forKey:@"radar-xPlatformSDKVersion"]; [Radar initializeWithPublishableKey:publishableKey]; result(nil); } diff --git a/ios/flutter_radar.podspec b/ios/flutter_radar.podspec index 9749451..87e11ed 100644 --- a/ios/flutter_radar.podspec +++ b/ios/flutter_radar.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'flutter_radar' - s.version = '3.10.0' + s.version = '3.10.0-beta.1' s.summary = 'Flutter package for Radar, the leading geofencing and location tracking platform' s.description = 'Flutter package for Radar, the leading geofencing and location tracking platform' s.homepage = 'http://example.com' diff --git a/pubspec.yaml b/pubspec.yaml index 2b48bb1..8a5baa5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_radar description: Flutter package for Radar, the leading geofencing and location tracking platform -version: 3.10.0 +version: 3.10.0-beta.1 homepage: https://github.com/radarlabs/flutter-radar environment: From c920ec2af679667c6f097e2040e2fcda46b21568 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 18 Jul 2024 16:34:11 -0400 Subject: [PATCH 12/16] add beta chagnelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3a6f19..92c9114 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 3.10.0 +# 3.10.0-beta.1 - Bump iOS version from 3.9.14 to 3.15.0 - Bump Android version from 3.9.8 to 3.15.0 From bda047a8eb210e0eadae2eee41cdb5c81e0074e4 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 18 Jul 2024 16:40:41 -0400 Subject: [PATCH 13/16] env sdk version --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 8a5baa5..ed958f9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 3.10.0-beta.1 homepage: https://github.com/radarlabs/flutter-radar environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.12.0 <4.0.0' flutter: ">=1.20.0" dependencies: From 8222a2775b8468defd71fbefab245bf009579762 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 18 Jul 2024 16:48:21 -0400 Subject: [PATCH 14/16] change to future void --- lib/flutter_radar.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/flutter_radar.dart b/lib/flutter_radar.dart index 2477bd0..8d4cdac 100644 --- a/lib/flutter_radar.dart +++ b/lib/flutter_radar.dart @@ -50,7 +50,7 @@ class Radar { } } - static Future _handleMethodCall(MethodCall call) async { + static Future _handleMethodCall(MethodCall call) async { final args = call.arguments; switch (call.method) { case 'location': From c2385b0d9fdae2bcf91e31006afa7181b6e43639 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 22 Jul 2024 12:23:39 -0400 Subject: [PATCH 15/16] change interface and add safe unwrapping --- .../io/radar/flutter/RadarFlutterPlugin.java | 427 +++++++---- example/lib/main.dart | 712 +++++++++--------- ios/Classes/RadarFlutterPlugin.m | 297 ++++---- lib/flutter_radar.dart | 119 +-- 4 files changed, 861 insertions(+), 694 deletions(-) diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index 266776f..6507ceb 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -21,6 +21,7 @@ import org.json.JSONObject; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Array; import java.util.ArrayList; import java.util.EnumSet; import java.util.HashMap; @@ -67,7 +68,8 @@ import io.flutter.view.FlutterRunArguments; import io.flutter.view.FlutterCallbackInformation; -public class RadarFlutterPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware, RequestPermissionsResultListener { +public class RadarFlutterPlugin + implements FlutterPlugin, MethodCallHandler, ActivityAware, RequestPermissionsResultListener { private static FlutterEngine sBackgroundFlutterEngine; @@ -82,9 +84,9 @@ public class RadarFlutterPlugin implements FlutterPlugin, MethodCallHandler, Act private static final int PERMISSIONS_REQUEST_CODE = 20160525; private Result mPermissionsRequestResult; - + private static void initializeBackgroundEngine(Context context) { - synchronized(lock) { + synchronized (lock) { if (sBackgroundFlutterEngine == null) { FlutterMain.startInitialization(context.getApplicationContext()); FlutterMain.ensureInitializationComplete(context.getApplicationContext(), null); @@ -96,12 +98,15 @@ private static void initializeBackgroundEngine(Context context) { return; } - FlutterCallbackInformation callbackInfo = FlutterCallbackInformation.lookupCallbackInformation(callbackDispatcherHandle); + FlutterCallbackInformation callbackInfo = FlutterCallbackInformation + .lookupCallbackInformation(callbackDispatcherHandle); sBackgroundFlutterEngine = new FlutterEngine(context.getApplicationContext()); - DartCallback callback = new DartCallback(context.getAssets(), FlutterMain.findAppBundlePath(context), callbackInfo); + DartCallback callback = new DartCallback(context.getAssets(), FlutterMain.findAppBundlePath(context), + callbackInfo); sBackgroundFlutterEngine.getDartExecutor().executeDartCallback(callback); - sBackgroundChannel = new MethodChannel(sBackgroundFlutterEngine.getDartExecutor().getBinaryMessenger(), "flutter_radar_background"); + sBackgroundChannel = new MethodChannel(sBackgroundFlutterEngine.getDartExecutor().getBinaryMessenger(), + "flutter_radar_background"); } } } @@ -249,6 +254,12 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) case "cancelTrip": cancelTrip(result); break; + case "acceptEvent": + acceptEvent(call, result); + break; + case "rejectEvent": + rejectEvent(call, result); + break; case "getContext": getContext(call, result); break; @@ -260,7 +271,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) break; case "autocomplete": autocomplete(call, result); - break; + break; case "forwardGeocode": geocode(call, result); break; @@ -321,18 +332,103 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull final Result result) } } + private String getStringFromMethodCall(MethodCall call, String key) { + try { + final Map arguments = call.arguments(); + if (arguments.containsKey(key)) { + Object value = arguments.get(key); + if (value instanceof String) { + return (String) value; // Return the string value if it exists and is a string + } + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + return null; // Return null if the key does not exist or is not a string + } + + private boolean getBooleanFromMethodCall(MethodCall call, String key, boolean defaultValue) { + try { + final Map arguments = call.arguments(); + if (arguments.containsKey(key)) { + Object value = arguments.get(key); + if (value instanceof Boolean) { + return (Boolean) value; + } + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + return defaultValue; + } + + private HashMap getHashMapFromMethodCall(MethodCall call, String key) { + try { + final Map arguments = call.arguments(); + if (arguments.containsKey(key)) { + Object value = arguments.get(key); + if (value instanceof HashMap) { + return (HashMap) value; + } + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + return null; + } + + private int getIntFromMethodCall(MethodCall call, String key, int defaultValue) { + try { + final Map arguments = call.arguments(); + if (arguments.containsKey(key)) { + Object value = arguments.get(key); + if (value instanceof Integer) { + return (Integer) value; + } + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + return defaultValue; + } + + private ArrayList getArrayListFromMethodCall(MethodCall call, String key) { + try { + final Map arguments = call.arguments(); + if (arguments.containsKey(key)) { + Object value = arguments.get(key); + if (value instanceof ArrayList) { + return (ArrayList) value; + } + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } + return null; + } + + private String[] getStringArrayFromMethodCall(MethodCall call, String key) { + ArrayList list = getArrayListFromMethodCall(call, key); + if (list != null) { + return list.toArray(new String[0]); + } + return null; + } + private void initialize(MethodCall call, Result result) { - String publishableKey = call.argument("publishableKey"); + String publishableKey = getStringFromMethodCall(call, "publishableKey"); + boolean fraud = getBooleanFromMethodCall(call, "fraud", false); SharedPreferences.Editor editor = mContext.getSharedPreferences("RadarSDK", Context.MODE_PRIVATE).edit(); editor.putString("x_platform_sdk_type", "Flutter"); editor.putString("x_platform_sdk_version", "3.10.0"); editor.apply(); - Radar.initialize(mContext, publishableKey); + // need to init with fraud + Radar.initialize(mContext, publishableKey, null, Radar.RadarLocationServicesProvider.GOOGLE, fraud); result.success(true); } private void setNotificationOptions(MethodCall call, Result result) { - HashMap notificationOptionsMap = (HashMap)call.arguments; + HashMap notificationOptionsMap = (HashMap) call.arguments; JSONObject notificationOptionsJson = new JSONObject(notificationOptionsMap); RadarNotificationOptions options = RadarNotificationOptions.fromJson(notificationOptionsJson); Radar.setNotificationOptions(options); @@ -340,15 +436,16 @@ private void setNotificationOptions(MethodCall call, Result result) { } private void setForegroundServiceOptions(MethodCall call, Result result) { - HashMap foregroundServiceOptionsMap = (HashMap)call.arguments; + HashMap foregroundServiceOptionsMap = (HashMap) call.arguments; JSONObject foregroundServiceOptionsJson = new JSONObject(foregroundServiceOptionsMap); - RadarTrackingOptionsForegroundService options = RadarTrackingOptionsForegroundService.fromJson(foregroundServiceOptionsJson); + RadarTrackingOptionsForegroundService options = RadarTrackingOptionsForegroundService + .fromJson(foregroundServiceOptionsJson); Radar.setForegroundServiceOptions(options); result.success(true); } private void setLogLevel(MethodCall call, Result result) { - String logLevel = call.argument("logLevel"); + String logLevel = getStringFromMethodCall(call, "logLevel"); if (logLevel == null) { Radar.setLogLevel(Radar.RadarLogLevel.NONE); } else if (logLevel.equals("debug")) { @@ -365,20 +462,21 @@ private void setLogLevel(MethodCall call, Result result) { result.success(true); } - private void getPermissionStatus(Result result) { String status = "NOT_DETERMINED"; - + if (mActivity == null || result == null) { result.success(status); return; } - boolean foreground = ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; + boolean foreground = ActivityCompat.checkSelfPermission(mActivity, + Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; if (Build.VERSION.SDK_INT >= 29) { if (foreground) { - boolean background = ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED; + boolean background = ActivityCompat.checkSelfPermission(mActivity, + Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED; status = background ? "GRANTED_BACKGROUND" : "GRANTED_FOREGROUND"; } else { status = "DENIED"; @@ -391,21 +489,27 @@ private void getPermissionStatus(Result result) { } private void requestPermissions(MethodCall call, Result result) { - boolean background = call.argument("background"); + boolean background = getBooleanFromMethodCall(call, "background", false); mPermissionsRequestResult = result; if (mActivity != null) { if (Build.VERSION.SDK_INT >= 23) { if (background && Build.VERSION.SDK_INT >= 29) { - ActivityCompat.requestPermissions(mActivity, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION }, PERMISSIONS_REQUEST_CODE); + ActivityCompat.requestPermissions(mActivity, + new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_BACKGROUND_LOCATION }, + PERMISSIONS_REQUEST_CODE); } else { - ActivityCompat.requestPermissions(mActivity, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }, PERMISSIONS_REQUEST_CODE); + ActivityCompat.requestPermissions(mActivity, new String[] { + Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }, + PERMISSIONS_REQUEST_CODE); } } } } private void setUserId(MethodCall call, Result result) { - String userId = call.argument("userId"); + String userId = getStringFromMethodCall(call, "userId"); Radar.setUserId(userId); result.success(true); } @@ -416,7 +520,7 @@ private void getUserId(Result result) { } private void setDescription(MethodCall call, Result result) { - String description = call.argument("description"); + String description = getStringFromMethodCall(call, "description"); Radar.setDescription(description); result.success(true); } @@ -427,7 +531,7 @@ private void getDescription(Result result) { } private void setMetadata(MethodCall call, Result result) { - HashMap metadataMap = (HashMap)call.arguments; + HashMap metadataMap = (HashMap) call.arguments; JSONObject metadata = new JSONObject(metadataMap); Radar.setMetadata(metadata); result.success(true); @@ -437,13 +541,13 @@ private void getMetadata(Result result) { JSONObject metadata = Radar.getMetadata(); HashMap metadataMap = null; if (metadata != null) { - metadataMap = new Gson().fromJson(metadata.toString(), HashMap.class); + metadataMap = new Gson().fromJson(metadata.toString(), HashMap.class); } result.success(metadataMap); } private void setAnonymousTrackingEnabled(MethodCall call, Result result) { - boolean enabled = call.argument("enabled"); + boolean enabled = getBooleanFromMethodCall(call, "enabled", false); Radar.setAnonymousTrackingEnabled(enabled); result.success(true); } @@ -473,7 +577,7 @@ public void run() { } }; - String accuracy = call.argument("accuracy"); + String accuracy = getStringFromMethodCall(call, "accuracy"); if (accuracy == null) { Radar.getLocation(callback); } else if (accuracy.equals("high")) { @@ -490,7 +594,8 @@ public void run() { private void trackOnce(MethodCall call, final Result result) { Radar.RadarTrackCallback callback = new Radar.RadarTrackCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final Location location, final RadarEvent[] events, final RadarUser user) { + public void onComplete(final Radar.RadarStatus status, final Location location, final RadarEvent[] events, + final RadarUser user) { runOnMainThread(new Runnable() { @Override public void run() { @@ -506,7 +611,7 @@ public void run() { if (user != null) { obj.put("user", user.toJson()); } - + HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); result.success(map); } catch (Exception e) { @@ -516,37 +621,31 @@ public void run() { }); } }; - - if (call.hasArgument("location") && call.argument("location") != null) { - HashMap locationMap = (HashMap)call.argument("location"); + + HashMap locationMap = getHashMapFromMethodCall(call, "location"); + if (locationMap != null) { Location location = locationForMap(locationMap); Radar.trackOnce(location, callback); } else { RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.MEDIUM; - boolean beaconsTrackingOption = false; - - if (call.hasArgument("desiredAccuracy") && call.argument("desiredAccuracy") != null) { - String desiredAccuracy = ((String)call.argument("desiredAccuracy")).toLowerCase(); - if (desiredAccuracy.equals("none")) { - accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.NONE; - } else if (desiredAccuracy.equals("low")) { - accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.LOW; - } else if (desiredAccuracy.equals("medium")) { - accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.MEDIUM; - } else if (desiredAccuracy.equals("high")) { - accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.HIGH; - } - } - if (call.hasArgument("beacons") && call.argument("beacons") != null) { - beaconsTrackingOption = call.argument("beacons"); + boolean beaconsTrackingOption = getBooleanFromMethodCall(call, "beacons", false); + String desiredAccuracy = (getStringFromMethodCall(call, "desiredAccuracy")).toLowerCase(); + if (desiredAccuracy.equals("none")) { + accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.NONE; + } else if (desiredAccuracy.equals("low")) { + accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.LOW; + } else if (desiredAccuracy.equals("medium")) { + accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.MEDIUM; + } else if (desiredAccuracy.equals("high")) { + accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.HIGH; } - + Radar.trackOnce(accuracyLevel, beaconsTrackingOption, callback); } - } + } private void startTracking(MethodCall call, Result result) { - String preset = call.argument("preset"); + String preset = getStringFromMethodCall(call, "preset"); if (preset == null) { Radar.startTracking(RadarTrackingOptions.RESPONSIVE); } else if (preset.equals("continuous")) { @@ -562,7 +661,7 @@ private void startTracking(MethodCall call, Result result) { } private void startTrackingCustom(MethodCall call, Result result) { - HashMap optionsMap = (HashMap)call.arguments; + HashMap optionsMap = (HashMap) call.arguments; JSONObject optionsJson = new JSONObject(optionsMap); RadarTrackingOptions options = RadarTrackingOptions.fromJson(optionsJson); Radar.startTracking(options); @@ -570,8 +669,8 @@ private void startTrackingCustom(MethodCall call, Result result) { } private void startTrackingVerified(MethodCall call, Result result) { - int interval = call.hasArgument("interval") && call.argument("interval") != null ? (int)call.argument("interval") : 1; - Boolean beacons = call.hasArgument("beacons") ? call.argument("beacons") : false; + int interval = getIntFromMethodCall(call, "interval", 1); + Boolean beacons = getBooleanFromMethodCall(call, "beacons", false); Radar.startTrackingVerified(interval, beacons); result.success(true); } @@ -582,11 +681,11 @@ private void stopTrackingVerified(MethodCall call, Result result) { } public void mockTracking(MethodCall call, final Result result) { - HashMap originMap = (HashMap)call.argument("origin"); + HashMap originMap = getHashMapFromMethodCall(call, "origin"); Location origin = locationForMap(originMap); - HashMap destinationMap = (HashMap)call.argument("destination"); + HashMap destinationMap = getHashMapFromMethodCall(call, "destination"); Location destination = locationForMap(destinationMap); - String modeStr = call.argument("mode"); + String modeStr = getStringFromMethodCall(call, "mode"); Radar.RadarRouteMode mode = Radar.RadarRouteMode.CAR; if (modeStr.equals("FOOT") || modeStr.equals("foot")) { mode = Radar.RadarRouteMode.FOOT; @@ -595,13 +694,13 @@ public void mockTracking(MethodCall call, final Result result) { } else if (modeStr.equals("CAR") || modeStr.equals("car")) { mode = Radar.RadarRouteMode.CAR; } - int steps = call.hasArgument("steps") ? (int)call.argument("steps") : 10; - int interval = call.hasArgument("interval") ? (int)call.argument("interval") : 1; + int steps = getIntFromMethodCall(call, "steps", 10); + int interval = getIntFromMethodCall(call, "interval", 1); Radar.mockTracking(origin, destination, mode, steps, interval, new Radar.RadarTrackCallback() { @Override public void onComplete(Radar.RadarStatus status, Location location, RadarEvent[] events, RadarUser user) { - + } }); } @@ -616,21 +715,21 @@ private void isTracking(Result result) { result.success(isTracking); } - private void getTrackingOptions(Result result) throws JSONException { - RadarTrackingOptions options = Radar.getTrackingOptions(); + private void getTrackingOptions(Result result) throws JSONException { + RadarTrackingOptions options = Radar.getTrackingOptions(); JSONObject optionsJson = options.toJson(); HashMap optionsMap = null; if (optionsJson != null) { - optionsMap = new Gson().fromJson(optionsJson.toString(), HashMap.class); + optionsMap = new Gson().fromJson(optionsJson.toString(), HashMap.class); } result.success(optionsMap); } public void startTrip(MethodCall call, Result result) throws JSONException { - HashMap tripOptionsMap = (HashMap)call.argument("tripOptions"); + HashMap tripOptionsMap = getHashMapFromMethodCall(call, "tripOptions"); JSONObject tripOptionsJson = jsonForMap(tripOptionsMap); RadarTripOptions tripOptions = RadarTripOptions.fromJson(tripOptionsJson); - HashMap trackingOptionsMap = (HashMap)call.argument("trackingOptions"); + HashMap trackingOptionsMap = getHashMapFromMethodCall(call, "trackingOptions"); JSONObject trackingOptionsJson = jsonForMap(trackingOptionsMap); RadarTrackingOptions trackingOptions = null; if (trackingOptionsJson != null) { @@ -639,8 +738,8 @@ public void startTrip(MethodCall call, Result result) throws JSONException { Radar.startTrip(tripOptions, trackingOptions, new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -666,10 +765,10 @@ public void run() { } public void updateTrip(MethodCall call, Result result) throws JSONException { - HashMap tripOptionsMap = (HashMap)call.argument("tripOptions"); + HashMap tripOptionsMap = getHashMapFromMethodCall(call, "tripOptions"); JSONObject tripOptionsJson = jsonForMap(tripOptionsMap); RadarTripOptions tripOptions = RadarTripOptions.fromJson(tripOptionsJson); - String statusStr = call.argument("status"); + String statusStr = getStringFromMethodCall(call, "status"); RadarTrip.RadarTripStatus status = RadarTrip.RadarTripStatus.UNKNOWN; statusStr = statusStr.toLowerCase(); if (statusStr.equals("started")) { @@ -683,12 +782,12 @@ public void updateTrip(MethodCall call, Result result) throws JSONException { } else if (statusStr.equals("canceled")) { status = RadarTrip.RadarTripStatus.CANCELED; } - + Radar.updateTrip(tripOptions, status, new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -715,7 +814,7 @@ public void run() { public void getTripOptions(Result result) { RadarTripOptions tripOptions = Radar.getTripOptions(); - HashMap map = new Gson().fromJson(tripOptions.toJson().toString(), HashMap.class); + HashMap map = new Gson().fromJson(tripOptions.toJson().toString(), HashMap.class); result.success(map); } @@ -723,8 +822,8 @@ public void completeTrip(Result result) { Radar.completeTrip(new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -753,8 +852,8 @@ public void cancelTrip(Result result) { Radar.cancelTrip(new Radar.RadarTripCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, - @Nullable RadarTrip trip, - @Nullable RadarEvent[] events) { + @Nullable RadarTrip trip, + @Nullable RadarEvent[] events) { runOnMainThread(new Runnable() { @Override public void run() { @@ -779,10 +878,24 @@ public void run() { }); } + public void acceptEvent(MethodCall call, Result result) { + String eventId = getStringFromMethodCall(call, "eventId"); + String verifiedPlaceId = getStringFromMethodCall(call, "verifiedPlaceId"); + Radar.acceptEvent(eventId, verifiedPlaceId); + result.success(true); + } + + public void rejectEvent(MethodCall call, Result result) { + String eventId = getStringFromMethodCall(call, "eventId"); + Radar.rejectEvent(eventId); + result.success(true); + } + public void getContext(MethodCall call, final Result result) { Radar.RadarContextCallback callback = new Radar.RadarContextCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final Location location, final RadarContext context) { + public void onComplete(final Radar.RadarStatus status, final Location location, + final RadarContext context) { runOnMainThread(new Runnable() { @Override public void run() { @@ -805,9 +918,8 @@ public void run() { }); } }; - - if (call.hasArgument("location")) { - HashMap locationMap = (HashMap)call.argument("location"); + HashMap locationMap = getHashMapFromMethodCall(call, "location"); + if (locationMap != null) { Location location = locationForMap(locationMap); Radar.getContext(location, callback); } else { @@ -818,7 +930,8 @@ public void run() { private void searchGeofences(MethodCall call, final Result result) throws JSONException { Radar.RadarSearchGeofencesCallback callback = new Radar.RadarSearchGeofencesCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final Location location, final RadarGeofence[] geofences) { + public void onComplete(final Radar.RadarStatus status, final Location location, + final RadarGeofence[] geofences) { runOnMainThread(new Runnable() { @Override public void run() { @@ -843,17 +956,17 @@ public void run() { }; Location near = null; - if (call.hasArgument("near")) { - HashMap nearMap = (HashMap)call.argument("near"); + HashMap nearMap = getHashMapFromMethodCall(call, "near"); + if (nearMap != null) { near = locationForMap(nearMap); } - int radius = call.hasArgument("radius") ? (int)call.argument("radius") : 1000; - ArrayList tagsList = (ArrayList)call.argument("tags"); - String[] tags = (String[])tagsList.toArray(new String[0]); - HashMap metadataMap = (HashMap)call.argument("metadata"); + int radius = getIntFromMethodCall(call, "radius", 1000); + + String[] tags = getStringArrayFromMethodCall(call, "tags"); + HashMap metadataMap = getHashMapFromMethodCall(call, "metadata"); JSONObject metadata = jsonForMap(metadataMap); - int limit = call.hasArgument("limit") ? (int)call.argument("limit") : 10; - boolean includeGeometry = call.hasArgument("includeGeometry") ? call.argument("includeGeometry") : false; + int limit = getIntFromMethodCall(call, "limit", 10); + boolean includeGeometry = getBooleanFromMethodCall(call, "includeGeometry", false); if (near != null) { Radar.searchGeofences(near, radius, tags, metadata, limit, includeGeometry, callback); @@ -890,19 +1003,16 @@ public void run() { }; Location near = null; - if (call.hasArgument("near")) { - HashMap nearMap = (HashMap)call.argument("near"); + HashMap nearMap = getHashMapFromMethodCall(call, "near"); + if (nearMap != null) { near = locationForMap(nearMap); } - int radius = call.hasArgument("radius") ? (int)call.argument("radius") : 1000; - ArrayList chainsList = (ArrayList)call.argument("chains"); - String[] chains = (String[])chainsList.toArray(new String[0]); - Map chainMetadata = (Map)call.argument("chainMetadata"); - ArrayList categoriesList = (ArrayList)call.argument("categories"); - String[] categories = categoriesList != null ? (String[])categoriesList.toArray(new String[0]) : new String[0]; - ArrayList groupsList = (ArrayList)call.argument("groups"); - String[] groups = groupsList != null ? (String[])groupsList.toArray(new String[0]) : new String[0]; - int limit = call.hasArgument("limit") ? (int)call.argument("limit") : 10; + int radius = getIntFromMethodCall(call, "radius", 1000); + String[] chains = getStringArrayFromMethodCall(call, "chains"); + Map chainMetadata = (Map) call.argument("chainMetadata"); + String[] categories = getStringArrayFromMethodCall(call, "categories"); + String[] groups = getStringArrayFromMethodCall(call, "groups"); + int limit = getIntFromMethodCall(call, "limit", 10); if (near != null) { Radar.searchPlaces(near, radius, chains, chainMetadata, categories, groups, limit, callback); @@ -912,14 +1022,13 @@ public void run() { } public void autocomplete(MethodCall call, final Result result) { - String query = call.argument("query"); - HashMap nearMap = (HashMap)call.argument("near"); + String query = getStringFromMethodCall(call, "query"); + HashMap nearMap = getHashMapFromMethodCall(call, "near"); Location near = locationForMap(nearMap); - int limit = call.hasArgument("limit") ? (int)call.argument("limit") : 10; - String country = call.argument("country"); - ArrayList layersList = (ArrayList)call.argument("layers"); - String[] layers = layersList != null ? (String[])layersList.toArray(new String[0]) : new String[0]; - Boolean mailable = call.argument("mailable"); + int limit = getIntFromMethodCall(call, "limit", 10); + String country = getStringFromMethodCall(call, "country"); + String[] layers = getStringArrayFromMethodCall(call, "layers"); + Boolean mailable = getBooleanFromMethodCall(call, "mailable", false); Radar.autocomplete(query, near, layers, limit, country, true, mailable, new Radar.RadarGeocodeCallback() { @Override @@ -946,9 +1055,9 @@ public void run() { } public void geocode(MethodCall call, final Result result) { - String query = call.argument("query"); + String query = getStringFromMethodCall(call, "query"); - Radar.geocode(query, null, null, new Radar.RadarGeocodeCallback() { + Radar.geocode(query, null, null, new Radar.RadarGeocodeCallback() { @Override public void onComplete(final Radar.RadarStatus status, final RadarAddress[] addresses) { runOnMainThread(new Runnable() { @@ -960,7 +1069,7 @@ public void run() { if (addresses != null) { obj.put("addresses", RadarAddress.toJson(addresses)); } - + HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); result.success(map); } catch (Exception e) { @@ -996,10 +1105,9 @@ public void run() { } }; - String[] layers = call.hasArgument("layers") && call.argument("layers") != null ? call.argument("layers") - : null; - if (call.hasArgument("location") && call.argument("location") != null) { - HashMap locationMap = (HashMap) call.argument("location"); + String[] layers = getStringArrayFromMethodCall(call, "layers"); + HashMap locationMap = getHashMapFromMethodCall(call, "location"); + if (locationMap != null) { Location location = locationForMap(locationMap); Radar.reverseGeocode(location, layers, callback); } else { @@ -1058,15 +1166,14 @@ public void run() { }; Location origin = null; + HashMap originMap = getHashMapFromMethodCall(call, "origin"); if (call.hasArgument("origin")) { - HashMap originMap = (HashMap)call.argument("origin"); origin = locationForMap(originMap); } - HashMap destinationMap = (HashMap)call.argument("destination"); + HashMap destinationMap = getHashMapFromMethodCall(call, "destination"); Location destination = locationForMap(destinationMap); EnumSet modes = EnumSet.noneOf(Radar.RadarRouteMode.class); - ArrayList modesList = call.argument("modes"); - String[] modesArr = (String[])(new String[0]); + String[] modesArr = getStringArrayFromMethodCall(call, "modes"); for (String modeStr : modesArr) { if (modeStr.equals("FOOT") || modeStr.equals("foot")) { modes.add(Radar.RadarRouteMode.FOOT); @@ -1078,8 +1185,10 @@ public void run() { modes.add(Radar.RadarRouteMode.CAR); } } - String unitsStr = call.argument("units"); - Radar.RadarRouteUnits units = unitsStr.equals("METRIC") || unitsStr.equals("metric") ? Radar.RadarRouteUnits.METRIC : Radar.RadarRouteUnits.IMPERIAL; + String unitsStr = getStringFromMethodCall(call, "units"); + Radar.RadarRouteUnits units = unitsStr.equals("METRIC") || unitsStr.equals("metric") + ? Radar.RadarRouteUnits.METRIC + : Radar.RadarRouteUnits.IMPERIAL; if (origin != null) { Radar.getDistance(origin, destination, modes, units, callback); @@ -1088,7 +1197,7 @@ public void run() { } } - public void logConversion(MethodCall call, final Result result) throws JSONException { + public void logConversion(MethodCall call, final Result result) throws JSONException { Radar.RadarLogConversionCallback callback = new Radar.RadarLogConversionCallback() { @Override public void onComplete(@NonNull Radar.RadarStatus status, @Nullable RadarEvent event) { @@ -1101,7 +1210,7 @@ public void run() { if (event != null) { obj.put("event", event.toJson()); } - + HashMap map = new Gson().fromJson(obj.toString(), HashMap.class); result.success(map); } catch (Exception e) { @@ -1112,11 +1221,14 @@ public void run() { } }; - String name = call.argument("name"); - HashMap metadataMap= call.argument("metadata"); - JSONObject metadataJson = jsonForMap(metadataMap); + String name = getStringFromMethodCall(call, "name"); + JSONObject metadataJson; + HashMap metadataMap = getHashMapFromMethodCall(call, "metadata"); + if (metadataMap == null) { + metadataJson = jsonForMap(metadataMap); + } if (call.hasArgument("revenue") && call.argument("revenue") != null) { - double revenue = (Double)call.argument("revenue"); + double revenue = (Double) call.argument("revenue"); Radar.logConversion(name, revenue, metadataJson, callback); } else { Radar.logConversion(name, metadataJson, callback); @@ -1134,7 +1246,7 @@ public void logResigningActive(Result result) { } public void getMatrix(MethodCall call, final Result result) throws JSONException { - ArrayList originsArr = call.argument("origins"); + ArrayList originsArr = call.argument("origins"); Location[] origins = new Location[originsArr.size()]; for (int i = 0; i < originsArr.size(); i++) { origins[i] = locationForMap(originsArr.get(i)); @@ -1144,11 +1256,11 @@ public void getMatrix(MethodCall call, final Result result) throws JSONException for (int i = 0; i < destinationsArr.size(); i++) { destinations[i] = locationForMap(destinationsArr.get(i)); } - String modeStr = call.argument("mode"); + String modeStr = getStringFromMethodCall(call, "mode"); Radar.RadarRouteMode mode = Radar.RadarRouteMode.CAR; if (modeStr != null) { modeStr = modeStr.toLowerCase(); - if ( modeStr.equals("foot")) { + if (modeStr.equals("foot")) { mode = Radar.RadarRouteMode.FOOT; } else if (modeStr.equals("bike")) { mode = Radar.RadarRouteMode.BIKE; @@ -1160,8 +1272,10 @@ public void getMatrix(MethodCall call, final Result result) throws JSONException mode = Radar.RadarRouteMode.MOTORBIKE; } } - String unitsStr = call.argument("units"); - Radar.RadarRouteUnits units = unitsStr != null && unitsStr.toLowerCase().equals("metric") ? Radar.RadarRouteUnits.METRIC : Radar.RadarRouteUnits.IMPERIAL; + String unitsStr = getStringFromMethodCall(call, "units"); + Radar.RadarRouteUnits units = unitsStr != null && unitsStr.toLowerCase().equals("metric") + ? Radar.RadarRouteUnits.METRIC + : Radar.RadarRouteUnits.IMPERIAL; Radar.getMatrix(origins, destinations, mode, units, new Radar.RadarMatrixCallback() { @Override @@ -1188,7 +1302,7 @@ public void run() { } public void trackVerified(MethodCall call, final Result result) { - Boolean beacons = call.hasArgument("beacons") ? call.argument("beacons") : false; + Boolean beacons = getBooleanFromMethodCall(call, "beacons", false); Radar.RadarTrackVerifiedCallback callback = new Radar.RadarTrackVerifiedCallback() { @Override @@ -1222,7 +1336,8 @@ private void isUsingRemoteTrackingOptions(Result result) { public void validateAddress(MethodCall call, final Result result) throws JSONException { Radar.RadarValidateAddressCallback callback = new Radar.RadarValidateAddressCallback() { @Override - public void onComplete(final Radar.RadarStatus status, final RadarAddress address, final Radar.RadarAddressVerificationStatus verificationStatus) { + public void onComplete(final Radar.RadarStatus status, final RadarAddress address, + final Radar.RadarAddressVerificationStatus verificationStatus) { runOnMainThread(new Runnable() { @Override public void run() { @@ -1246,21 +1361,21 @@ public void run() { } }; - HashMap addressMap= call.argument("address"); + HashMap addressMap = getHashMapFromMethodCall(call, "address"); JSONObject addressJSON = jsonForMap(addressMap); RadarAddress address = RadarAddress.fromJson(addressJSON); Radar.validateAddress(address, callback); } private Location locationForMap(HashMap locationMap) { - double latitude = (Double)locationMap.get("latitude"); - double longitude = (Double)locationMap.get("longitude"); + double latitude = (Double) locationMap.get("latitude"); + double longitude = (Double) locationMap.get("longitude"); Location location = new Location("RadarSDK"); location.setLatitude(latitude); location.setLongitude(longitude); if (locationMap.containsKey("accuracy")) { - double accuracyDouble = (Double)locationMap.get("accuracy"); - float accuracy = (float)accuracyDouble; + double accuracyDouble = (Double) locationMap.get("accuracy"); + float accuracy = (float) accuracyDouble; location.setAccuracy(accuracy); } return location; @@ -1293,13 +1408,13 @@ public void onEventsReceived(Context context, RadarEvent[] events, RadarUser use } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("events", RadarEvent.toJson(events)); obj.put("user", user.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1333,7 +1448,7 @@ public void onLocationUpdated(Context context, Location location, RadarUser user obj.put("user", user.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1348,9 +1463,9 @@ public void run() { Log.e(TAG, e.toString()); } } - - public void onClientLocationUpdated(Context context, Location location, boolean stopped, Radar.RadarLocationSource source) { + public void onClientLocationUpdated(Context context, Location location, boolean stopped, + Radar.RadarLocationSource source) { try { SharedPreferences sharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); long callbackHandle = sharedPrefs.getLong("clientLocation", 0L); @@ -1360,14 +1475,14 @@ public void onClientLocationUpdated(Context context, Location location, boolean } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("location", Radar.jsonForLocation(location)); obj.put("stopped", stopped); obj.put("source", source.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1382,7 +1497,7 @@ public void run() { Log.e(TAG, e.toString()); } } - + @Override public void onError(Context context, Radar.RadarStatus status) { try { @@ -1394,12 +1509,12 @@ public void onError(Context context, Radar.RadarStatus status) { } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("status", status.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1414,7 +1529,7 @@ public void run() { Log.e(TAG, e.toString()); } } - + @Override public void onLog(Context context, String message) { try { @@ -1426,12 +1541,12 @@ public void onLog(Context context, String message) { } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("message", message); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1447,7 +1562,7 @@ public void run() { } } } - + public static class RadarFlutterVerifiedReceiver extends RadarVerifiedReceiver { @Override @@ -1461,12 +1576,12 @@ public void onTokenUpdated(Context context, RadarVerifiedLocationToken token) { } RadarFlutterPlugin.initializeBackgroundEngine(context); - + JSONObject obj = new JSONObject(); obj.put("token", token.toJson()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - synchronized(lock) { + synchronized (lock) { final ArrayList args = new ArrayList(); args.add(callbackHandle); args.add(res); @@ -1486,7 +1601,7 @@ public void run() { public void attachListeners(MethodCall call, Result result) { SharedPreferences sharedPrefs = mContext.getSharedPreferences(TAG, Context.MODE_PRIVATE); - long callbackDispatcherHandle = ((Number)call.argument("callbackDispatcherHandle")).longValue(); + long callbackDispatcherHandle = ((Number) call.argument("callbackDispatcherHandle")).longValue(); sharedPrefs.edit().putLong(CALLBACK_DISPATCHER_HANDLE_KEY, callbackDispatcherHandle).commit(); result.success(true); } @@ -1501,7 +1616,7 @@ public void detachListeners(MethodCall call, Result result) { public void on(MethodCall call, Result result) { SharedPreferences sharedPrefs = mContext.getSharedPreferences(TAG, Context.MODE_PRIVATE); String listener = call.argument("listener"); - long callbackHandle = ((Number)call.argument("callbackHandle")).longValue(); + long callbackHandle = ((Number) call.argument("callbackHandle")).longValue(); sharedPrefs.edit().putLong(listener, callbackHandle).commit(); result.success(true); } diff --git a/example/lib/main.dart b/example/lib/main.dart index fc5f88d..f90cc65 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -4,8 +4,6 @@ import 'package:flutter_radar/flutter_radar.dart'; void main() => runApp(MyApp()); - - class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); @@ -68,12 +66,13 @@ class _MyAppState extends State with WidgetsBindingObserver { } Future initRadar() async { - Radar.initialize('prj_test_pk_0000000000000000000000000000000000000000'); - Radar.setUserId('flutter'); - Radar.setDescription('Flutter'); - Radar.setMetadata({'foo': 'bar', 'bax': true, 'qux': 1}); - Radar.setLogLevel('info'); - Radar.setAnonymousTrackingEnabled(false); + Radar.initialize( + publishableKey: 'prj_test_pk_0000000000000000000000000000000000000000'); + Radar.setUserId(userId: 'flutter'); + Radar.setDescription(description: 'Flutter'); + Radar.setMetadata(metadata: {'foo': 'bar', 'bax': true, 'qux': 1}); + Radar.setLogLevel(logLevel: 'info'); + Radar.setAnonymousTrackingEnabled(enabled: false); Radar.attachListeners(); @@ -84,13 +83,13 @@ class _MyAppState extends State with WidgetsBindingObserver { Radar.onLog(onLog); Radar.onToken(onToken); - await Radar.requestPermissions(false); + await Radar.requestPermissions(background: false); - await Radar.requestPermissions(true); + await Radar.requestPermissions(background: true); var permissionStatus = await Radar.getPermissionsStatus(); if (permissionStatus != "DENIED") { - var b = await Radar.startTrackingCustom({ - ... Radar.presetResponsive, + var b = await Radar.startTrackingCustom(options: { + ...Radar.presetResponsive, "showBlueBar": true, }); //Radar.startTracking('continuous'); @@ -102,352 +101,383 @@ class _MyAppState extends State with WidgetsBindingObserver { @override Widget build(BuildContext context) { - return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('flutter_radar_example'), ), body: SingleChildScrollView( - scrollDirection: Axis.vertical, - child: Container( - child: Column(children: [ - Permissions(), - TrackOnce(), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var status = await Radar.requestPermissions(false); - print(status); - if (status == 'GRANTED_FOREGROUND') { - status = await Radar.requestPermissions(true); + scrollDirection: Axis.vertical, + child: Container( + child: Column(children: [ + Permissions(), + TrackOnce(), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var status = + await Radar.requestPermissions(background: false); print(status); - } - }, - child: Text('requestPermissions()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - Radar.setForegroundServiceOptions({ - 'title': 'Tracking', - 'text': 'Trip tracking started', - 'icon': 2131165271, - 'importance': 2, - 'updatesOnly': false, - 'activity': 'io.radar.example.MainActivity' - }); - var resp = await Radar.startTrip( - tripOptions: { + if (status == 'GRANTED_FOREGROUND') { + status = await Radar.requestPermissions(background: true); + print(status); + } + }, + child: Text('requestPermissions()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + Radar.setForegroundServiceOptions(foregroundServiceOptions: { + 'title': 'Tracking', + 'text': 'Trip tracking started', + 'icon': 2131165271, + 'importance': 2, + 'updatesOnly': false, + 'activity': 'io.radar.example.MainActivity' + }); + var resp = await Radar.startTrip(tripOptions: { "externalId": '299', "destinationGeofenceTag": 'store', "destinationGeofenceExternalId": '123', "mode": 'car', "scheduledArrivalAt": "2020-08-20T10:30:55.837Z", "metadata": {"test": 123} - }, - trackingOptions: { - "desiredStoppedUpdateInterval": 30, - "fastestStoppedUpdateInterval": 30, - "desiredMovingUpdateInterval": 30, - "fastestMovingUpdateInterval": 30, - "desiredSyncInterval": 20, - "desiredAccuracy": "high", - "stopDuration": 0, - "stopDistance": 0, - "replay": "none", - "sync": "all", - "showBlueBar": true, - "useStoppedGeofence": false, - "stoppedGeofenceRadius": 0, - "useMovingGeofence": false, - "movingGeofenceRadius": 0, - "syncGeofences": false, - "syncGeofencesLimit": 0, - "beacons": false, - "foregroundServiceEnabled": true - } - ); - print("startTrip: $resp"); - }, - child: Text('startTrip'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.completeTrip(); - print("completeTrip: $resp"); - }, - child: Text('completeTrip'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.cancelTrip(); - print("cancelTrip: $resp"); - }, - child: Text('cancelTrip'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.getTrackingOptions(); - print("getTrackingOptions: $resp"); - }, - child: Text('getTrackingOptions'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.updateTrip( - status:'arrived', - options: { + }, trackingOptions: { + "desiredStoppedUpdateInterval": 30, + "fastestStoppedUpdateInterval": 30, + "desiredMovingUpdateInterval": 30, + "fastestMovingUpdateInterval": 30, + "desiredSyncInterval": 20, + "desiredAccuracy": "high", + "stopDuration": 0, + "stopDistance": 0, + "replay": "none", + "sync": "all", + "showBlueBar": true, + "useStoppedGeofence": false, + "stoppedGeofenceRadius": 0, + "useMovingGeofence": false, + "movingGeofenceRadius": 0, + "syncGeofences": false, + "syncGeofencesLimit": 0, + "beacons": false, + "foregroundServiceEnabled": true + }); + print("startTrip: $resp"); + }, + child: Text('startTrip'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.completeTrip(); + print("completeTrip: $resp"); + }, + child: Text('completeTrip'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.cancelTrip(); + print("cancelTrip: $resp"); + }, + child: Text('cancelTrip'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.getTrackingOptions(); + print("getTrackingOptions: $resp"); + }, + child: Text('getTrackingOptions'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = + await Radar.updateTrip(status: 'arrived', options: { "externalId": '299', - "metadata": { - "parkingSpot": '5' - } - } - ); - print("updateTrip: $resp"); - }, - child: Text('updateTrip'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.logConversion( - name: "in_app_purchase", - revenue: 0.2, - metadata: {"price": "150USD"}); - print("logConversion: $resp"); - }, - child: Text('logConversion'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - await Radar.setNotificationOptions({ - 'iconString': 'icon' - }); - }, - child: Text('setNotificationOptions'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.searchPlaces( - near: { - 'latitude': 40.783826, - 'longitude': -73.975363, - }, - radius: 1000, - chains: ["starbucks"], - chainMetadata: { - "customFlag": "true" - }, - limit: 10, - ); - print("searchPlaces: $resp"); - }, - child: Text('searchPlaces()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.searchGeofences( - near: { - 'latitude': 40.783826, - 'longitude': -73.975363, - }, - radius: 1000, - limit: 10, - includeGeometry: true, - tags: List.empty(), - metadata: {}, - ); - print("searchGeofences: $resp"); - }, - child: Text('searchGeofences()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.geocode( - '20 jay st brooklyn', - ); - print("geocode: $resp"); - }, - child: Text('geocode()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.reverseGeocode(); - print("reverseGeocode: $resp"); - }, - child: Text('reverseGeocode()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.autocomplete( - query: 'brooklyn roasting', - near: { - 'latitude': 40.783826, - 'longitude': -73.975363, - }, - limit: 10, - layers: ['address', 'street'], - country: 'US', - mailable: false - ); - print("autocomplete: $resp"); - }, - child: Text('autocomplete'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - var resp = await Radar.getMatrix( - origins: [ - { - 'latitude': 40.78382, - 'longitude': -73.97536, - }, - { - 'latitude': 40.70390, - 'longitude': -73.98670, + "metadata": {"parkingSpot": '5'} + }); + print("updateTrip: $resp"); + }, + child: Text('updateTrip'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.logConversion( + name: "in_app_purchase", + revenue: 0.2, + metadata: {"price": "150USD"}); + print("logConversion: $resp"); + }, + child: Text('logConversion'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + await Radar.setNotificationOptions( + notificationOptions: {'iconString': 'icon'}); + }, + child: Text('setNotificationOptions'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.searchPlaces( + radius: 1000, + limit: 10, + near: { + 'latitude': 40.783826, + 'longitude': -73.975363, }, - ], - destinations: [ - { - 'latitude': 40.64189, - 'longitude': -73.78779, + chains: ["starbucks"], + chainMetadata: {"customFlag": "true"}, + ); + print("searchPlaces: $resp"); + }, + child: Text('searchPlaces()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.searchGeofences( + near: { + 'latitude': 40.783826, + 'longitude': -73.975363, }, - { - 'latitude': 35.99801, - 'longitude': -78.94294, - }, - ], - mode: 'car', - units: 'imperial', - ); - print("getMatrix: $resp"); - }, - child: Text('getMatrix'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () { - Radar.startTracking('responsive'); - }, - child: Text('startTracking(\'responsive\')'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () { - - Radar.setForegroundServiceOptions({ - 'title': 'Tracking', - 'text': 'Continuous tracking started', - 'icon': 2131165271, - 'importance': 2, - 'updatesOnly': false, - 'activity': 'io.radar.example.MainActivity' - }); - Radar.startTrackingCustom({ - 'desiredStoppedUpdateInterval': 120, - 'fastestStoppedUpdateInterval': 120, - 'desiredMovingUpdateInterval': 30, - 'fastestMovingUpdateInterval': 30, - 'desiredSyncInterval': 20, - 'desiredAccuracy': 'high', - 'stopDuration': 140, - 'stopDistance': 70, - 'sync': 'all', - 'replay': 'none', - 'showBlueBar': true, - 'foregroundServiceEnabled': true - }); - }, - child: Text('startTrackingCustom()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () { - Radar.startTrackingVerified(30, false); - }, - child: Text('startTrackingVerified()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () { - Radar.stopTrackingVerified(); - }, - child: Text('stopTrackingVerified()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () { - Radar.stopTracking(); - }, - child: Text('stopTracking()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () { - Radar.mockTracking( - origin: {'latitude': 40.78382, 'longitude': -73.97536}, - destination: {'latitude': 40.70390, 'longitude': -73.98670}, + radius: 1000, + limit: 10, + includeGeometry: true, + tags: List.empty(), + metadata: {}, + ); + print("searchGeofences: $resp"); + }, + child: Text('searchGeofences()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.geocode( + query: '20 jay st brooklyn', + ); + print("geocode: $resp"); + }, + child: Text('geocode()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.reverseGeocode(); + print("reverseGeocode: $resp"); + }, + child: Text('reverseGeocode()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.autocomplete( + query: 'brooklyn roasting', + limit: 10, + near: { + 'latitude': 40.783826, + 'longitude': -73.975363, + }, + layers: ['address', 'street'], + country: 'US', + mailable: false); + print("autocomplete: $resp"); + }, + child: Text('autocomplete'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + var resp = await Radar.getMatrix( + origins: [ + { + 'latitude': 40.78382, + 'longitude': -73.97536, + }, + { + 'latitude': 40.70390, + 'longitude': -73.98670, + }, + ], + destinations: [ + { + 'latitude': 40.64189, + 'longitude': -73.78779, + }, + { + 'latitude': 35.99801, + 'longitude': -78.94294, + }, + ], mode: 'car', - steps: 3, - interval: 3); - }, - child: Text('mockTracking()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - Map? location = await Radar.getLocation('high'); - print(location); - }, - child: Text('getLocation()'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - Map? resp = await Radar.trackVerified(); - print("trackVerified: $resp"); - }, - child: Text('trackVerified()'), - ), - - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - bool? resp = await Radar.isUsingRemoteTrackingOptions(); - print("isUsingRemoteTrackingOptions: $resp"); - }, - child: Text('isUsingRemoteTrackingOptions'), - ), - ElevatedButton( - style: raisedButtonStyle, - onPressed: () async { - Map? resp = await Radar.validateAddress({ - "city": "NEW YORK", - "stateCode": "NY", - "postalCode": "10003", - "countryCode": "US", - "street": "BROADWAY", - "number": "841", - }); - print("validateAddress: $resp"); - }, - child: Text('validateAddress'), - ), - ]), - ) - ), + units: 'imperial', + ); + print("getMatrix: $resp"); + }, + child: Text('getMatrix'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () { + Radar.startTracking(preset: 'responsive'); + }, + child: Text('startTracking(\'responsive\')'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () { + Radar.setForegroundServiceOptions(foregroundServiceOptions: { + 'title': 'Tracking', + 'text': 'Continuous tracking started', + 'icon': 2131165271, + 'importance': 2, + 'updatesOnly': false, + 'activity': 'io.radar.example.MainActivity' + }); + Radar.startTrackingCustom(options: { + 'desiredStoppedUpdateInterval': 120, + 'fastestStoppedUpdateInterval': 120, + 'desiredMovingUpdateInterval': 30, + 'fastestMovingUpdateInterval': 30, + 'desiredSyncInterval': 20, + 'desiredAccuracy': 'high', + 'stopDuration': 140, + 'stopDistance': 70, + 'sync': 'all', + 'replay': 'none', + 'showBlueBar': true, + 'foregroundServiceEnabled': true + }); + }, + child: Text('startTrackingCustom()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () { + Radar.startTrackingVerified(interval: 30, beacons: false); + }, + child: Text('startTrackingVerified()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () { + Radar.stopTrackingVerified(); + }, + child: Text('stopTrackingVerified()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () { + Radar.stopTracking(); + }, + child: Text('stopTracking()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () { + Radar.mockTracking(origin: { + 'latitude': 40.78382, + 'longitude': -73.97536 + }, destination: { + 'latitude': 40.70390, + 'longitude': -73.98670 + }, mode: 'car', steps: 3, interval: 3); + }, + child: Text('mockTracking()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + Map? location = await Radar.getLocation(accuracy: 'high'); + print(location); + }, + child: Text('getLocation()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + Map? resp = await Radar.trackVerified(); + print("trackVerified: $resp"); + }, + child: Text('trackVerified()'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + bool? resp = await Radar.isUsingRemoteTrackingOptions(); + print("isUsingRemoteTrackingOptions: $resp"); + }, + child: Text('isUsingRemoteTrackingOptions'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + Map? resp = await Radar.validateAddress(address:{ + "city": "NEW YORK", + "stateCode": "NY", + "postalCode": "10003", + "countryCode": "US", + "street": "BROADWAY", + "number": "841", + }); + print("validateAddress: $resp"); + }, + child: Text('validateAddress'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + await Radar.acceptEvent( + eventId: 'event-id', + VerifiedPlaceId: 'verified-place-id'); + ; + print("accept event"); + }, + child: Text('acceptEvent'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + await Radar.rejectEvent(eventId: 'event-id'); + ; + print("reject event"); + }, + child: Text('rejectEvent'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + Map? res = await Radar.getContext( + location: {'latitude': 40.78382, 'longitude': -73.97536}); + ; + print("getContext: $res"); + }, + child: Text('getContext'), + ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + Map? res = await Radar.getDistance(destination: { + 'latitude': 40.78382, + 'longitude': -73.97536 + }, modes: [ + 'car' + ], units: 'imperial'); + ; + print("getDistance: $res"); + }, + child: Text('getDistance'), + ), + ]), + )), )); } } diff --git a/ios/Classes/RadarFlutterPlugin.m b/ios/Classes/RadarFlutterPlugin.m index c505483..281d6af 100644 --- a/ios/Classes/RadarFlutterPlugin.m +++ b/ios/Classes/RadarFlutterPlugin.m @@ -94,6 +94,10 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self completeTrip:call withResult:result]; } else if ([@"cancelTrip" isEqualToString:call.method]) { [self cancelTrip:call withResult:result]; + } else if ([@"acceptEvent" isEqualToString:call.method]) { + [self acceptEvent:call withResult:result]; + } else if ([@"rejectEvent" isEqualToString:call.method]) { + [self rejectEvent:call withResult:result]; } else if ([@"getContext" isEqualToString:call.method]) { [self getContext:call withResult:result]; } else if ([@"searchGeofences" isEqualToString:call.method]) { @@ -143,10 +147,56 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { } } +- (NSString *)getStringValueForKey:(NSDictionary *)dictionary key:(NSString *)key { + id value = [dictionary objectForKey:key]; + + if (value && [value isKindOfClass:[NSString class]]) { + return (NSString *)value; + } + + return nil; +} + +- (BOOL)getBoolValueForKey:(NSDictionary *)dictionary key:(NSString *)key defaultValue:(BOOL)defaultValue { + id value = [dictionary objectForKey:key]; + if (value && [value isKindOfClass:[NSNumber class]]) { + return [(NSNumber *)value boolValue]; + } + + return defaultValue; +} + +- (NSDictionary *)getDictionaryValueForKey:(NSDictionary *)dictionary key:(NSString *)key { + id value = [dictionary objectForKey:key]; + if (value && [value isKindOfClass:[NSDictionary class]]) { + return (NSDictionary *)value; + } + + return nil; +} + +- (NSArray *)getArrayValueForKey:(NSDictionary *)dictionary key:(NSString *)key { + id value = [dictionary objectForKey:key]; + if (value && [value isKindOfClass:[NSArray class]]) { + return (NSArray *)value; + } + + return nil; +} + +- (int)getIntegerValueForKey:(NSDictionary *)dictionary key:(NSString *)key defaultValue:(int)defaultValue { + id value = [dictionary objectForKey:key]; + if (value && [value isKindOfClass:[NSNumber class]]) { + return [(NSNumber *)value intValue]; + } + + return defaultValue; +} + - (void)initialize:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSString *publishableKey = argsDict[@"publishableKey"]; + NSString *publishableKey = [self getStringValueForKey:argsDict key:@"publishableKey"]; [[NSUserDefaults standardUserDefaults] setObject:@"Flutter" forKey:@"radar-xPlatformSDKType"]; [[NSUserDefaults standardUserDefaults] setObject:@"3.10.0" forKey:@"radar-xPlatformSDKVersion"]; [Radar initializeWithPublishableKey:publishableKey]; @@ -156,7 +206,7 @@ - (void)initialize:(FlutterMethodCall *)call withResult:(FlutterResult)result { - (void)setLogLevel:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSString *logLevel = argsDict[@"logLevel"]; + NSString *logLevel = [self getStringValueForKey:argsDict key:@"logLevel"]; if (!logLevel) { [Radar setLogLevel:RadarLogLevelNone]; } else if ([logLevel isEqualToString:@"debug"]) { @@ -207,9 +257,8 @@ - (void)requestPermissions:(FlutterMethodCall *)call withResult:(FlutterResult)r self.permissionsRequestResult = result; NSDictionary *argsDict = call.arguments; + BOOL background = [self getBoolValueForKey:argsDict key:@"background" defaultValue:NO]; - NSNumber *backgroundNumber = argsDict[@"background"]; - BOOL background = [backgroundNumber boolValue]; CLAuthorizationStatus status = [CLLocationManager authorizationStatus]; if (background && status == kCLAuthorizationStatusAuthorizedWhenInUse) { [self.locationManager requestAlwaysAuthorization]; @@ -223,7 +272,7 @@ - (void)requestPermissions:(FlutterMethodCall *)call withResult:(FlutterResult)r - (void)setUserId:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSString *userId = argsDict[@"userId"]; + NSString *userId = [self getStringValueForKey:argsDict key:@"userId"]; [Radar setUserId:userId]; result(nil); } @@ -236,7 +285,7 @@ - (void)getUserId:(FlutterMethodCall *)call withResult:(FlutterResult)result { - (void)setDescription:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSString *description = argsDict[@"description"]; + NSString *description = [self getStringValueForKey:argsDict key:@"description"]; [Radar setDescription:description]; result(nil); } @@ -260,8 +309,7 @@ - (void)getMetadata:(FlutterMethodCall *)call withResult:(FlutterResult)result { - (void)setAnonymousTrackingEnabled:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSNumber* enabledNumber = argsDict[@"enabled"]; - BOOL enabled = [enabledNumber boolValue]; + BOOL enabled = [self getBoolValueForKey:argsDict key:@"enabled" defaultValue:NO]; [Radar setAnonymousTrackingEnabled:enabled]; result(nil); } @@ -280,7 +328,7 @@ - (void)getLocation:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSString *accuracy = argsDict[@"accuracy"]; + NSString *accuracy = [self getStringValueForKey:argsDict key:@"accuracy"]; if (!accuracy) { [Radar getLocationWithCompletionHandler:completionHandler]; } else if ([accuracy isEqualToString:@"high"]) { @@ -314,8 +362,8 @@ - (void)trackOnce:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSDictionary *locationDict = argsDict[@"location"]; - if (locationDict != nil && [locationDict isKindOfClass:[NSDictionary class]]) { + NSDictionary *locationDict = [self getDictionaryValueForKey:argsDict key:@"location"]; + if (locationDict != nil) { NSNumber *latitudeNumber = locationDict[@"latitude"]; NSNumber *longitudeNumber = locationDict[@"longitude"]; NSNumber *accuracyNumber = locationDict[@"accuracy"]; @@ -326,11 +374,11 @@ - (void)trackOnce:(FlutterMethodCall *)call withResult:(FlutterResult)result { [Radar trackOnceWithLocation:location completionHandler:completionHandler]; } else { RadarTrackingOptionsDesiredAccuracy desiredAccuracy = RadarTrackingOptionsDesiredAccuracyMedium; - BOOL beaconsTrackingOption = NO; + BOOL beaconsTrackingOption = [self getBoolValueForKey:argsDict key:@"beacons" defaultValue:NO]; - NSString *accuracy = argsDict[@"desiredAccuracy"]; + NSString *accuracy =[self getStringValueForKey:argsDict key:@"desiredAccuracy"]; - if (accuracy != nil && [accuracy isKindOfClass:[NSString class]]) { + if (accuracy != nil) { NSString *lowerAccuracy = [accuracy lowercaseString]; if ([lowerAccuracy isEqualToString:@"high"]) { desiredAccuracy = RadarTrackingOptionsDesiredAccuracyHigh; @@ -340,13 +388,7 @@ - (void)trackOnce:(FlutterMethodCall *)call withResult:(FlutterResult)result { desiredAccuracy = RadarTrackingOptionsDesiredAccuracyLow; } } - - BOOL beacons = argsDict[@"beacons"]; - - if (beacons) { - beaconsTrackingOption = beacons; - } - + [Radar trackOnceWithDesiredAccuracy:desiredAccuracy beacons:beaconsTrackingOption completionHandler:completionHandler]; } } @@ -354,7 +396,7 @@ - (void)trackOnce:(FlutterMethodCall *)call withResult:(FlutterResult)result { - (void)startTracking:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSString *preset = argsDict[@"preset"]; + NSString *preset = [self getStringValueForKey:argsDict key:@"preset"]; if (!preset) { [Radar startTrackingWithOptions:RadarTrackingOptions.presetResponsive]; } else if ([preset isEqualToString:@"continuous"]) { @@ -379,17 +421,9 @@ - (void)startTrackingCustom:(FlutterMethodCall *)call withResult:(FlutterResult) - (void)startTrackingVerified:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - BOOL beacons = NO; - NSNumber *beaconsNumber = argsDict[@"beacons"]; - if (beaconsNumber != nil && [beaconsNumber isKindOfClass:[NSNumber class]]) { - beacons = [beaconsNumber boolValue]; - } + BOOL beacons = [self getBoolValueForKey:argsDict key:@"beacons" defaultValue:NO]; - double interval = 1; - NSNumber *intervalNumber = argsDict[@"interval"]; - if (intervalNumber != nil && [intervalNumber isKindOfClass:[NSNumber class]]) { - interval = [intervalNumber doubleValue]; - } + double interval = [argsDict[@"interval"] doubleValue]; [Radar startTrackingVerifiedWithInterval:interval beacons:beacons]; result(nil); @@ -423,19 +457,25 @@ - (void)getTrackingOptions:(FlutterMethodCall *)call withResult:(FlutterResult)r - (void)mockTracking:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSDictionary *originDict = argsDict[@"origin"]; + NSDictionary *originDict = [self getDictionaryValueForKey:argsDict key:@"origin"]; + NSDictionary *destinationDict = [self getDictionaryValueForKey:argsDict key:@"destination"]; + if (!originDict || !destinationDict) { + result(nil); + return; + } NSNumber *originLatitudeNumber = originDict[@"latitude"]; NSNumber *originLongitudeNumber = originDict[@"longitude"]; double originLatitude = [originLatitudeNumber doubleValue]; double originLongitude = [originLongitudeNumber doubleValue]; CLLocation *origin = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(originLatitude, originLongitude) altitude:-1 horizontalAccuracy:5 verticalAccuracy:-1 timestamp:[NSDate date]]; - NSDictionary *destinationDict = argsDict[@"destination"]; + NSNumber *destinationLatitudeNumber = destinationDict[@"latitude"]; NSNumber *destinationLongitudeNumber = destinationDict[@"longitude"]; double destinationLatitude = [destinationLatitudeNumber doubleValue]; double destinationLongitude = [destinationLongitudeNumber doubleValue]; CLLocation *destination = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(destinationLatitude, destinationLongitude) altitude:-1 horizontalAccuracy:5 verticalAccuracy:-1 timestamp:[NSDate date]]; - NSString *modeStr = argsDict[@"mode"]; + + NSString *modeStr = [self getStringValueForKey:argsDict key:@"mode"]; RadarRouteMode mode = RadarRouteModeCar; if ([modeStr isEqualToString:@"FOOT"] || [modeStr isEqualToString:@"foot"]) { mode = RadarRouteModeFoot; @@ -444,20 +484,8 @@ - (void)mockTracking:(FlutterMethodCall *)call withResult:(FlutterResult)result } else if ([modeStr isEqualToString:@"CAR"] || [modeStr isEqualToString:@"car"]) { mode = RadarRouteModeCar; } - NSNumber *stepsNumber = argsDict[@"steps"]; - int steps; - if (stepsNumber != nil && [stepsNumber isKindOfClass:[NSNumber class]]) { - steps = [stepsNumber intValue]; - } else { - steps = 10; - } - NSNumber *intervalNumber = argsDict[@"interval"]; - int interval; - if (intervalNumber != nil && [intervalNumber isKindOfClass:[NSNumber class]]) { - interval = [intervalNumber intValue]; - } else { - interval = 1; - } + int steps = [argsDict[@"steps"] intValue]; + int interval = [argsDict[@"interval"] intValue]; [Radar mockTrackingWithOrigin:origin destination:destination mode:mode steps:steps interval:interval completionHandler:nil]; } @@ -477,9 +505,9 @@ - (void)startTrip:(FlutterMethodCall *)call withResult:(FlutterResult)result { } }; NSDictionary *argsDict = call.arguments; - NSDictionary *tripOptionsDict = argsDict[@"tripOptions"]; + NSDictionary *tripOptionsDict = [self getDictionaryValueForKey:argsDict key:@"tripOptions"]; RadarTripOptions *tripOptions = [RadarTripOptions tripOptionsFromDictionary:tripOptionsDict]; - NSDictionary *trackingOptionsDict = argsDict[@"trackingOptions"]; + NSDictionary *trackingOptionsDict = [self getDictionaryValueForKey:argsDict key:@"trackingOptions"]; RadarTrackingOptions *trackingOptions; if (trackingOptionsDict) { trackingOptions = [RadarTrackingOptions trackingOptionsFromDictionary:trackingOptionsDict]; @@ -503,9 +531,9 @@ - (void)updateTrip:(FlutterMethodCall *)call withResult:(FlutterResult)result { } }; NSDictionary *argsDict = call.arguments; - NSDictionary *tripOptionsDict = argsDict[@"tripOptions"]; + NSDictionary *tripOptionsDict = [self getDictionaryValueForKey:argsDict key:@"tripOptions"]; RadarTripOptions *tripOptions = [RadarTripOptions tripOptionsFromDictionary:tripOptionsDict]; - NSString* statusStr = argsDict[@"status"]; + NSString* statusStr = [self getStringValueForKey:argsDict key:@"status"]; RadarTripStatus status = RadarTripStatusUnknown; statusStr = [statusStr lowercaseString]; if ([statusStr isEqualToString:@"started"]) { @@ -566,6 +594,21 @@ - (void)cancelTrip:(FlutterMethodCall *)call withResult:(FlutterResult)result { [Radar cancelTripWithCompletionHandler:completionHandler]; } +- (void) acceptEvent:(FlutterMethodCall *)call withResult:(FlutterResult)result { + NSDictionary *argsDict = call.arguments; + NSString *eventId = [self getStringValueForKey:argsDict key:@"eventId"]; + NSString *verifiedPlaceId = [self getStringValueForKey:argsDict key:@"verifiedPlaceId"]; + [Radar acceptEventId:eventId verifiedPlaceId:verifiedPlaceId]; + result(nil); +} + +- (void) rejectEvent:(FlutterMethodCall *)call withResult:(FlutterResult)result { + NSDictionary *argsDict = call.arguments; + NSString *eventId = [self getStringValueForKey:argsDict key:@"eventId"]; + [Radar rejectEventId:eventId]; + result(nil); +} + - (void)getContext:(FlutterMethodCall *)call withResult:(FlutterResult)result { RadarContextCompletionHandler completionHandler = ^(RadarStatus status, CLLocation * _Nullable location, RadarContext * _Nullable context) { NSMutableDictionary *dict = [NSMutableDictionary new]; @@ -581,7 +624,7 @@ - (void)getContext:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSDictionary *locationDict = argsDict[@"location"]; + NSDictionary *locationDict = [self getDictionaryValueForKey:argsDict key:@"location"]; if (locationDict) { NSNumber *latitudeNumber = locationDict[@"latitude"]; NSNumber *longitudeNumber = locationDict[@"longitude"]; @@ -614,7 +657,7 @@ - (void)searchGeofences:(FlutterMethodCall *)call withResult:(FlutterResult)resu NSDictionary *argsDict = call.arguments; CLLocation *near; - NSDictionary *nearDict = argsDict[@"near"]; + NSDictionary *nearDict = [self getDictionaryValueForKey:argsDict key:@"near"]; if (nearDict) { NSNumber *latitudeNumber = nearDict[@"latitude"]; NSNumber *longitudeNumber = nearDict[@"longitude"]; @@ -622,28 +665,15 @@ - (void)searchGeofences:(FlutterMethodCall *)call withResult:(FlutterResult)resu double longitude = [longitudeNumber doubleValue]; near = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) altitude:-1 horizontalAccuracy:5 verticalAccuracy:-1 timestamp:[NSDate date]]; } - NSNumber *radiusNumber = argsDict[@"radius"]; - int radius; - if (radiusNumber != nil && [radiusNumber isKindOfClass:[NSNumber class]]) { - radius = [radiusNumber intValue]; - } else { - radius = 1000; - } - NSArray *tags = argsDict[@"tags"]; - NSDictionary *metadata = argsDict[@"metadata"]; - NSNumber *limitNumber = argsDict[@"limit"]; - int limit; - if (limitNumber != nil && [limitNumber isKindOfClass:[NSNumber class]]) { - limit = [limitNumber intValue]; - } else { - limit = 10; - } - BOOL includeGeometry = NO; - NSNumber *includeGeometryNumber = argsDict[@"includeGeometry"]; - if (includeGeometryNumber != nil && [includeGeometryNumber isKindOfClass:[NSNumber class]]) { - includeGeometry = [includeGeometryNumber boolValue]; - } + int radius = [self getIntegerValueForKey:argsDict key:@"radius" defaultValue:1000]; + + NSArray *tags = [self getArrayValueForKey:argsDict key:@"tags"]; + + NSDictionary *metadata = [self getDictionaryValueForKey:argsDict key:@"metadata"]; + + int limit = [self getIntegerValueForKey:argsDict key:@"limit" defaultValue:10]; + BOOL includeGeometry = [self getBoolValueForKey:argsDict key:@"includeGeometry" defaultValue:NO]; if (near != nil) { [Radar searchGeofencesNear:near radius:radius tags:tags metadata:metadata limit:limit includeGeometry:includeGeometry completionHandler:completionHandler]; @@ -670,7 +700,7 @@ - (void)searchPlaces:(FlutterMethodCall *)call withResult:(FlutterResult)result NSDictionary *argsDict = call.arguments; CLLocation *near; - NSDictionary *nearDict = argsDict[@"near"]; + NSDictionary *nearDict = [self getDictionaryValueForKey:argsDict key:@"near"]; if (nearDict) { NSNumber *latitudeNumber = nearDict[@"latitude"]; NSNumber *longitudeNumber = nearDict[@"longitude"]; @@ -678,25 +708,16 @@ - (void)searchPlaces:(FlutterMethodCall *)call withResult:(FlutterResult)result double longitude = [longitudeNumber doubleValue]; near = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) altitude:-1 horizontalAccuracy:5 verticalAccuracy:-1 timestamp:[NSDate date]]; } - NSNumber *radiusNumber = argsDict[@"radius"]; - int radius; - if (radiusNumber != nil && [radiusNumber isKindOfClass:[NSNumber class]]) { - radius = [radiusNumber intValue]; - } else { - radius = 1000; - } - NSArray *chains = argsDict[@"chains"]; - NSDictionary *chainMetadata = [argsDict[@"chainMetadata"] isKindOfClass:[NSNull class]] ? nil : argsDict[@"chainMetadata"]; - NSArray *categories = [argsDict[@"categories"] isKindOfClass:[NSNull class]] ? nil : argsDict[@"categories"]; - NSArray *groups = [argsDict[@"groups"] isKindOfClass:[NSNull class]] ? nil : argsDict[@"groups"]; - NSNumber *limitNumber = argsDict[@"limit"]; - int limit; - if (limitNumber != nil && [limitNumber isKindOfClass:[NSNumber class]]) { - limit = [limitNumber intValue]; - } else { - limit = 10; - } + + int radius = [self getIntegerValueForKey:argsDict key:@"radius" defaultValue:1000]; + NSArray *chains = [self getArrayValueForKey:argsDict key:@"chains"]; + NSDictionary *chainMetadata = [self getDictionaryValueForKey:argsDict key:@"chainMetadata"]; + NSArray *categories = [self getArrayValueForKey:argsDict key:@"categories"]; + NSArray *groups = [self getArrayValueForKey:argsDict key:@"groups"]; + + int limit = [self getIntegerValueForKey:argsDict key:@"limit" defaultValue:10]; + if (near != nil) { [Radar searchPlacesNear:near radius:radius chains:chains chainMetadata:chainMetadata categories:categories groups:groups limit:limit completionHandler:completionHandler]; } else { @@ -707,9 +728,9 @@ - (void)searchPlaces:(FlutterMethodCall *)call withResult:(FlutterResult)result - (void)autocomplete:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSString *query = argsDict[@"query"]; + NSString *query = [self getStringValueForKey:argsDict key:@"query"]; CLLocation *near; - NSDictionary *nearDict = argsDict[@"near"]; + NSDictionary *nearDict = [self getDictionaryValueForKey:argsDict key:@"near"]; if (nearDict) { NSNumber *latitudeNumber = nearDict[@"latitude"]; NSNumber *longitudeNumber = nearDict[@"longitude"]; @@ -717,15 +738,11 @@ - (void)autocomplete:(FlutterMethodCall *)call withResult:(FlutterResult)result double longitude = [longitudeNumber doubleValue]; near = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) altitude:-1 horizontalAccuracy:5 verticalAccuracy:-1 timestamp:[NSDate date]]; } - NSNumber *limitNumber = argsDict[@"limit"]; - int limit; - if (limitNumber != nil && [limitNumber isKindOfClass:[NSNumber class]]) { - limit = [limitNumber intValue]; - } else { - limit = 10; - } - NSArray *layers = [argsDict[@"layers"] isKindOfClass:[NSNull class]] ? nil : argsDict[@"layers"]; - NSString *country = [argsDict[@"country"] isKindOfClass:[NSNull class]] ? nil : argsDict[@"country"]; + + int limit = [self getIntegerValueForKey:argsDict key:@"limit" defaultValue:10]; + + NSArray *layers = [self getArrayValueForKey:argsDict key:@"layers"]; + NSString *country = [self getStringValueForKey:argsDict key:@"country"]; RadarGeocodeCompletionHandler completionHandler = ^(RadarStatus status, NSArray * _Nullable addresses) { NSMutableDictionary *dict = [NSMutableDictionary new]; @@ -736,20 +753,14 @@ - (void)autocomplete:(FlutterMethodCall *)call withResult:(FlutterResult)result result(dict); }; - - NSNumber *mailableNumber = argsDict[@"mailable"]; - if (mailableNumber != nil && [mailableNumber isKindOfClass:[NSNumber class]]) { - BOOL mailable = [mailableNumber boolValue]; - [Radar autocompleteQuery:query near:near layers:layers limit:limit country:country mailable:mailable completionHandler:completionHandler]; - } else { - [Radar autocompleteQuery:query near:near layers:layers limit:limit country:country completionHandler:completionHandler]; - } + BOOL mailable = [self getBoolValueForKey:argsDict key:@"mailable" defaultValue:NO]; + [Radar autocompleteQuery:query near:near layers:layers limit:limit country:country mailable:mailable completionHandler:completionHandler]; } - (void)geocode:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSString *query = argsDict[@"query"]; + NSString *query = [self getStringValueForKey:argsDict key:@"query"]; [Radar geocodeAddress:query completionHandler:^(RadarStatus status, NSArray * _Nullable addresses) { NSMutableDictionary *dict = [NSMutableDictionary new]; [dict setObject:[Radar stringForStatus:status] forKey:@"status"]; @@ -772,29 +783,11 @@ - (void)reverseGeocode:(FlutterMethodCall *)call withResult:(FlutterResult)resul NSDictionary *argsDict = call.arguments; - NSArray *layers = nil; - id layersValue = argsDict[@"layers"]; - if (layersValue != nil && [layersValue isKindOfClass:[NSArray class]]) { - NSArray *tempLayers = (NSArray *)layersValue; - // Further check if the array contains only NSString objects - BOOL allStrings = YES; - for (id item in tempLayers) { - if (![item isKindOfClass:[NSString class]]) { - allStrings = NO; - break; - } - } - if (allStrings) { - layers = tempLayers; - } - } + NSArray *layers = [self getArrayValueForKey:argsDict key:@"layers"]; - NSDictionary *locationDict = nil; - id locationDictValue = argsDict[@"location"]; - if (locationDictValue != nil && [locationDictValue isKindOfClass:[NSDictionary class]]) { - locationDict = (NSDictionary *)locationDictValue; - } - if (locationDict) { + NSDictionary *locationDict = [self getDictionaryValueForKey:argsDict key:@"location"]; + + if (locationDict) { NSNumber *latitudeNumber = locationDict[@"latitude"]; NSNumber *longitudeNumber = locationDict[@"longitude"]; double latitude = [latitudeNumber doubleValue]; @@ -832,7 +825,7 @@ - (void)getDistance:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; CLLocation *origin; - NSDictionary *originDict = argsDict[@"origin"]; + NSDictionary *originDict = [self getDictionaryValueForKey:argsDict key:@"origin"]; if (originDict) { NSNumber *originLatitudeNumber = originDict[@"latitude"]; NSNumber *originLongitudeNumber = originDict[@"longitude"]; @@ -840,13 +833,14 @@ - (void)getDistance:(FlutterMethodCall *)call withResult:(FlutterResult)result { double originLongitude = [originLongitudeNumber doubleValue]; origin = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(originLatitude, originLongitude) altitude:-1 horizontalAccuracy:5 verticalAccuracy:-1 timestamp:[NSDate date]]; } - NSDictionary *destinationDict = argsDict[@"destination"]; + NSDictionary *destinationDict = [self getDictionaryValueForKey:argsDict key:@"destination"]; NSNumber *destinationLatitudeNumber = destinationDict[@"latitude"]; NSNumber *destinationLongitudeNumber = destinationDict[@"longitude"]; double destinationLatitude = [destinationLatitudeNumber doubleValue]; double destinationLongitude = [destinationLongitudeNumber doubleValue]; CLLocation *destination = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(destinationLatitude, destinationLongitude) altitude:-1 horizontalAccuracy:5 verticalAccuracy:-1 timestamp:[NSDate date]]; - NSArray *modesArr = argsDict[@"modes"]; + + NSArray *modesArr = [self getArrayValueForKey:argsDict key:@"modes"]; RadarRouteMode modes = 0; if (modesArr != nil) { if ([modesArr containsObject:@"FOOT"] || [modesArr containsObject:@"foot"]) { @@ -861,7 +855,8 @@ - (void)getDistance:(FlutterMethodCall *)call withResult:(FlutterResult)result { } else { modes = RadarRouteModeCar; } - NSString *unitsStr = argsDict[@"units"]; + + NSString *unitsStr = [self getStringValueForKey:argsDict key:@"units"]; RadarRouteUnits units; if (unitsStr != nil && [unitsStr isKindOfClass:[NSString class]]) { units = [unitsStr isEqualToString:@"METRIC"] || [unitsStr isEqualToString:@"metric"] ? RadarRouteUnitsMetric : RadarRouteUnitsImperial; @@ -890,8 +885,8 @@ - (void)logConversion:(FlutterMethodCall *)call withResult:(FlutterResult)result NSDictionary *argsDict = call.arguments; - NSDictionary *metadata = argsDict[@"metadata"]; - NSString *name = argsDict[@"name"]; + NSDictionary *metadata = [self getDictionaryValueForKey:argsDict key:@"metadata"]; + NSString *name = [self getStringValueForKey:argsDict key:@"name"]; NSNumber *revenueNumber = argsDict[@"revenue"]; if (revenueNumber != nil && [revenueNumber isKindOfClass:[NSNumber class]]) { [Radar logConversionWithName:name revenue:revenueNumber metadata:metadata completionHandler:completionHandler]; @@ -918,7 +913,7 @@ - (void)logResigningActive:(FlutterResult)result { - (void)getMatrix:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - NSArray *originsArr = argsDict[@"origins"]; + NSArray *originsArr = [self getArrayValueForKey:argsDict key:@"origins"]; NSMutableArray *origins = [NSMutableArray new]; for (NSDictionary *originDict in originsArr) { NSNumber *latitudeNumber = originDict[@"latitude"]; @@ -930,7 +925,7 @@ - (void)getMatrix:(FlutterMethodCall *)call withResult:(FlutterResult)result { CLLocation *origin = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) altitude:-1 horizontalAccuracy:accuracy verticalAccuracy:-1 timestamp:[NSDate date]]; [origins addObject:origin]; } - NSArray *destinationsArr = argsDict[@"destinations"]; + NSArray *destinationsArr = [self getArrayValueForKey:argsDict key:@"destinations"]; NSMutableArray *destinations = [NSMutableArray new]; for (NSDictionary *destinationDict in destinationsArr) { NSNumber *latitudeNumber = destinationDict[@"latitude"]; @@ -942,7 +937,7 @@ - (void)getMatrix:(FlutterMethodCall *)call withResult:(FlutterResult)result { CLLocation *destination = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) altitude:-1 horizontalAccuracy:accuracy verticalAccuracy:-1 timestamp:[NSDate date]]; [destinations addObject:destination]; } - NSString *modeStr = argsDict[@"mode"]; + NSString *modeStr = [self getStringValueForKey:argsDict key:@"mode"]; RadarRouteMode mode = RadarRouteModeCar; if ([modeStr isEqualToString:@"FOOT"] || [modeStr isEqualToString:@"foot"]) { mode = RadarRouteModeFoot; @@ -955,7 +950,7 @@ - (void)getMatrix:(FlutterMethodCall *)call withResult:(FlutterResult)result { } else if ([modeStr isEqualToString:@"MOTORBIKE"] || [modeStr isEqualToString:@"motorbike"]) { mode = RadarRouteModeMotorbike; } - NSString *unitsStr = argsDict[@"units"]; + NSString *unitsStr = [self getStringValueForKey:argsDict key:@"units"]; RadarRouteUnits units; if (unitsStr != nil && [unitsStr isKindOfClass:[NSString class]]) { units = [unitsStr isEqualToString:@"METRIC"] || [unitsStr isEqualToString:@"metric"] ? RadarRouteUnitsMetric : RadarRouteUnitsImperial; @@ -976,11 +971,7 @@ - (void)getMatrix:(FlutterMethodCall *)call withResult:(FlutterResult)result { - (void)trackVerified:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSDictionary *argsDict = call.arguments; - BOOL beacons = NO; - NSNumber *beaconsNumber = argsDict[@"beacons"]; - if (beaconsNumber != nil && [beaconsNumber isKindOfClass:[NSNumber class]]) { - beacons = [beaconsNumber boolValue]; - } + BOOL beacons = [self getBoolValueForKey:argsDict key:@"beacons" defaultValue:NO]; RadarTrackVerifiedCompletionHandler completionHandler = ^(RadarStatus status, RadarVerifiedLocationToken* token) { if (status == RadarStatusSuccess) { @@ -1007,7 +998,7 @@ - (void)validateAddress:(FlutterMethodCall *)call withResult:(FlutterResult)resu NSDictionary *argsDict = call.arguments; - NSDictionary *addressDict = argsDict[@"address"]; + NSDictionary *addressDict = [self getDictionaryValueForKey:argsDict key:@"address"]; RadarAddress *address = [RadarAddress addressFromObject:addressDict]; [Radar validateAddress:address completionHandler:completionHandler]; } diff --git a/lib/flutter_radar.dart b/lib/flutter_radar.dart index 7eabb41..aac4a6c 100644 --- a/lib/flutter_radar.dart +++ b/lib/flutter_radar.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:ffi'; import 'package:flutter/services.dart'; import 'dart:ui'; import 'package:flutter/material.dart'; @@ -23,10 +24,12 @@ void callbackDispatcher() { class Radar { static const MethodChannel _channel = const MethodChannel('flutter_radar'); - static Future initialize(String publishableKey) async { + static Future initialize( + {required String publishableKey, bool fraud = false}) async { try { await _channel.invokeMethod('initialize', { 'publishableKey': publishableKey, + 'fraud': fraud, }); } on PlatformException catch (e) { print(e); @@ -52,7 +55,7 @@ class Radar { } } - static Future setLogLevel(String logLevel) async { + static Future setLogLevel({required String logLevel}) async { try { await _channel.invokeMethod('setLogLevel', {'logLevel': logLevel}); } on PlatformException catch (e) { @@ -64,7 +67,7 @@ class Radar { return await _channel.invokeMethod('getPermissionsStatus'); } - static Future requestPermissions(bool background) async { + static Future requestPermissions({required bool background}) async { try { return await _channel .invokeMethod('requestPermissions', {'background': background}); @@ -73,7 +76,7 @@ class Radar { } } - static Future setUserId(String userId) async { + static Future setUserId({required String userId}) async { try { await _channel.invokeMethod('setUserId', {'userId': userId}); } on PlatformException catch (e) { @@ -85,7 +88,7 @@ class Radar { return await _channel.invokeMethod('getUserId'); } - static Future setDescription(String description) async { + static Future setDescription({required String description}) async { try { await _channel .invokeMethod('setDescription', {'description': description}); @@ -98,7 +101,7 @@ class Radar { return await _channel.invokeMethod('getDescription'); } - static Future setMetadata(Map metadata) async { + static Future setMetadata({required Map metadata}) async { try { await _channel.invokeMethod('setMetadata', metadata); } on PlatformException catch (e) { @@ -110,7 +113,7 @@ class Radar { return await _channel.invokeMethod('getMetadata'); } - static Future setAnonymousTrackingEnabled(bool enabled) async { + static Future setAnonymousTrackingEnabled({required bool enabled}) async { try { await _channel .invokeMethod('setAnonymousTrackingEnabled', {'enabled': enabled}); @@ -119,7 +122,7 @@ class Radar { } } - static Future getLocation([String? accuracy]) async { + static Future getLocation({String? accuracy}) async { try { return await _channel.invokeMethod('getLocation', {'accuracy': accuracy}); } on PlatformException catch (e) { @@ -129,6 +132,7 @@ class Radar { } static Future trackOnce( + // maybe type it more strongly in the future? {Map? location, String? desiredAccuracy, bool? beacons}) async { @@ -144,7 +148,7 @@ class Radar { } } - static Future startTracking(String preset) async { + static Future startTracking({required String preset}) async { try { await _channel.invokeMethod('startTracking', { 'preset': preset, @@ -154,7 +158,8 @@ class Radar { } } - static Future startTrackingCustom(Map options) async { + static Future startTrackingCustom( + {required Map options}) async { try { await _channel.invokeMethod('startTrackingCustom', options); } on PlatformException catch (e) { @@ -162,7 +167,8 @@ class Radar { } } - static Future startTrackingVerified(int interval, bool beacons) async { + static Future startTrackingVerified( + {required int interval, required bool beacons}) async { try { await _channel.invokeMethod( 'startTrackingVerified', {'interval': interval, 'beacons': beacons}); @@ -201,11 +207,11 @@ class Radar { } static Future mockTracking( - {Map? origin, - Map? destination, - String? mode, - int? steps, - int? interval}) async { + {required Map origin, + required Map destination, + required String mode, + required int steps, + required int interval}) async { try { return await _channel.invokeMethod('mockTracking', { 'origin': origin, @@ -221,7 +227,7 @@ class Radar { } static Future startTrip( - {Map? tripOptions, + {required Map tripOptions, Map? trackingOptions}) async { try { return await _channel.invokeMethod('startTrip', @@ -233,7 +239,7 @@ class Radar { } static Future updateTrip( - {required Map options, required String status}) async { + {required String status, required Map options}) async { try { return await _channel.invokeMethod( 'updateTrip', {'tripOptions': options, 'status': status}); @@ -265,7 +271,26 @@ class Radar { } } - static Future getContext(Map location) async { + static Future acceptEvent( + {required String eventId, String? VerifiedPlaceId}) async { + try { + _channel.invokeMethod('acceptEvent', + {'eventId': eventId, 'VerifiedPlaceId': VerifiedPlaceId}); + } on PlatformException catch (e) { + print(e); + } + } + + static Future rejectEvent({required String eventId}) async { + try { + _channel.invokeMethod('rejectEvent', {'eventId': eventId}); + } on PlatformException catch (e) { + print(e); + } + } + + static Future getContext( + {required Map location}) async { try { return await _channel.invokeMethod('getContext', {'location': location}); } on PlatformException catch (e) { @@ -274,6 +299,7 @@ class Radar { } } + // you have to pass in all or none of the parameters static Future searchGeofences( {Map? near, int? radius, @@ -297,9 +323,9 @@ class Radar { } static Future searchPlaces( - {Map? near, - int? radius, - int? limit, + {required int radius, + required limit, + Map? near, List? chains, Map? chainMetadata, List? categories, @@ -321,9 +347,9 @@ class Radar { } static Future autocomplete( - {String? query, + {required String query, + required int limit, Map? near, - int? limit, String? country, List? layers, bool? mailable}) async { @@ -342,10 +368,11 @@ class Radar { } } - static Future geocode(String query) async { + static Future geocode( + {required String query, List? layers, List? countries}) async { try { - final Map? geocodeResult = - await _channel.invokeMethod('forwardGeocode', {'query': query}); + final Map? geocodeResult = await _channel.invokeMethod('forwardGeocode', + {'query': query, 'layers': layers, 'countries': countries}); return geocodeResult; } on PlatformException catch (e) { print(e); @@ -356,11 +383,8 @@ class Radar { static Future reverseGeocode( {Map? location, List? layers}) async { try { - final Map arguments = { - 'location': location != null ? location : null, - 'layers': layers != null ? layers : null - }; - return await _channel.invokeMethod('reverseGeocode', arguments); + return await _channel.invokeMethod( + 'reverseGeocode', {'location': location, 'layers': layers}); } on PlatformException catch (e) { print(e); return {'error': e.code}; @@ -377,10 +401,10 @@ class Radar { } static Future getDistance( - {Map? origin, - Map? destination, - List? modes, - String? units}) async { + {required Map destination, + required List modes, + required String units, + Map? origin}) async { try { return await _channel.invokeMethod('getDistance', { 'origin': origin, @@ -397,7 +421,7 @@ class Radar { static Future logConversion( {required String name, double? revenue, - required Map metadata}) async { + Map? metadata}) async { try { return await _channel.invokeMethod('logConversion', {'name': name, 'revenue': revenue, 'metadata': metadata}); @@ -434,7 +458,7 @@ class Radar { // Android only static Future setNotificationOptions( - Map notificationOptions) async { + {required Map notificationOptions}) async { try { await _channel.invokeMethod( 'setNotificationOptions', notificationOptions); @@ -444,10 +468,7 @@ class Radar { } static Future getMatrix( - {required List origins, - required List destinations, - required String mode, - required String units}) async { + { required List origins, required List destinations,required String mode, required String units}) async { try { return await _channel.invokeMethod('getMatrix', { 'origins': origins, @@ -461,8 +482,9 @@ class Radar { } } + //Android only static Future setForegroundServiceOptions( - Map foregroundServiceOptions) async { + {required Map foregroundServiceOptions}) async { try { await _channel.invokeMethod( 'setForegroundServiceOptions', foregroundServiceOptions); @@ -481,11 +503,20 @@ class Radar { } } + static Future getVerifiedLocationToken() async { + try { + return await _channel.invokeMethod('getVerifiedLocationToken'); + } on PlatformException catch (e) { + print(e); + return {'error': e.code}; + } + } + static Future isUsingRemoteTrackingOptions() async { return await _channel.invokeMethod('isUsingRemoteTrackingOptions'); } - static Future validateAddress(Map address) async { + static Future validateAddress({required Map address}) async { try { return await _channel .invokeMethod('validateAddress', {'address': address}); From 0a9b8d5a1e9049941ab4a4f077ea128ad0f6d1f2 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 22 Jul 2024 13:21:28 -0400 Subject: [PATCH 16/16] fixes to unpacking --- .../io/radar/flutter/RadarFlutterPlugin.java | 64 +++++++++++-------- example/lib/main.dart | 1 + 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index 6507ceb..95fb159 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -629,15 +629,18 @@ public void run() { } else { RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.MEDIUM; boolean beaconsTrackingOption = getBooleanFromMethodCall(call, "beacons", false); - String desiredAccuracy = (getStringFromMethodCall(call, "desiredAccuracy")).toLowerCase(); - if (desiredAccuracy.equals("none")) { - accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.NONE; - } else if (desiredAccuracy.equals("low")) { - accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.LOW; - } else if (desiredAccuracy.equals("medium")) { - accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.MEDIUM; - } else if (desiredAccuracy.equals("high")) { - accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.HIGH; + String desiredAccuracy = (getStringFromMethodCall(call, "desiredAccuracy")); + if (desiredAccuracy != null){ + desiredAccuracy = desiredAccuracy.toLowerCase(); + if (desiredAccuracy.equals("none")) { + accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.NONE; + } else if (desiredAccuracy.equals("low")) { + accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.LOW; + } else if (desiredAccuracy.equals("medium")) { + accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.MEDIUM; + } else if (desiredAccuracy.equals("high")) { + accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.HIGH; + } } Radar.trackOnce(accuracyLevel, beaconsTrackingOption, callback); @@ -687,13 +690,16 @@ public void mockTracking(MethodCall call, final Result result) { Location destination = locationForMap(destinationMap); String modeStr = getStringFromMethodCall(call, "mode"); Radar.RadarRouteMode mode = Radar.RadarRouteMode.CAR; - if (modeStr.equals("FOOT") || modeStr.equals("foot")) { - mode = Radar.RadarRouteMode.FOOT; - } else if (modeStr.equals("BIKE") || modeStr.equals("bike")) { - mode = Radar.RadarRouteMode.BIKE; - } else if (modeStr.equals("CAR") || modeStr.equals("car")) { - mode = Radar.RadarRouteMode.CAR; + if (modeStr != null) { + if (modeStr.equals("FOOT") || modeStr.equals("foot")) { + mode = Radar.RadarRouteMode.FOOT; + } else if (modeStr.equals("BIKE") || modeStr.equals("bike")) { + mode = Radar.RadarRouteMode.BIKE; + } else if (modeStr.equals("CAR") || modeStr.equals("car")) { + mode = Radar.RadarRouteMode.CAR; + } } + int steps = getIntFromMethodCall(call, "steps", 10); int interval = getIntFromMethodCall(call, "interval", 1); @@ -770,17 +776,19 @@ public void updateTrip(MethodCall call, Result result) throws JSONException { RadarTripOptions tripOptions = RadarTripOptions.fromJson(tripOptionsJson); String statusStr = getStringFromMethodCall(call, "status"); RadarTrip.RadarTripStatus status = RadarTrip.RadarTripStatus.UNKNOWN; - statusStr = statusStr.toLowerCase(); - if (statusStr.equals("started")) { - status = RadarTrip.RadarTripStatus.STARTED; - } else if (statusStr.equals("approaching")) { - status = RadarTrip.RadarTripStatus.APPROACHING; - } else if (statusStr.equals("arrived")) { - status = RadarTrip.RadarTripStatus.ARRIVED; - } else if (statusStr.equals("completed")) { - status = RadarTrip.RadarTripStatus.COMPLETED; - } else if (statusStr.equals("canceled")) { - status = RadarTrip.RadarTripStatus.CANCELED; + if (statusStr != null){ + statusStr = statusStr.toLowerCase(); + if (statusStr.equals("started")) { + status = RadarTrip.RadarTripStatus.STARTED; + } else if (statusStr.equals("approaching")) { + status = RadarTrip.RadarTripStatus.APPROACHING; + } else if (statusStr.equals("arrived")) { + status = RadarTrip.RadarTripStatus.ARRIVED; + } else if (statusStr.equals("completed")) { + status = RadarTrip.RadarTripStatus.COMPLETED; + } else if (statusStr.equals("canceled")) { + status = RadarTrip.RadarTripStatus.CANCELED; + } } Radar.updateTrip(tripOptions, status, new Radar.RadarTripCallback() { @@ -1167,7 +1175,7 @@ public void run() { Location origin = null; HashMap originMap = getHashMapFromMethodCall(call, "origin"); - if (call.hasArgument("origin")) { + if (originMap != null) { origin = locationForMap(originMap); } HashMap destinationMap = getHashMapFromMethodCall(call, "destination"); @@ -1222,7 +1230,7 @@ public void run() { }; String name = getStringFromMethodCall(call, "name"); - JSONObject metadataJson; + JSONObject metadataJson = null; HashMap metadataMap = getHashMapFromMethodCall(call, "metadata"); if (metadataMap == null) { metadataJson = jsonForMap(metadataMap); diff --git a/example/lib/main.dart b/example/lib/main.dart index f90cc65..67a003a 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -528,6 +528,7 @@ class _PermissionsState extends State { setState(() { _status = status; }); + print('Permissions status: $status'); } }