SDK Reference

The Radar SDK abstracts away cross-platform differences between location services, allowing you to add location context and tracking to your apps with just a few lines of code. You can use the SDK to track the user's location in the foreground, in the background, or both.

Note that you can use our toolkit apps for iOS and Android to test Radar before integrating the SDK, or to test your implementation of Radar side-by-side with a complete implementation.

Authentication

Authenticate using your publishable API keys, found on the Settings page. Use your Test Publishable key for testing and non-production environments. Use your Live Publishable key for production environments.

Note that you should always use your publishable API keys, which are restricted in scope, in the SDK. Do not use your secret API keys, which are unrestricted in scope, in any client-side code.

iOS

Learn how to integrate the iOS SDK below. You can also see the source and a detailed SDK reference on GitHub.

Configure Xcode project

To track the user's location in the foreground, you must add a string for the NSLocationWhenInUseUsageDescription key in your Info.plist file if you haven't already. This string will be displayed when prompting the user for foreground location permissions.

To track the user's location in the background, you must also add a string for the NSLocationAlwaysUsageDescription (iOS 10 and before) and NSLocationAlwaysAndWhenInUseUsageDescription (iOS 11 and later) keys in your Info.plist file if you haven't already. These strings will be displayed when prompting the user for background location permissions.

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Your iOS 11 and higher background location usage description goes here. e.g., "This app uses your location in the background to recommend places nearby."</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>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."</string>

<key>NSLocationWhenInUseUsageDescription</key>
<string>Your foreground location usage description goes here. e.g., "This app uses your location in the foreground to recommend places nearby."</string>

Then, in your project settings, go to Capabilities > Background Modes and turn on Background fetch.

If using RadarTrackingOptions.responsive, you should also turn on Location updates. Note that this requires additional justification during App Store review. Learn more below.

<key>UIBackgroundModes</key>
<array>
  <string>fetch</string>
  <string>location</string>
</array>

Add iOS SDK to project

The best way to add the SDK to your project is via CocoaPods or Carthage.

The SDK is small and typically adds less than 500 KB to your compiled app.

CocoaPods

For CocoaPods, add the following to your Podfile:

pod 'RadarSDK', '~> 3.0.0'

Then, run pod install.

Carthage

To include Radar as a github origin in Carthage, add the following to your Cartfile:

github "radarlabs/radar-sdk-ios" ~> 3.0.0

To include Radar as a binary origin in Carthage, add the following to your Cartfile:

binary "https://raw.githubusercontent.com/radarlabs/radar-sdk-ios/master/RadarSDK.json" ~> 3.0.0

Then, run carthage update and drag Build/iOS/RadarSDK.framework into the Linked Frameworks and Libraries section of your target. Do not add the framework as an input to your copy-frameworks run script.

Add manually

You can also add the SDK to your project manually, though this is not recommended. Download the current release, unzip the package, and drag RadarSDK.framework into your Xcode project. It will automatically appear in the Linked Frameworks and Libraries section of your project settings.

Dependencies

The SDK depends on Apple's CoreLocation framework (for location services). In your project settings, go to General > Linked Frameworks and Libraries and add CoreLocation if you haven't already.

The SDK currently supports iOS 10 and higher.

Integrate iOS SDK into app

Initialize SDK

Import the SDK:

Swift Objective-C

import RadarSDK
// modules enabled
@import RadarSDK;

// modules not enabled
#import <RadarSDK/RadarSDK.h>

Initialize the SDK in your AppDelegate class, on the main thread, before calling any other Radar methods. In application:didFinishLaunchingWithOptions:application(_:didFinishLaunchingWithOptions:), call:

Swift Objective-C

Radar.initialize(publishableKey: publishableKey)
[Radar initializeWithPublishableKey:publishableKey];

where publishableKey is a string containing your publishable API key.

Identify user

Until you identify the user, Radar will automatically identify the user by deviceId (IDFV).

To identify the user when logged in, call:

Swift Objective-C

Radar.setUserId(userId)
[Radar setUserId:userId];

where userId is a stable unique ID for the user.

Do not send any PII, like names, email addresses, or publicly available IDs, for userId. See privacy best practices for more information.

To set an optional dictionary of custom metadata for the user, call:

Swift Objective-C

Radar.setMetadata(metadata)
[Radar setMetadata:metadata];

where metadata is a dictionary with up to 16 keys and values of type string, boolean, or number.

