Radar abstracts away cross-platform differences between location services on iOS and Android, allowing you to add location tracking and geofencing to your apps with just a few lines of code.
In this playbook, we explain how Radar can power your location-aware hacks. You will learn how to:
Geofences represent custom regions or places monitored in your project. Depending on your use case, a geofence might represent your campus, buildings on your campus, and so on.
Let's create some geofences!
First, sign up for a Radar account here. To create a geofence via the dashboard, go to the Geofences page and click the New button.
You specify the metadata for geofences when you create them, including the tag (an optional group for the geofence, e.g., building
), external ID (an optional ID for the geofence, e.g., 123
), and description (a display name for the geofence, e.g., Building #123
).
Start by searching for an address or place. Enter a description, optional tag, optional external ID, and optional metadata. Choose circle to draw a circle geofence, or polygon to draw a polygon geofence. Click Create to create the geofence.
For example, we can create the following geofences:
Duke University
(tag campus
and external IDduke
)Perkins Library
(tag building
and external ID library
)Cameron Indoor Stadium
(tag building
and external ID basketball
)To use the geofences, let's install the SDK!
For iOS, follow the documentation here. To start:
Info.plist
After following these steps, your AppDelegate
class should look like this:
import UIKit
import RadarSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, RadarDelegate {
let locationManager = CLLocationManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// request permissions
locationManager.requestAlwaysAuthorization()
// initialize SDK (replace with your publishable API key)
Radar.initialize(publishableKey: "prj_test_pk_...")
// todo in steps 3 and 4
}
}
For Android, follow the documentation here. To start:
After following these steps, your MainActivity
class should look like this:
import android.Manifest
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import io.radar.sdk.Radar
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// request permissions
if (Build.VERSION.SDK_INT >= 23) {
val requestCode = 0
if (Build.VERSION.SDK_INT >= 29) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION), requestCode)
} else {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), requestCode)
}
}
// initialize SDK (replace with your publishable API key)
Radar.initialize("prj_test_pk_...")
// todo in steps 3 and 4
}
}
With geofences created and the SDK installed, we can now start adding location-aware features to our app!
You can call trackOnce()
to check if a user is inside a geofence when the app is in the foreground. Learn more about foreground tracking on iOS and on Android.
For example, to unlock a feature only when a user is on campus, on iOS:
Radar.trackOnce { (status, location, events, user) in
user?.geofences?.forEach { (geofence) in
if geofence.tag == "campus" {
// user is on campus, unlock feature
}
}
}
On Android:
Radar.trackOnce { status, location, events, user ->
user?.geofences?.forEach { geofence ->
if (geofence.tag == "campus") {
// user is on campus, unlock feature
}
}
}
Check the Users page and Events page to verify that tracking is working. If you don't see a user or don't see events, check the status in the callback.
You can also call startTracking()
to listen for geofence entry and exit events when the app is in the background. Learn more about background tracking on iOS and on Android.
Assuming you have configured your project properly, the SDK will wake up while the user is moving (usually every 3-5 minutes), then shut down when the user stops (usually within 5-10 minutes). To save battery, the SDK will not wake up when stopped, and the user must move at least 100 meters from a stop (sometimes more) to wake up the SDK.
To listen for events, set a RadarDelegate
on iOS and a RadarReceiver
on Android.
For example, to start tracking and trigger a notification when a user enters the library, on iOS:
import UIKit
import RadarSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, RadarDelegate {
let locationManager = CLLocationManager()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// request permissions
locationManager.requestAlwaysAuthorization()
// initialize SDK (replace with your publishable API key)
Radar.initialize(publishableKey: "prj_test_pk_...")
Radar.setDelegate(self)
// start tracking
let trackingOptions = RadarTrackingOptions()
trackingOptions.priority = .responsiveness
trackingOptions.offline = .replayStopped
trackingOptions.sync = .all
Radar.startTracking(trackingOptions)
}
func didReceiveEvents(_ events: [RadarEvent], user: RadarUser) {
events.forEach { (event) in
if event.type == .userEnteredGeofence && event.geofence?.tag == "building" && event.geofence?.externalId == "library" {
// user entered library, show notification
}
}
}
}
On Android:
<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>
import android.Manifest
import android.os.Build
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import io.radar.sdk.Radar
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// request permissions
if (Build.VERSION.SDK_INT >= 23) {
val requestCode = 0
if (Build.VERSION.SDK_INT >= 29) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION), requestCode)
} else {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), requestCode)
}
}
// initialize SDK (replace with your publishable API key)
Radar.initialize("prj_test_pk_...")
// start tracking
val trackingOptions : RadarTrackingOptions = RadarTrackingOptions.Builder()
.priority(RadarTrackingPriority.RESPONSIVENESS)
.offline(RadarTrackingOffline.REPLAY_STOPPED)
.sync(RadarTrackingSync.ALL)
.build()
Radar.startTracking(trackingOptions)
}
}
import io.radar.sdk.Radar
import io.radar.sdk.RadarReceiver
import io.radar.sdk.model.RadarEvent
import io.radar.sdk.model.RadarUser
class MyRadarReceiver : RadarReceiver() {
override fun onEventsReceived(context: Context, events: Array<RadarEvent>, user: RadarUser) {
events.forEach { event ->
if (event.type == RadarEventType.USER_ENTERED_GEOFENCE && event.geofence?.tag == "building" && event.geofence?.externalId == "library") {
// user entered library, show notification
}
}
}
}
Try creating more geofences or creating a webhook to receive events server-side. The possibilities are endless.
We can't wait to see what you'll build with Radar!
See what Radar’s location and geofencingsolutions can do for your business.