From 4166d15eeaf28ba152a1ce9e89bf142f16b5b706 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 27 Jun 2024 13:30:23 -0400 Subject: [PATCH 01/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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 d63612192777a1639d369427c6c6e987b33e54b0 Mon Sep 17 00:00:00 2001 From: KennyHuRadar <139801512+KennyHuRadar@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:13:23 -0400 Subject: [PATCH 15/21] add improve interface to 3.10.0 candidate (#59) * change interface and add safe unwrapping * fixes to unpacking --- .../io/radar/flutter/RadarFlutterPlugin.java | 418 ++++++---- example/lib/main.dart | 713 +++++++++--------- ios/Classes/RadarFlutterPlugin.m | 297 ++++---- lib/flutter_radar.dart | 120 +-- 4 files changed, 859 insertions(+), 689 deletions(-) diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index 26289d7..93a28f8 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; @@ -83,7 +85,7 @@ public class RadarFlutterPlugin implements FlutterPlugin, MethodCallHandler, Act private static final int PERMISSIONS_REQUEST_CODE = 20160525; private Result mPermissionsRequestResult; - + @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { mContext = binding.getApplicationContext(); @@ -228,6 +230,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; @@ -239,7 +247,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; @@ -288,20 +296,104 @@ 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-beta.1"); editor.apply(); - Radar.initialize(mContext, publishableKey); + Radar.initialize(mContext, publishableKey, null, Radar.RadarLocationServicesProvider.GOOGLE, fraud); Radar.setReceiver(new RadarFlutterReceiver(channel)); Radar.setVerifiedReceiver(new RadarFlutterVerifiedReceiver(channel)); 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); @@ -309,15 +401,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")) { @@ -334,20 +427,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"; @@ -360,21 +454,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); } @@ -385,7 +485,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); } @@ -396,7 +496,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); @@ -406,13 +506,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); } @@ -442,7 +542,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")) { @@ -459,7 +559,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() { @@ -475,7 +576,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) { @@ -485,17 +586,17 @@ 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(); + boolean beaconsTrackingOption = getBooleanFromMethodCall(call, "beacons", false); + String desiredAccuracy = (getStringFromMethodCall(call, "desiredAccuracy")); + if (desiredAccuracy != null){ + desiredAccuracy = desiredAccuracy.toLowerCase(); if (desiredAccuracy.equals("none")) { accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.NONE; } else if (desiredAccuracy.equals("low")) { @@ -506,16 +607,13 @@ public void run() { accuracyLevel = RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.HIGH; } } - 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"); + String preset = getStringFromMethodCall(call, "preset"); if (preset == null) { Radar.startTracking(RadarTrackingOptions.RESPONSIVE); } else if (preset.equals("continuous")) { @@ -531,7 +629,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); @@ -539,8 +637,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); } @@ -551,26 +649,29 @@ 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; - } 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 = 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) { - + } }); } @@ -585,21 +686,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) { @@ -608,8 +709,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() { @@ -635,29 +736,31 @@ 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")) { - 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() { @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() { @@ -684,7 +787,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); } @@ -692,8 +795,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() { @@ -722,8 +825,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() { @@ -748,10 +851,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() { @@ -774,9 +891,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 { @@ -787,7 +903,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() { @@ -812,17 +929,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); @@ -859,19 +976,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); @@ -881,14 +995,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 @@ -915,9 +1028,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() { @@ -929,7 +1042,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) { @@ -965,10 +1078,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 { @@ -1027,15 +1139,14 @@ public void run() { }; Location origin = null; - if (call.hasArgument("origin")) { - HashMap originMap = (HashMap)call.argument("origin"); + HashMap originMap = getHashMapFromMethodCall(call, "origin"); + if (originMap != null) { 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); @@ -1047,8 +1158,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); @@ -1057,7 +1170,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) { @@ -1070,7 +1183,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) { @@ -1081,11 +1194,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 = null; + 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); @@ -1103,7 +1219,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)); @@ -1113,11 +1229,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; @@ -1129,8 +1245,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 @@ -1157,7 +1275,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 @@ -1191,7 +1309,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() { @@ -1215,21 +1334,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; @@ -1305,9 +1424,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 { JSONObject obj = new JSONObject(); obj.put("location", Radar.jsonForLocation(location)); @@ -1315,7 +1434,6 @@ public void onClientLocationUpdated(Context context, Location location, boolean obj.put("source", source.toString()); HashMap res = new Gson().fromJson(obj.toString(), HashMap.class); - final ArrayList clientLocationArgs = new ArrayList(); clientLocationArgs.add(0); clientLocationArgs.add(res); @@ -1331,7 +1449,7 @@ public void run() { Log.e(TAG, e.toString()); } } - + @Override public void onError(Context context, Radar.RadarStatus status) { try { @@ -1354,7 +1472,7 @@ public void run() { Log.e(TAG, e.toString()); } } - + @Override public void onLog(Context context, String message) { try { @@ -1378,7 +1496,7 @@ public void run() { } } } - + public static class RadarFlutterVerifiedReceiver extends RadarVerifiedReceiver { private MethodChannel channel; @@ -1390,7 +1508,6 @@ public static class RadarFlutterVerifiedReceiver extends RadarVerifiedReceiver { @Override public void onTokenUpdated(Context context, RadarVerifiedLocationToken token) { try { - JSONObject obj = new JSONObject(); obj.put("token", token.toJson()); @@ -1413,5 +1530,4 @@ public void run() { } } - }; diff --git a/example/lib/main.dart b/example/lib/main.dart index b56d490..de1d35c 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.onLocation(onLocation); Radar.onClientLocation(onClientLocation); @@ -82,13 +81,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'); @@ -100,352 +99,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'), + ), + ]), + )), )); } } @@ -496,6 +526,7 @@ class _PermissionsState extends State { setState(() { _status = status; }); + print('Permissions status: $status'); } } diff --git a/ios/Classes/RadarFlutterPlugin.m b/ios/Classes/RadarFlutterPlugin.m index fd6a396..51c71a1 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]) { @@ -135,10 +139,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-beta.1" forKey:@"radar-xPlatformSDKVersion"]; [Radar initializeWithPublishableKey:publishableKey]; @@ -148,7 +198,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"]) { @@ -199,9 +249,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]; @@ -215,7 +264,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); } @@ -228,7 +277,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); } @@ -252,8 +301,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); } @@ -272,7 +320,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"]) { @@ -306,8 +354,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"]; @@ -318,11 +366,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; @@ -332,13 +380,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]; } } @@ -346,7 +388,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"]) { @@ -371,17 +413,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); @@ -415,19 +449,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; @@ -436,20 +476,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]; } @@ -469,9 +497,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]; @@ -495,9 +523,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"]) { @@ -558,6 +586,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]; @@ -573,7 +616,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"]; @@ -606,7 +649,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"]; @@ -614,28 +657,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]; @@ -662,7 +692,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"]; @@ -670,25 +700,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 { @@ -699,9 +720,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"]; @@ -709,15 +730,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]; @@ -728,20 +745,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"]; @@ -764,29 +775,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]; @@ -824,7 +817,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"]; @@ -832,13 +825,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"]) { @@ -853,7 +847,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; @@ -882,8 +877,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]; @@ -910,7 +905,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"]; @@ -922,7 +917,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"]; @@ -934,7 +929,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; @@ -947,7 +942,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; @@ -968,11 +963,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) { @@ -999,7 +990,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 8d4cdac..78a7974 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'; @@ -39,10 +40,13 @@ class Radar { static EventsCallback? foregroundEventsCallback; static TokenCallback? foregroundTokenCallback; - 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, }); _channel.setMethodCallHandler(_handleMethodCall); } on PlatformException catch (e) { @@ -76,7 +80,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) { @@ -88,7 +92,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}); @@ -97,7 +101,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) { @@ -109,7 +113,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}); @@ -122,7 +126,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) { @@ -134,7 +138,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}); @@ -143,7 +147,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) { @@ -153,6 +157,7 @@ class Radar { } static Future trackOnce( + // maybe type it more strongly in the future? {Map? location, String? desiredAccuracy, bool? beacons}) async { @@ -168,7 +173,7 @@ class Radar { } } - static Future startTracking(String preset) async { + static Future startTracking({required String preset}) async { try { await _channel.invokeMethod('startTracking', { 'preset': preset, @@ -178,7 +183,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) { @@ -186,7 +192,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}); @@ -225,11 +232,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, @@ -245,7 +252,7 @@ class Radar { } static Future startTrip( - {Map? tripOptions, + {required Map tripOptions, Map? trackingOptions}) async { try { return await _channel.invokeMethod('startTrip', @@ -257,7 +264,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}); @@ -289,7 +296,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) { @@ -298,6 +324,7 @@ class Radar { } } + // you have to pass in all or none of the parameters static Future searchGeofences( {Map? near, int? radius, @@ -321,9 +348,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, @@ -345,9 +372,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 { @@ -366,10 +393,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); @@ -380,11 +408,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}; @@ -401,10 +426,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, @@ -421,7 +446,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}); @@ -458,7 +483,7 @@ class Radar { // Android only static Future setNotificationOptions( - Map notificationOptions) async { + {required Map notificationOptions}) async { try { await _channel.invokeMethod( 'setNotificationOptions', notificationOptions); @@ -468,10 +493,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, @@ -485,8 +507,9 @@ class Radar { } } + //Android only static Future setForegroundServiceOptions( - Map foregroundServiceOptions) async { + {required Map foregroundServiceOptions}) async { try { await _channel.invokeMethod( 'setForegroundServiceOptions', foregroundServiceOptions); @@ -505,11 +528,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 fa0eda2450fe89b7e3f11a2511a5d1c86599ffc0 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 22 Jul 2024 15:24:32 -0400 Subject: [PATCH 16/21] bump beta version --- CHANGELOG.md | 2 +- android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java | 2 +- ios/Classes/RadarFlutterPlugin.m | 2 +- ios/flutter_radar.podspec | 2 +- pubspec.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92c9114..776ad05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 3.10.0-beta.1 +# 3.10.0-beta.2 - Bump iOS version from 3.9.14 to 3.15.0 - Bump Android version from 3.9.8 to 3.15.0 diff --git a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java index 93a28f8..f7a5a12 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -384,7 +384,7 @@ private void initialize(MethodCall call, Result result) { 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-beta.1"); + editor.putString("x_platform_sdk_version", "3.10.0-beta.2"); editor.apply(); Radar.initialize(mContext, publishableKey, null, Radar.RadarLocationServicesProvider.GOOGLE, fraud); Radar.setReceiver(new RadarFlutterReceiver(channel)); diff --git a/ios/Classes/RadarFlutterPlugin.m b/ios/Classes/RadarFlutterPlugin.m index 51c71a1..a816f96 100644 --- a/ios/Classes/RadarFlutterPlugin.m +++ b/ios/Classes/RadarFlutterPlugin.m @@ -190,7 +190,7 @@ - (void)initialize:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSString *publishableKey = [self getStringValueForKey:argsDict key:@"publishableKey"]; [[NSUserDefaults standardUserDefaults] setObject:@"Flutter" forKey:@"radar-xPlatformSDKType"]; - [[NSUserDefaults standardUserDefaults] setObject:@"3.10.0-beta.1" forKey:@"radar-xPlatformSDKVersion"]; + [[NSUserDefaults standardUserDefaults] setObject:@"3.10.0-beta.2" forKey:@"radar-xPlatformSDKVersion"]; [Radar initializeWithPublishableKey:publishableKey]; result(nil); } diff --git a/ios/flutter_radar.podspec b/ios/flutter_radar.podspec index 87e11ed..e506461 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-beta.1' + s.version = '3.10.0-beta.2' 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 ed958f9..fc4bb92 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-beta.1 +version: 3.10.0-beta.2 homepage: https://github.com/radarlabs/flutter-radar environment: From 732d7dc2ba38fdc069ef3f2da3568caf2285869c Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Mon, 22 Jul 2024 15:32:00 -0400 Subject: [PATCH 17/21] remove unused inport --- lib/flutter_radar.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/flutter_radar.dart b/lib/flutter_radar.dart index 78a7974..2aa0fd4 100644 --- a/lib/flutter_radar.dart +++ b/lib/flutter_radar.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:ffi'; import 'package:flutter/services.dart'; import 'dart:ui'; import 'package:flutter/material.dart'; From 04e57a38acf3caf877eb2ed022789836d31adbea Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 1 Aug 2024 12:25:56 -0400 Subject: [PATCH 18/21] bump version --- CHANGELOG.md | 6 +++--- android/build.gradle | 2 +- .../src/main/java/io/radar/flutter/RadarFlutterPlugin.java | 2 +- example/android/app/build.gradle | 2 +- ios/Classes/RadarFlutterPlugin.m | 2 +- ios/flutter_radar.podspec | 4 ++-- pubspec.yaml | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 776ad05..0d1131d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ -# 3.10.0-beta.2 +# 3.10.0-beta.3 -- Bump iOS version from 3.9.14 to 3.15.0 -- Bump Android version from 3.9.8 to 3.15.0 +- Bump iOS version from 3.9.14 to 3.16.0-beta.1 +- Bump Android version from 3.9.8 to 3.16.0-beta.1 # 3.9.1 diff --git a/android/build.gradle b/android/build.gradle index 77e9a78..fb6ece6 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -34,7 +34,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.15.0' + implementation 'io.radar:sdk:3.16.0-beta.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 f7a5a12..baef92d 100644 --- a/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java +++ b/android/src/main/java/io/radar/flutter/RadarFlutterPlugin.java @@ -384,7 +384,7 @@ private void initialize(MethodCall call, Result result) { 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-beta.2"); + editor.putString("x_platform_sdk_version", "3.10.0-beta.3"); editor.apply(); Radar.initialize(mContext, publishableKey, null, Radar.RadarLocationServicesProvider.GOOGLE, fraud); Radar.setReceiver(new RadarFlutterReceiver(channel)); diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index aa55010..5734be8 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -49,7 +49,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.15.0' + implementation 'io.radar:sdk:3.16.0-beta.1' implementation "com.google.android.play:integrity:1.2.0" } } diff --git a/ios/Classes/RadarFlutterPlugin.m b/ios/Classes/RadarFlutterPlugin.m index a816f96..1c6785e 100644 --- a/ios/Classes/RadarFlutterPlugin.m +++ b/ios/Classes/RadarFlutterPlugin.m @@ -190,7 +190,7 @@ - (void)initialize:(FlutterMethodCall *)call withResult:(FlutterResult)result { NSString *publishableKey = [self getStringValueForKey:argsDict key:@"publishableKey"]; [[NSUserDefaults standardUserDefaults] setObject:@"Flutter" forKey:@"radar-xPlatformSDKType"]; - [[NSUserDefaults standardUserDefaults] setObject:@"3.10.0-beta.2" forKey:@"radar-xPlatformSDKVersion"]; + [[NSUserDefaults standardUserDefaults] setObject:@"3.10.0-beta.3" forKey:@"radar-xPlatformSDKVersion"]; [Radar initializeWithPublishableKey:publishableKey]; result(nil); } diff --git a/ios/flutter_radar.podspec b/ios/flutter_radar.podspec index e506461..5b944f0 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-beta.2' + s.version = '3.10.0-beta.3' 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.15.0' + s.dependency 'RadarSDK', '3.16.0-beta.1' s.platform = :ios, '10.0' s.static_framework = true diff --git a/pubspec.yaml b/pubspec.yaml index fc4bb92..5268b74 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-beta.2 +version: 3.10.0-beta.3 homepage: https://github.com/radarlabs/flutter-radar environment: From f1aa1c768970418c0a566a6499312736b7016c08 Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 1 Aug 2024 12:27:33 -0400 Subject: [PATCH 19/21] add ios permission --- example/ios/Runner/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index 921a5e5..d5e775a 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -28,6 +28,8 @@ Your iOS 10 and lower background location usage description goes here. e.g., "This app uses your location in the background to recommend places nearby." NSLocationWhenInUseUsageDescription Your foreground location usage description goes here. e.g., "This app uses your location in the foreground to recommend places nearby." + NSMotionUsageDescription + Your motion usage description goes here. UIBackgroundModes fetch From 36c35a16a0e405a5d21842636b67997c5462e7ad Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 1 Aug 2024 12:28:59 -0400 Subject: [PATCH 20/21] add android permission --- example/android/app/src/main/AndroidManifest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index e97e15c..142a98c 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -52,4 +52,6 @@ + + From f561843e96bd504cd168d65c401c1cb4f01989ce Mon Sep 17 00:00:00 2001 From: Kenny Hu Date: Thu, 1 Aug 2024 12:56:43 -0400 Subject: [PATCH 21/21] change dep, dog fooded --- CHANGELOG.md | 4 ++-- android/build.gradle | 2 +- example/android/app/build.gradle | 2 +- example/ios/Runner.xcodeproj/project.pbxproj | 6 +++--- example/lib/main.dart | 16 +++++++++++++++- example/pubspec.yaml | 2 ++ ios/flutter_radar.podspec | 2 +- 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d1131d..de2ded1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # 3.10.0-beta.3 -- Bump iOS version from 3.9.14 to 3.16.0-beta.1 -- Bump Android version from 3.9.8 to 3.16.0-beta.1 +- Bump iOS version from 3.9.14 to 3.16.1-beta.1 +- Bump Android version from 3.9.8 to 3.16.1-beta.1 # 3.9.1 diff --git a/android/build.gradle b/android/build.gradle index fb6ece6..ef9cfbb 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -34,7 +34,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.16.0-beta.1' + implementation 'io.radar:sdk:3.16.1-beta.1' implementation 'com.google.android.gms:play-services-location:21.0.1' implementation 'com.google.code.gson:gson:2.8.6' } diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 5734be8..753b4d0 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -49,7 +49,7 @@ android { } dependencies { - implementation 'io.radar:sdk:3.16.0-beta.1' + implementation 'io.radar:sdk:3.16.1-beta.1' implementation "com.google.android.play:integrity:1.2.0" } } diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 9e54d3c..6f58db5 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -368,7 +368,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = U6493D9J45; + DEVELOPMENT_TEAM = 96GHH65B9D; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -501,7 +501,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = U6493D9J45; + DEVELOPMENT_TEAM = 96GHH65B9D; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -529,7 +529,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = U6493D9J45; + DEVELOPMENT_TEAM = 96GHH65B9D; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/example/lib/main.dart b/example/lib/main.dart index de1d35c..9634308 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'dart:async'; import 'package:flutter_radar/flutter_radar.dart'; +import 'package:permission_handler/permission_handler.dart'; void main() => runApp(MyApp()); @@ -174,6 +175,19 @@ class _MyAppState extends State with WidgetsBindingObserver { }, child: Text('completeTrip'), ), + ElevatedButton( + style: raisedButtonStyle, + onPressed: () async { + PermissionStatus status = + await Permission.activityRecognition.request(); + if (status.isGranted) { + print('Permission granted'); + } else { + print('Permission denied'); + } + }, + child: Text('request activity permissions'), + ), ElevatedButton( style: raisedButtonStyle, onPressed: () async { @@ -418,7 +432,7 @@ class _MyAppState extends State with WidgetsBindingObserver { ElevatedButton( style: raisedButtonStyle, onPressed: () async { - Map? resp = await Radar.validateAddress(address:{ + Map? resp = await Radar.validateAddress(address: { "city": "NEW YORK", "stateCode": "NY", "postalCode": "10003", diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 63b0bc9..09a7e05 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -24,6 +24,8 @@ dependencies: # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.5 + permission_handler: ^10.2.0 + dev_dependencies: flutter_test: sdk: flutter diff --git a/ios/flutter_radar.podspec b/ios/flutter_radar.podspec index 5b944f0..e60e593 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.16.0-beta.1' + s.dependency 'RadarSDK', '3.16.1-beta.1' s.platform = :ios, '10.0' s.static_framework = true