Finally, to set an optional description for the user, displayed in the dashboard, call:

Swift Objective-C

Radar.setDescription(description)
[Radar setDescription:description];

You only need to call these methods once, as these settings will be persisted across app sessions.

Request permissions

Radar respects standard iOS location permissions. Before tracking the user's location, the user must have authorized location permissions for the app if they haven't already.

To track the user's location in the foreground, the app's location authorization status must be kCLAuthorizationStatusAuthorizedWhenInUseauthorizedWhenInUse or kCLAuthorizationStatusAuthorizedAlwaysauthorizedAlways.

To track the user's location in the background, the app's location authorization status must be kCLAuthorizationStatusAuthorizedAlwaysauthorizedAlways.

Learn more about requesting permissions here.

Swift Objective-C

self.locationManager = CLLocationManager()

// foreground
self.locationManager.requestWhenInUseAuthorization()

// background
self.locationManager.requestAlwaysAuthorization()
self.locationManager = [CLLocationManager new];

// foreground
[self.locationManager requestWhenInUseAuthorization];

// background
[self.locationManager requestAlwaysAuthorization];

Foreground tracking

Once you have initialized the SDK, you have identified the user, and the user has authorized foreground permissions, you can track the user's location in the foreground.

To track the user's location in the foreground, call:

Swift Objective-C

Radar.trackOnce { (status: RadarStatus, location: CLLocation?, events: [RadarEvent]?, user: RadarUser?) in
  // do something with location, events, user
}
[Radar trackOnceWithCompletionHandler:^(RadarStatus status, CLLocation *location, NSArray<RadarEvent *> *events, RadarUser *user) {
  // do something with location, events, user
}];

You may provide an optional completionHandler that receives the request status, the user's location, the events generated, if any, and the user. The request status can be:

  • RadarStatusSuccesssuccess: success
  • RadarStatusErrorPublishableKeyerrorPublishableKey: SDK not initialized
  • RadarStatusErrorPermissionserrorPermissions: location permissions not granted
  • RadarStatusErrorLocationerrorLocation: location services error or timeout (10 seconds)
  • RadarStatusErrorNetworkerrorNetwork: network error or timeout (10 seconds)
  • RadarStatusErrorBadRequesterrorBadRequest: bad request (missing or invalid params)
  • RadarStatusErrorUnauthorizederrorUnauthorized: unauthorized (invalid API key)
  • RadarStatusErrorPaymentRequirederrorPaymentRequired: payment required (organization disabled or usage exceeded)
  • RadarStatusErrorForbiddenerrorForbidden: forbidden (insufficient permissions)
  • RadarStatusErrorNotFounderrorNotFound: not found
  • RadarStatusErrorRateLimiterrorRateLimit: too many requests (rate limit exceeded)
  • RadarStatusErrorServererrorServer: internal server error
  • RadarStatusErrorUnknownerrorUnknown: unknown error

Note that these calls are subject to rate limits.

Background tracking

Once you have initialized the SDK and the user has authorized background permissions, you can start tracking the user's location in the background.

For background tracking, the SDK supports custom tracking options as well as three presets:

  • RadarTrackingOptions.efficient: A preset that uses the iOS visit monitoring service to update only on stops and exits. Must move a significant distance to start moving again after a stop. Lowest battery usage.
  • RadarTrackingOptions.responsive: Updates about every 2.5 minutes when moving, shuts down when stopped, and only syncs stops and exits to the server. Requires the location background mode. Must move at least 200 meters to start moving again after a stop. Low battery usage.
  • RadarTrackingOptions.continuous: A preset that updates about every 30 seconds and syncs all locations to the server. High battery usage. Shows the flashing blue status bar when tracking.

Note that location updates may be delayed significantly by Low Power Mode, or if the device has connectivity issues, low battery, or wi-fi disabled.

To start tracking the user's location in the background, call one of:

Swift Objective-C

// efficient
Radar.startTracking(RadarTrackingOptions.efficient)

// responsive
Radar.startTracking(RadarTrackingOptions.responsive)

// continuous
Radar.startTracking(RadarTrackingOptions.continuous)
// efficient
[Radar startTrackingWithOptions:RadarTrackingOptions.efficient];

// responsive
[Radar startTrackingWithOptions:RadarTrackingOptions.responsive];

// continuous
[Radar startTrackingWithOptions:RadarTrackingOptions.continuous];

