Engineering

Radar student hackathon playbook

by

Radar Team

on

January 14, 2020

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:

  • Create geofences for your campus, buildings on your campus, and more
  • Install the Radar SDK in your iOS or Android app
  • Change the app experience when a user is inside a geofence
  • Trigger a push notification when a user enters or exits a geofence
  • And more

https://cdn.prod.website-files.com/67606084339203323d92a420/67881eb3d832cb40e8a47e4d_photo.jpeg

Step 1: Create geofences

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)

https://cdn.prod.website-files.com/67606084339203323d92a420/67881eb3d832cb40e8a47e88_geofences.gif

Step 2: Install the SDK

To use the geofences, let's install the SDK!

For iOS, follow the documentation here. To start:

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
    }

}

Step 3: Change the app experience when a user is inside a geofence

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.

https://cdn.prod.website-files.com/67606084339203323d92a420/67881eb3d832cb40e8a47e85_user.png

Step 4: Trigger a push notification when a user enters or exits a geofence

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
            }
        }
    }

}

What's next?

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!

It's time to build

See what Radar’s location and geofencingsolutions can do for your business.