Location tracking

Updated

How it works

The Location module captures location (with user consent) from your app and attaches it to a person’s profile in Customer.io. You can use this data for geo-aware messaging and audience segmentation with more accuracy than IP-based geolocation.

When you identify a person, the SDK includes the latest location in the identify call. The SDK also sends a Location Update event to the person’s activity timeline, which you can use in journeys and segments. To balance location updates with battery and data usage, the SDK limits location updates once a day (at most)—and only sends that update when the person has moved a meaningful distance since the last update.

The SDK does not request location permission on its own—your app must handle the permission flow.

Install the location module

To use location tracking, add the location dependency to your app’s build.gradle file.

implementation 'io.customer.android:location:<version-here>'

Initialize the SDK with the location module

Add ModuleLocation when you initialize the SDK. The module takes a LocationModuleConfig where you set the tracking mode.

OptionTypeDefaultDescription
trackingModeLocationTrackingModeMANUALControls how and when the SDK captures location. See tracking modes below.

Tracking modes

ModeDescription
MANUALYour app controls when it caputres location. Call setLastKnownLocation() or requestLocationUpdate() to provide location. You should use this option when your app already has a location-tracking mechanism or you want full control over when you capture location data.
ON_APP_STARTThe SDK automatically captures a one-shot location once per app launch when your app enters the foreground. You can still call setLastKnownLocation() or requestLocationUpdate() alongside automatic capture. Use this for hands-off location tracking with minimal battery impact.
OFFDisables location tracking entirely. All location calls become silent and location is not included in identify calls. Use this if you want to register the module but disable it at runtime.
val config = CustomerIOConfigBuilder(applicationContext, "your-cdp-api-key")
    .addCustomerIOModule(
        ModuleLocation(
            LocationModuleConfig.Builder()
                .setLocationTrackingMode(LocationTrackingMode.MANUAL)
                .build()
        )
    )
    .build()

CustomerIO.initialize(config)
CustomerIOConfigBuilder builder = new CustomerIOConfigBuilder(application, "your-cdp-api-key");
builder.addCustomerIOModule(
    new ModuleLocation(
        new LocationModuleConfig.Builder()
            .setLocationTrackingMode(LocationTrackingMode.MANUAL)
            .build()
    )
);

CustomerIO.initialize(builder.build());

Location APIs

The module provides two methods to capture location. You can call either method as often as you like; the SDK always caches the latest coordinates for profile enrichment, but sends a Location Update event no more than once a day—and only if the person has moved a meaningful distance. No matter how frequently you call these methods, the SDK throttles the updates for you so as not to overwhelm your workspace with profile updates.

setLastKnownLocation

Pass coordinates directly from your app’s own location system. This doesn’t require any location permissions from the SDK. Your app manages location access independently of Customer.io.

ParameterTypeDescription
latitudeDoubleLatitude in degrees. Must be between -90 and 90.
longitudeDoubleLongitude in degrees. Must be between -180 and 180.

You can also pass an Android Location object directly.

// From coordinates
ModuleLocation.instance().locationServices.setLastKnownLocation(37.7749, -122.4194)

// From an Android Location object
ModuleLocation.instance().locationServices.setLastKnownLocation(androidLocation)
// From coordinates
ModuleLocation.instance().getLocationServices().setLastKnownLocation(37.7749, -122.4194);

// From an Android Location object
ModuleLocation.instance().getLocationServices().setLastKnownLocation(androidLocation);

requestLocationUpdate

Request a one-shot location from the SDK using Google’s Fused Location Provider. Use this if your app doesn’t have its own location system. Your app must request location permission before calling this method—the SDK won’t prompt the user.

If a user doesn’t grant permission or location services are disabled, the request is ignored—no crash or exception. If a request is already in progress, additional calls are ignored until the current request completes.

  1. Add the permission to your AndroidManifest.xml:

     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <!-- Optional: for more precise location -->
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
  2. Request permission at runtime and call the SDK:

    val launcher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { granted ->
        if (granted) {
            ModuleLocation.instance().locationServices.requestLocationUpdate()
        }
    }
    
    launcher.launch(Manifest.permission.ACCESS_COARSE_LOCATION)
    
    ActivityResultLauncher<String> launcher = registerForActivityResult(
        new ActivityResultContracts.RequestPermission(),
        granted -> {
            if (granted) {
                ModuleLocation.instance().getLocationServices().requestLocationUpdate();
            }
        }
    );
    
    launcher.launch(Manifest.permission.ACCESS_COARSE_LOCATION);
    

Profile switch behavior

When you call clearIdentify(), the SDK clears cached location data so that one person’s location doesn’t carry over to another person’s profile. The next person you identify starts with a clean slate.

Location persists across app restarts. When your app relaunches, the SDK restores the cached location so that the next identify() call includes it automatically.

Copied to clipboard!
  Contents
Version