You only need to call this method once, as these settings will be persisted across app sessions.

Though we recommend using presets for most use cases, you can modify the presets. See the tracking options reference.

To stop tracking the user's location in the background (e.g., when the user logs out), call:

Swift Objective-C

Radar.stopTracking()
[Radar stopTracking];

Delegate

To listen for events, location updates, and errors client-side, create a class that implements RadarDelegate, then call setDelegate:setDelegate().

Set your RadarDelegate in a codepath that will be initialized and executed in the background. For example, make your AppDelegate implement RadarDelegate, not a ViewController. AppDelegate will be initialized in the background, whereas a ViewController may not be.

Swift Objective-C

class AppDelegate: UIResponder, UIApplicationDelegate, RadarDelegate {

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    Radar.initialize(publishableKey: publishableKey)
    Radar.setDelegate(self)

    return true
  }

  func didReceiveEvents(_ events: [RadarEvent], user: RadarUser) {
    // do something with events, user
  }

  func didUpdateLocation(_ location: CLLocation, user: RadarUser) {
    // do something with location, user
  }

  func didUpdateClientLocation(_ location: CLLocation, stopped: Bool, source: RadarLocationSource) {
    // do something with location, stopped, source
  }

  func didFail(status: RadarStatus) {
    // do something with status
  }

}
@interface AppDelegate : UIResponder <UIApplicationDelegate, RadarDelegate>

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [Radar initializeWithPublishableKey:publishableKey];
  [Radar setDelegate:self];

  return YES;
}

- (void)didReceiveEvents:(NSArray<RadarEvent *> *)events user:(RadarUser *)user {
  // do something with events, user
}

- (void)didUpdateLocation:(CLLocation *)location user:(RadarUser *)user {
  // do something with location, user
}

- (void)didUpdateClientLocation:(CLLocation *)location stopped:(BOOL)stopped source:(RadarLocationSource)source {
  // do something with location, stopped, source
}

- (void)didFailWithStatus:(RadarStatus)status {
  // do something with status
}

@end

To listen for events server-side instead, add a webhook.

Manual tracking

If you want to manage location services yourself, you can manually update the user's location instead by calling:

Swift Objective-C

Radar.trackOnce(
  location: location
) { (status: RadarStatus, location: CLLocation?, events: [RadarEvent]?, user: RadarUser?) in
  // do something with location, events, user
}
[Radar trackOnceWithLocation:location
           completionHandler:^(RadarStatus status, CLLocation *location, NSArray<RadarEvent *> *events, RadarUser *user) {
  // do something with location, events, user
}];

where location is a CLLocation instance with a valid latitude, longitude, and horizontal accuracy.

Note that these calls are subject to rate limits.

Verify events

You can accept or reject events after user check-ins or other forms of verification. Event verifications will be used to improve the accuracy and confidence level of future Insights and Places events.

Swift Objective-C

Radar.acceptEventId(event._id, verifiedPlaceId: event.alternatePlaces[0]._id)

Radar.rejectEventId(event._id)
[Radar acceptEventId:event._id withVerifiedPlaceId:event.alternatePlaces[0]._id];

[Radar rejectEventId:event._id];

Submit to App Store

Apple requires that you justify your use of background location. Add something materially similar to the following to the bottom of your App Store description: This app uses background location to (insert use case here). Continued use of background location may decrease battery life.

If you turned on the Location updates background mode, Apple requires additional justification. Add something materially similar to the following to your App Store review notes: This app uses the Radar SDK (https://radar.io) to (insert use case here). The Radar SDK requires the background location mode to support polygon geofences, home and work detection, and nearby place detection, which cannot be accomplished with region monitoring or visit monitoring.

Learn more about this requirement in section 2.5.4 of the App Store Review Guidelines here.

Other APIs for iOS

The iOS SDK also exposes APIs for anonymous context, geocoding, search, and distance.

Get location

Get a single location update without sending it to the server:

Swift Objective-C

Radar.getLocation { (status: RadarStatus, location: CLLocation?, stopped: Bool) in
  // do something with location
}
[Radar getLocationWithCompletionHandler:^(RadarStatus status, CLLocation *location, BOOL stopped) {
  // do something with location
}];

Context

With the context API, get context for a location without sending device or user identifiers to the server:

Swift Objective-C

Radar.getContext { (status: RadarStatus, location: CLLocation?, context: RadarContext?) in
  // do something with context
}
[Radar getContextWithCompletionHandler:^(RadarStatus status, CLLocation *location, RadarContext *context) {
  // do something with context
}];

Geocoding

With the forward geocoding API, geocode an address, converting address to coordinates:

Swift Objective-C

Radar.geocode(
  address: "20 jay st brooklyn ny"
) { (status, addresses) in
  // do something with addresses
}
[Radar geocodeAddress:@"20 jay st brooklyn ny"
    completionHandler:^(RadarStatus status, NSArray<RadarAddress *> *addresses) {
  // do something with addresses
}];

With the reverse geocoding API, reverse geocode a location, converting coordinates to address:

Swift Objective-C

Radar.reverseGeocode(
  location: location
) { (status, addresses) in
  // do something with addresses
}
[Radar reverseGeocodeLocation:location
            completionHandler:^(RadarStatus status, NSArray<RadarAddress *> *addresses) {
  // do something with addresses
}];

With the IP geocoding API, geocode the device's current IP address, converting IP address to city, state, and country:

Swift Objective-C

Radar.ipGeocode { (status, address) in
  // do something with address
}
[Radar ipGeocodeWithCompletionHandler:^(RadarStatus status, RadarAddress *address) {
  // do something with address
}];

With the autocomplete API, autocomplete partial addresses and place names, sorted by relevance:

Swift Objective-C

Radar.autocomplete(
  query: "brooklyn roasting",
  near: location,
  limit: 10
) { (status, addresses) in
  // do something with addresses
}
[Radar autocompleteQuery:@"brooklyn roasting"
                    near:location
                   limit:10
       completionHandler:^(RadarStatus status, NSArray<RadarAddress *> *addresses) {
  // do something with addresses
}];

With the geofence search API, search for geofences near a location, sorted by distance:

Swift Objective-C

Radar.searchGeofences(
  near: location,
  radius: 1000, // meters
  tags: ["store"],
  metadata: nil,
  limit: 10
) { (status, location, geofences) in
  // do something with geofences
}
[Radar searchGeofencesNear:location
                    radius:1000 // meters
                      tags:@[@"store"]
                  metadata:nil
                     limit:100
         completionHandler:^(RadarStatus status, CLLocation *location, NSArray<RadarGeofence *> *geofences) {
  // do something with geofences
}];

With the places search API, search for places near a location, sorted by distance:

Swift Objective-C

Radar.searchPlaces(
  near: location,
  radius: 1000, // meters
  chains: ["starbucks"],
  categories: nil,
  groups: nil,
  limit: 10
) { (status, location, places) in
  // do something with places
}
[Radar searchGeofencesNear:location
                    radius:1000 // meters
                    chains:@[@"starbucks"]
                categories:nil
                    groups:nil
                     limit:100
         completionHandler:^(RadarStatus status, CLLocation *location, NSArray<RadarPlace *> *places) {
  // do something with places
}];

Distance

With the distance API, calculate the travel distance and duration between two locations:

Swift Objective-C

Radar.getDistance(
  origin: origin,
  destination: destination,
  modes: [.foot, .car],
  units: .imperial
) { (status, routes) in
  // do something with routes
}
[Radar getDistanceFromOrigin:origin
                 destination:destination
                       modes:RadarRouteModeFoot | RadarRouteModeCar
                       units:RadarRouteUnitsImperial
           completionHandler:^(RadarStatus status, RadarRoutes *routes) {
  // do something with routes
}];

Android

You can also see the source and a detailed SDK reference.

Configure Android Studio project

Radar uses the Play Services Location library. If you haven't already configured your project for Play Services, follow the instructions here.

Radar requires the following permissions, added automatically by the SDK manifest:

  • ACCESS_FINE_LOCATION, for location services
  • INTERNET and ACCESS_NETWORK_STATE, to send API requests
  • RECEIVE_BOOT_COMPLETED, to restore geofences on boot

If targeting API level 29 or higher, to track the user's location in the background, you must also add the new ACCESS_BACKGROUND_LOCATION permission to your manifest. Learn more about location permissions changes in Android 10.

Add Android SDK to project

The best way to add the SDK to your project is via Gradle and JCenter in Android Studio. Add the SDK to the dependencies section of your build.gradle file:

dependencies {
  implementation 'io.radar:sdk:3.0.0'
}

The SDK depends on AndroidX (to check location permissions) and Play Services Location library version 17.0.0 and higher (for location services). These libraries will be automatically included as transitive dependencies. Learn more about managing dependencies in Gradle here.

You can also add the SDK to your project manually, though this is not recommended. Download the current release and unzip the package. The package contains an aar file. In Android Studio, add the SDK as a module using File > New Module > Import .JAR/.AAR Package.

The SDK currently supports API level 16 and higher.

The SDK is small and typically adds less than 500 KB to your compiled app.

Integrate Android SDK into app

Initialize SDK

Import the SDK:

Java Kotlin

import io.radar.sdk.Radar;
import io.radar.sdk.Radar

Initialize the SDK in your Application class before calling any other Radar methods. In onCreate(), call:

Java Kotlin

Radar.initialize(this, publishableKey);
Radar.initialize(this, publishableKey)

where publishableKey is a string containing your publishable API key.

Identify user

Until you identify the user, Radar will automatically identify the user by deviceId (Android ID).

To identify the user when logged in, call:

Java Kotlin

Radar.setUserId(userId);
Radar.setUserId(userId)

where userId is a stable unique ID for the user.

Do not send any PII, like names, email addresses, or publicly available IDs, for userId. See privacy best practices for more information.

To set an optional dictionary of custom metadata for the user, call:

Java Kotlin

Radar.setMetadata(metadata);
Radar.setMetadata(metadata)

where metadata is a JSONObject with up to 16 keys and values of type string, boolean, or number.

Finally, to set an optional description for the user, displayed in the dashboard, call:

Java Kotlin

Radar.setDescription(description);
Radar.setDescription(description)

You only need to call these methods once, as these settings will be persisted across app sessions.

Request permissions

Radar respects standard Android location permissions. Before tracking the user's location, the user must have granted location permissions for the app if they haven't already.

To track the user's location in the foreground, Radar requires the ACCESS_FINE_LOCATION permission. Learn more about requesting permissions here.

If targeting API level 29 or higher, to track the user's location in the background, Radar also requires the new ACCESS_BACKGROUND_LOCATION permission. Learn more about location permissions changes in Android 10.

Java Kotlin

// foreground only or targeting API level 28 and lower
ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, requestCode)

// background and targeting API level 29 and higher
ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION }, requestCode)
// foreground only or targeting API level 28 and lower
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), requestCode)

// background and targeting API level 29 and higher
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION), requestCode)

Foreground tracking

Once you have initialized the SDK, you have identified the user, and the user has granted permissions, you can track the user's location in the foreground.

To track the user's location in the foreground, call:

Java Kotlin

Radar.trackOnce(new RadarCallback() {
  @Override
  public void onComplete(RadarStatus status, Location location, RadarEvent[] events, RadarUser user) {
    // do something with location, events, user
  }
});
Radar.trackOnce { status, location, events, user ->
  // do something with location, events, user
}

You may provide an optional instance of RadarCallback with an implementation of onComplete() that receives the request status, the user's location, the events generated, if any, and the user. The request status can be:

  • RadarStatus.SUCCESS: success
  • RadarStatus.ERROR_PUBLISHABLE_KEY: SDK not initialized
  • RadarStatus.ERROR_PERMISSIONS: location permissions not granted
  • RadarStatus.ERROR_LOCATION: location services error or timeout (10 seconds)
  • RadarStatus.ERROR_NETWORK: network error or timeout (10 seconds)
  • RadarStatus.ERROR_BAD_REQUEST: bad request (missing or invalid params)
  • RadarStatus.ERROR_UNAUTHORIZED: unauthorized (invalid API key)
  • RadarStatus.ERROR_PAYMENT_REQUIRED: payment required (organization disabled or usage exceeded)
  • RadarStatus.ERROR_FORBIDDEN: forbidden (insufficient permissions)
  • RadarStatus.ERROR_NOT_FOUND: not found
  • RadarStatus.ERROR_RATE_LIMIT: too many requests (rate limit exceeded)
  • RadarStatus.ERROR_SERVER: internal server error
  • RadarStatus.ERROR_UNKNOWN: unknown error

Note that these calls are subject to rate limits.

Background tracking

Once you have initialized the SDK and the user has granted permissions, you can start tracking the user's location in the background.

For background tracking, the SDK supports custom tracking options as well as three presets:

  • RadarTrackingOptions.EFFICIENT: A preset that updates as fast as every 6 minutes while moving, periodically when stopped, and only syncs stops and exits to the server. Must move a significant distance to start moving again after a stop. Lowest battery usage and will not exceed Android vitals bad behavior thresholds. Recommended for most use cases.
  • RadarTrackingOptions.RESPONSIVE: A preset that updates as fast as every 2.5 minutes while moving, shuts down when stopped, and only syncs stops and exits to the server. Must move at least 200 meters to start moving again after a stop. Low battery usage, but may exceed Android vitals bad behavior thresholds for excessive wakeups and excessive wi-fi scans.
  • RadarTrackingOptions.CONTINUOUS: A preset that updates every 30 seconds and syncs all location updates to the server. High battery usage. Should be used with a foreground service.

Note that location updates may be delayed significantly by Doze Mode, App Standby, and Background Location Limits, or if the device has connectivity issues, low battery, or wi-fi disabled.

To start tracking the user's location in the background with default tracking options, call one of:

Java Kotlin

// efficient
Radar.startTracking(RadarTrackingOptions.EFFICIENT);

// responsive
Radar.startTracking(RadarTrackingOptions.RESPONSIVE);

// continuous
Radar.startTracking(RadarTrackingOptions.CONTINUOUS);
// efficient
Radar.startTracking(RadarTrackingOptions.EFFICIENT)

// responsive
Radar.startTracking(RadarTrackingOptions.RESPONSIVE)

// continuous
Radar.startTracking(RadarTrackingOptions.CONTINUOUS)

You only need to call this method once, as these settings will be persisted across app sessions.

Though we recommend using presets for most use cases, you can modify the presets. See the tracking options reference.

To stop tracking the user's location in the background (e.g., when the user logs out), call:

Java Kotlin

Radar.stopTracking();
Radar.stopTracking()

You only need to call these methods once, as these settings will be persisted across app sessions.

Receiver

To listen for events, location updates, and errors client-side, create a class that extends RadarReceiver. Then, register the receiver by adding a receiver element to the application element in your manifest:

<application android:label="@string/app_name">
  <receiver
      android:name=".MyRadarReceiver"
      android:enabled="true"
      android:exported="false">
      <intent-filter>
          <action android:name="io.radar.sdk.RECEIVED" />
      </intent-filter>
  </receiver>
</application>

Your receiver should implement the following:

Java Kotlin

public class MyRadarReceiver extends RadarReceiver {

  @Override
  public void onEventsReceived(Context context, RadarEvent[] events, RadarUser user) {
    // do something with events, user
  }

  @Override
  public void onLocationUpdated(Context context, Location location, RadarUser user) {
    // do something with location, user
  }

  @Override
  public void onClientLocationUpdated(Context context, Location location, boolean stopped, RadarLocationSource source) {
    // do something with location, stopped, source
  }

  @Override
  public void onError(Context context, RadarStatus status) {
    // do something with status
  }

}
class MyRadarReceiver: RadarReceiver() {

  override fun onEventsReceived(context: Context, events: Array<RadarEvent>, user: RadarUser) {
    // do something with events, user
  }

  override fun onLocationUpdated(context: Context, location: Location, user: RadarUser) {
    // do something with location, user
  }

  override fun onClientLocationUpdated(context: Context, location: Location, stopped: Boolean, source: RadarLocationSource) {
    // do something with location, stopped, source
  }

  override fun onError(context: Context, status: RadarStatus) {
    // do something with status
  }

}

To listen for events server-side instead, add a webhook.

Manual tracking

If you want to manage location services yourself, you can manually update the user's location instead by calling:

Java Kotlin

Radar.trackOnce(
  location,
  new RadarCallback() {
    @Override
    public void onComplete(RadarStatus status, Location location, RadarEvent[] events, RadarUser user) {
      // do something with location, events, user
    }
  }
);
Radar.trackOnce(location) { status, location, events, user ->
  // do something with location, events, user
}

where location is a Location instance with a valid latitude, longitude, and accuracy.

Note that these calls are subject to rate limits.

Verify events

You can accept or reject events after user check-ins or other forms of verification. Event verifications will be used to improve the accuracy and confidence level of future Insights and Places events.

Java Kotlin

Radar.acceptEvent(event.getId(), event.alternatePlaces[0].getId());

Radar.rejectEvent(event.getId());
Radar.acceptEvent(event.id, event.alternatePlaces[0].id)

Radar.rejectEvent(event.id)

Other APIs for Android

The Android SDK also exposes APIs for anonymous context, geocoding, search, and distance.

Get location

Get a single location update without sending it to the server:

Java Kotlin

Radar.getLocation(new RadarLocationCallback() {
  @Override
  public void onComplete(RadarStatus status, Location location, boolean stopped) {
    // do something with location
  }
});
Radar.getLocation { status, location, stopped ->
  // do something with location
}

Context

With the context API, get context for a location without sending device or user identifiers to the server:

Java Kotlin

Radar.getContext(new RadarContextCallback() {
  @Override
  public void onComplete(RadarStatus status, Location location, RadarContext context) {
    // do something with context
  }
});
Radar.getContext { status, location, context ->
  // do something with context
}

Geocoding

With the forward geocoding API, geocode an address, converting address to coordinates:

Java Kotlin

Radar.geocode(
  "20 jay street brooklyn ny", // query
  new RadarGeocodeCallback() {
    @Override
    public void onComplete(RadarStatus status, RadarAddress[] addresses) {
      // do something with addresses
    }
  }
);
Radar.geocode("20 jay street brooklyn ny") { status, addresses ->
  // do something with addresses
}

With the reverse geocoding API, reverse geocode a location, converting coordinates to address:

Java Kotlin

Radar.reverseGeocode(
  location,
  new RadarGeocodeCallback() {
    @Override
    public void onComplete(RadarStatus status, RadarAddress[] addresses) {
      // do something with addresses
    }
  }
);
Radar.reverseGeocode(location) { status, addresses ->
  // do something with addresses
}

With the IP geocoding API, geocode the device's current IP address, converting IP address to city, state, and country:

Java Kotlin

Radar.ipGeocode(new RadarIpGeocodeCallback() {
  @Override
  public void onComplete(RadarStatus status, RadarAddress address) {
    // do something with address
  }
});
Radar.ipGeocode { status, address ->
  // do something with address
}

Search

With the autocomplete API, autocomplete partial addresses and place names, sorted by relevance:

Java Kotlin

Radar.autocomplete(
  "brooklyn roasting", // query
  near,
  10, // limit
  new RadarGeocodeCallback() {
    @Override
    public void onComplete(RadarStatus status, RadarAddress[] addresses) {
      // do something with addresses
    }
  }
);
Radar.autocomplete(
  "brooklyn roasting", // query
  near,
  10 // limit
) { status, addresses ->
  // do something with addresses
}

With the geofence search API, search for geofences near a location, sorted by distance:

Java Kotlin

Radar.searchGeofences(
  near,
  1000, // radius (meters)
  {"store"}, // tags
  nil, //metadata
  10, // limit
  new RadarSearchGeofencesCallback() {
    @Override
    public void onComplete(RadarStatus status, Location location, RadarGeofence[] geofences) {
      // do something with geofences
    }
  }
);
Radar.searchGeofences(
  near,
  1000, // radius (meters)
  arrayOf("store"), // tags
  nil, // metadata
  10 // limit
) { status, location, geofences ->
  // do something with geofences
}

With the places search API, search for places near a location, sorted by distance:

Java Kotlin

Radar.searchPlaces(
  near,
  1000, // radius (meters)
  {"starbucks"}, // chains
  null, // categories
  null, //groups
  10, // limit
  new RadarSearchPlacesCallback() {
    @Override
    public void onComplete(RadarStatus status, Location location, RadarPlace[] places) {
      // do something with places
    }
  }
);
Radar.searchPlaces(
  near,
  1000, // radius (meters)
  arrayOf("starbucks"), // chains
  null, // categories
  null, // groups
  10 // limit
) { status, location, places ->
  // do something with places
}

Distance

With the distance API, calculate the travel distance and duration between two locations:

Java Kotlin

Radar.getDistance(
  origin,
  destination,
  EnumSet.of(RadarRouteMode.FOOT, RadarRouteMode.CAR),
  RadarRouteUnits.IMPERIAL,
  new RadarRouteCallback() {
    @Override
    public void onComplete(RadarStatus status, RadarRoutes routes) {
      // do something with routes
    }
  }
);
Radar.getDistance(
  origin,
  destination,
  EnumSet.of(RadarRouteMode.FOOT, RadarRouteMode.CAR),
  RadarRouteUnits.IMPERIAL
) { status, routes ->
  // do something with routes
}

Web

See the documentation here.

React Native

See the documentation here.

Capacitor

See the documentation and source on GitHub here.

Cordova

See the documentation here.