-
public class DoorstepAI
-
-
Field Summary
Fields Modifier and Type Field Description private BooleandevModeprivate BooleanmanualForegroundprivate DoubleautoStopAfterDropoffSecondsprivate final IntegerPERMISSION_REQUEST_CODEprivate final IntegerBACKGROUND_LOCATION_REQUEST_CODEprivate final Flow<GeofenceSessionEvent>geofenceSessionEventsprivate final List<DeliveryStop>monitoredStopsprivate final Flow<Long>configFetchedpublic final static DoorstepAIINSTANCE
-
Method Summary
Modifier and Type Method Description final static UnitnotePermissionRequestResult(Context context, Array<out String> permissions, IntArray grantResults)Forward the OS's answer to a permission request so checkPermissions can tell a refusable denial from one only Settings can fix. final Map<DoorstepPermission, DoorstepPermissionStatus>checkPermissions(Context context, Set<DoorstepPermission> permissions)The current state of every whitelisted permission bucket. final Map<DoorstepPermission, DoorstepPermissionStatus>checkPermissions(Context context)The current state of every whitelisted permission bucket. final DoorstepPermissionStatuscheckPermission(Context context, DoorstepPermission permission)Single-bucket convenience over checkPermissions. final StringcheckPermissionsJson(Context context, Set<DoorstepPermission> permissions)checkPermissions rendered as compact JSON — for bug reports, support logs and scripted on-device assertions (same intent as debugStateJson). final StringcheckPermissionsJson(Context context)checkPermissions rendered as compact JSON — for bug reports, support logs and scripted on-device assertions (same intent as debugStateJson). final PermissionRequestResultrequestPermissions(Activity activity, Set<DoorstepPermission> permissions, Integer requestCode)Request exactly the whitelisted permission buckets — nothing else. final PermissionRequestResultrequestPermissions(Activity activity, Set<DoorstepPermission> permissions)Request exactly the whitelisted permission buckets — nothing else. final PermissionRequestResultrequestPermissions(Activity activity)Request exactly the whitelisted permission buckets — nothing else. final List<String>requestPermissions(Activity activity, Integer requestCode, Boolean includeBluetooth)Request the SDK's foreground runtime permissions from activity. final PermissionRequestResultrequestAllPermissions(Activity activity, Integer requestCode)Every bucket, in one call — the explicit spelling of requestPermissions's default whitelist. final PermissionRequestResultrequestAllPermissions(Activity activity)Every bucket, in one call — the explicit spelling of requestPermissions's default whitelist. final List<String>getRequiredPermissions(Boolean includeBluetooth)The dangerous runtime permissions the SDK needs on the current device, version-gated. final BooleanhasRequiredPermissions(Context context, Boolean includeBluetooth)True when every foreground permission the SDK needs is currently granted. final BooleanhasBackgroundLocationPermission(Context context)True when Manifest.permission.ACCESS_BACKGROUND_LOCATION is granted (always true below API 29, where the permission does not exist as a separate grant). final BooleanrequestBackgroundLocationPermission(Activity activity, Integer requestCode)Request Manifest.permission.ACCESS_BACKGROUND_LOCATION (Android 10+), required to keep collecting when the host app is backgrounded / screen-off and by route geofencing. final BooleanrequestBackgroundLocationPermission(Activity activity)Request Manifest.permission.ACCESS_BACKGROUND_LOCATION (Android 10+), required to keep collecting when the host app is backgrounded / screen-off and by route geofencing. final Unitinit(Context context, String notificationTitle, String notificationText, Function1<Result<Unit>, Unit> callback)final UnitstartDeliveryByPlaceID(String placeID, String deliveryId, Function1<Result<String>, Unit> callback)final UnitstartDeliveryByPlaceID(String placeID, String deliveryId, Double timeoutSeconds, Boolean manualForeground, Double autoStopAfterDropoffSeconds, String customerId, String driverId, Function1<Result<String>, Unit> callback)final UnitretryGnssCallbacks()Retry GNSS callback registration after permissions have been granted. final UnitstartDeliveryByPlusCode(String plusCode, String deliveryId, Function1<Result<String>, Unit> callback)final UnitstartDeliveryByPlusCode(String plusCode, String deliveryId, Double timeoutSeconds, String customerId, String driverId, Function1<Result<String>, Unit> callback)final UnitstartDeliveryByAddressString(String address, String deliveryId, Function1<Result<String>, Unit> callback)final UnitstartDeliveryByAddressString(String address, String deliveryId, Double timeoutSeconds, Function1<Result<String>, Unit> callback)final UnitstartDeliveryByAddressString(String address, String deliveryId, LatLngObject coordinates, Double timeoutSeconds, Boolean manualForeground, Double autoStopAfterDropoffSeconds, String customerId, String driverId, Function1<Result<String>, Unit> callback)final UnitstartDeliveryByLatLng(Double latitude, Double longitude, String deliveryId, Function1<Result<String>, Unit> callback)final UnitstartDeliveryByLatLng(Double latitude, Double longitude, String subUnit, String deliveryId, Double timeoutSeconds, String customerId, String driverId, Function1<Result<String>, Unit> callback)final UnitstartDeliveryByAddressType(AddressType address, String deliveryId, Function1<Result<String>, Unit> callback)final UnitstartDeliveryByAddressType(AddressType address, String deliveryId, Double timeoutSeconds, Function1<Result<String>, Unit> callback)final UnitstartDeliveryByAddressType(AddressType address, String deliveryId, LatLngObject coordinates, Double timeoutSeconds, Boolean manualForeground, Double autoStopAfterDropoffSeconds, String customerId, String driverId, Function1<Result<String>, Unit> callback)final UnitnewEvent(String eventName, String deliveryId, Double timestamp, Function1<Result<String>, Unit> callback)final UnitnewEvent(String eventName, String deliveryId, Double timestamp)final UnitmarkDropoff(String deliveryId, DropoffType dropoffType)final UnitstopDelivery(String deliveryId)Stop a delivery. final UnitstartRouteGeofencing(List<DeliveryStop> stops, RouteGeofenceOptions options, Function1<Result<Unit>, Unit> callback)Begin in-SDK route geofencing for stops. final UnitupdateRouteStops(List<DeliveryStop> stops, Function1<Result<Unit>, Unit> callback)Replace the active route's stop set mid-route (add/remove). final UnitstopRouteGeofencing()Stop route geofencing: clear all geofences, stop any active route sessions, end the service. final UnitresumeRouteGeofencingIfNeeded()Idempotent restore of route geofencing from persisted state. final UnitsetDoorstepGoApiKey(String key)Sets the API key used by DoorstepEmbedView to mint Doorstep Go links ( GET /v1/link/go).final UnitsetAPIKey(String key, Boolean shouldGetConfig)final BooleanenableDevMode()Securely enables dev mode after validating the API token. final BooleanvalidateDevModeAccess()Validates whether the current API key has dev mode privileges without changing devMode state. final UnitdisableDevMode()Disables dev mode safely. final BooleangetDevMode()final UnitsetDevMode(Boolean devMode)final BooleangetManualForeground()When true, the SDK will NOT promote its internal TrackingService to the foreground. final UnitsetManualForeground(Boolean manualForeground)final DoublegetAutoStopAfterDropoffSeconds()Host-app override for the post-dropoff auto-stop timer, in seconds. final UnitsetAutoStopAfterDropoffSeconds(Double autoStopAfterDropoffSeconds)final IntegergetPERMISSION_REQUEST_CODE()Request code used by requestPermissions when the caller doesn't supply one. final IntegergetBACKGROUND_LOCATION_REQUEST_CODE()Request code used by requestBackgroundLocationPermission when none is supplied. final Flow<GeofenceSessionEvent>getGeofenceSessionEvents()Hot stream of route-geofencing session start/stop events, so the host can update UI without polling. final List<DeliveryStop>getMonitoredStops()final Flow<Long>getConfigFetched()Hot stream of "config fetch succeeded" events. -
-
Method Detail
-
notePermissionRequestResult
final static Unit notePermissionRequestResult(Context context, Array<out String> permissions, IntArray grantResults)
Forward the OS's answer to a permission request so checkPermissions can tell a refusable denial from one only Settings can fix.
Call it from your activity's
onRequestPermissionsResult(or yourActivityResultCallback) — one line, and it is the ONLY way the SDK can see a user's answer, because the result is delivered to the host, not to the SDK:override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) DoorstepAI.notePermissionRequestResult(this, permissions, grantResults) }Optional: without it, a permanently-denied permission reports as the re-askable DoorstepPermissionState.DENIED instead — the SDK never upgrades a guess into "permanently denied", because that verdict sends a driver to a Settings screen.
An emptygrantResults means the interaction was interrupted or the dialog was dismissed, which Android documents and which is NOT a denial; it is deliberately not recorded. A later grant clears the recorded denial, so a user who changes their mind is not held to it.
-
checkPermissions
@JvmOverloads() final Map<DoorstepPermission, DoorstepPermissionStatus> checkPermissions(Context context, Set<DoorstepPermission> permissions)
The current state of every whitelisted permission bucket. Never prompts — pure observation, safe to call from anywhere, including at launch or on every screen.
Robust where it matters:
DoorstepPermission.LOCATION_WHEN_IN_USE and DoorstepPermission.LOCATION_ALWAYS are separate buckets, so While-Using vs Always is legible: with foreground granted and background not, ALWAYS reports DoorstepPermissionState.WHEN_IN_USE_ONLY, never GRANTED and never a bare DENIED.
a refusable denial (DoorstepPermissionState.DENIED) is distinguished from one only Settings can fix (DoorstepPermissionState.PERMANENTLY_DENIED) — pass an Activity as context for this; with a plain
Contextthere is noshouldShowRequestPermissionRationalesignal and a refusal reports as the re-askable DENIED.a permission the host manifest forgot to declare reports DoorstepPermissionState.NOT_DECLARED instead of silently never prompting, and one that does not exist on this OS version or hardware reports DoorstepPermissionState.UNAVAILABLE.
- Parameters:
permissions- whitelist; defaults to every bucket.
-
checkPermissions
@JvmOverloads() final Map<DoorstepPermission, DoorstepPermissionStatus> checkPermissions(Context context)
The current state of every whitelisted permission bucket. Never prompts — pure observation, safe to call from anywhere, including at launch or on every screen.
Robust where it matters:
DoorstepPermission.LOCATION_WHEN_IN_USE and DoorstepPermission.LOCATION_ALWAYS are separate buckets, so While-Using vs Always is legible: with foreground granted and background not, ALWAYS reports DoorstepPermissionState.WHEN_IN_USE_ONLY, never GRANTED and never a bare DENIED.
a refusable denial (DoorstepPermissionState.DENIED) is distinguished from one only Settings can fix (DoorstepPermissionState.PERMANENTLY_DENIED) — pass an Activity as context for this; with a plain
Contextthere is noshouldShowRequestPermissionRationalesignal and a refusal reports as the re-askable DENIED.a permission the host manifest forgot to declare reports DoorstepPermissionState.NOT_DECLARED instead of silently never prompting, and one that does not exist on this OS version or hardware reports DoorstepPermissionState.UNAVAILABLE.
-
checkPermission
final DoorstepPermissionStatus checkPermission(Context context, DoorstepPermission permission)
Single-bucket convenience over checkPermissions.
-
checkPermissionsJson
@JvmOverloads() final String checkPermissionsJson(Context context, Set<DoorstepPermission> permissions)
checkPermissions rendered as compact JSON — for bug reports, support logs and scripted on-device assertions (same intent as debugStateJson).
Shape:
{"<wireName>":{"state":"…","canRequest":true|false,"os":"…"}}.stateis a DoorstepPermissionState name and is stable;osis free-form diagnostic evidence and is not.
-
checkPermissionsJson
@JvmOverloads() final String checkPermissionsJson(Context context)
checkPermissions rendered as compact JSON — for bug reports, support logs and scripted on-device assertions (same intent as debugStateJson).
Shape:
{"<wireName>":{"state":"…","canRequest":true|false,"os":"…"}}.stateis a DoorstepPermissionState name and is stable;osis free-form diagnostic evidence and is not.
-
requestPermissions
@JvmOverloads() final PermissionRequestResult requestPermissions(Activity activity, Set<DoorstepPermission> permissions, Integer requestCode)
Request exactly the whitelisted permission buckets — nothing else.
Must be called on the main thread, from a live Activity: the grant result is delivered to that activity's
onRequestPermissionsResult(requestCode, …), matching requestCode.What it will and will not ask for (all of it reported in the returned PermissionRequestResult rather than happening silently):
already-granted buckets are skipped (PermissionRequestResult.alreadyGranted);
buckets absent on this OS version / hardware, or missing from the host manifest, are skipped (PermissionRequestResult.unavailable);
permanently-denied buckets are skipped (PermissionRequestResult.deferred) — the OS would answer with an instant denial and no dialog, so deep-link the user to Settings instead;
DoorstepPermission.LOCATION_ALWAYS is only ever requested alone, and only after foreground location is granted, because Android 11+ auto-denies a background-location ask that is bundled with the foreground one. Whitelist both and you get the foreground dialog now and ALWAYS in PermissionRequestResult.deferred — call again (or use requestBackgroundLocationPermission) once the user has answered.
If PermissionRequestResult.requested comes back empty, no dialog was shown and
onRequestPermissionsResultwill never fire — do not await it.- Parameters:
permissions- whitelist; defaults to every bucket.
-
requestPermissions
@JvmOverloads() final PermissionRequestResult requestPermissions(Activity activity, Set<DoorstepPermission> permissions)
Request exactly the whitelisted permission buckets — nothing else.
Must be called on the main thread, from a live Activity: the grant result is delivered to that activity's
onRequestPermissionsResult(requestCode, …), matching requestCode.What it will and will not ask for (all of it reported in the returned PermissionRequestResult rather than happening silently):
already-granted buckets are skipped (PermissionRequestResult.alreadyGranted);
buckets absent on this OS version / hardware, or missing from the host manifest, are skipped (PermissionRequestResult.unavailable);
permanently-denied buckets are skipped (PermissionRequestResult.deferred) — the OS would answer with an instant denial and no dialog, so deep-link the user to Settings instead;
DoorstepPermission.LOCATION_ALWAYS is only ever requested alone, and only after foreground location is granted, because Android 11+ auto-denies a background-location ask that is bundled with the foreground one. Whitelist both and you get the foreground dialog now and ALWAYS in PermissionRequestResult.deferred — call again (or use requestBackgroundLocationPermission) once the user has answered.
If PermissionRequestResult.requested comes back empty, no dialog was shown and
onRequestPermissionsResultwill never fire — do not await it.- Parameters:
permissions- whitelist; defaults to every bucket.
-
requestPermissions
@JvmOverloads() final PermissionRequestResult requestPermissions(Activity activity)
Request exactly the whitelisted permission buckets — nothing else.
Must be called on the main thread, from a live Activity: the grant result is delivered to that activity's
onRequestPermissionsResult(requestCode, …), matching requestCode.What it will and will not ask for (all of it reported in the returned PermissionRequestResult rather than happening silently):
already-granted buckets are skipped (PermissionRequestResult.alreadyGranted);
buckets absent on this OS version / hardware, or missing from the host manifest, are skipped (PermissionRequestResult.unavailable);
permanently-denied buckets are skipped (PermissionRequestResult.deferred) — the OS would answer with an instant denial and no dialog, so deep-link the user to Settings instead;
DoorstepPermission.LOCATION_ALWAYS is only ever requested alone, and only after foreground location is granted, because Android 11+ auto-denies a background-location ask that is bundled with the foreground one. Whitelist both and you get the foreground dialog now and ALWAYS in PermissionRequestResult.deferred — call again (or use requestBackgroundLocationPermission) once the user has answered.
If PermissionRequestResult.requested comes back empty, no dialog was shown and
onRequestPermissionsResultwill never fire — do not await it.
-
requestPermissions
@Deprecated(message = Use requestPermissions(activity, permissions = setOf(...)) — a real whitelist — or requestAllPermissions(activity)., replaceWith = @ReplaceWith(imports = {}, expression = requestAllPermissions(activity, requestCode))) final List<String> requestPermissions(Activity activity, Integer requestCode, Boolean includeBluetooth)
Request the SDK's foreground runtime permissions from activity.
Superseded by the whitelist form, requestPermissions(activity, permissions, requestCode), which can name individual buckets instead of "everything, with or without Bluetooth". This overload is kept because the Capacitor / React Native / Flutter bridges call it, and its behavior is unchanged: the legacy getRequiredPermissions set, minus whatever is already granted.
Note for callers of the new API: because this overload's parameters all have defaults, a bare
requestPermissions(activity)is ambiguous to the Kotlin compiler while both exist. Use requestAllPermissions or pass an explicit whitelist.- Parameters:
includeBluetooth- also requestBLUETOOTH_SCAN(Android 12+).
-
requestAllPermissions
@JvmOverloads() final PermissionRequestResult requestAllPermissions(Activity activity, Integer requestCode)
Every bucket, in one call — the explicit spelling of requestPermissions's default whitelist.
Prefer this over a bare
requestPermissions(activity): while the deprecatedincludeBluetoothoverload still exists, a call with no second argument is ambiguous to the Kotlin compiler.Note that DoorstepPermission.LOCATION_ALWAYS will land in PermissionRequestResult.deferred here, since anything else askable in the same call means background location has to wait for its own request.
-
requestAllPermissions
@JvmOverloads() final PermissionRequestResult requestAllPermissions(Activity activity)
Every bucket, in one call — the explicit spelling of requestPermissions's default whitelist.
Prefer this over a bare
requestPermissions(activity): while the deprecatedincludeBluetoothoverload still exists, a call with no second argument is ambiguous to the Kotlin compiler.Note that DoorstepPermission.LOCATION_ALWAYS will land in PermissionRequestResult.deferred here, since anything else askable in the same call means background location has to wait for its own request.
-
getRequiredPermissions
final List<String> getRequiredPermissions(Boolean includeBluetooth)
The dangerous runtime permissions the SDK needs on the current device, version-gated. Foreground set only — it deliberately EXCLUDES Manifest.permission.ACCESS_BACKGROUND_LOCATION, which Android 11+ requires be requested separately and only after foreground location is granted (see requestBackgroundLocationPermission).
Pass this to your own
ActivityResultContracts.RequestMultiplePermissionslauncher, or use requestPermissions.This is the legacy flat list, kept verbatim for hosts and wrappers that feed it to their own launcher. It is not the source of truth for what the SDK can request: DoorstepPermission is, and it additionally covers DoorstepPermission.ACTIVITY_RECOGNITION (deliberately absent here — the SDK's manifest does not declare it) and DoorstepPermission.LOCATION_ALWAYS.
PermissionMappingTestpins this list against the bucket mapping so the two cannot drift.- Parameters:
includeBluetooth- includeBLUETOOTH_SCAN(Android 12+) for BLE collection, andNEARBY_WIFI_DEVICES(Android 13+) for WiFi RTT ranging.
-
hasRequiredPermissions
final Boolean hasRequiredPermissions(Context context, Boolean includeBluetooth)
True when every foreground permission the SDK needs is currently granted. includeBluetooth defaults to
falsehere — unlike the request methods, which request Bluetooth by default — because Bluetooth is optional: a denied "Nearby devices" grant must not make the SDK appear unusable. Passtrueonly when you specifically want to verify the BLE scan grant as well.
-
hasBackgroundLocationPermission
final Boolean hasBackgroundLocationPermission(Context context)
True when Manifest.permission.ACCESS_BACKGROUND_LOCATION is granted (always true below API 29, where the permission does not exist as a separate grant).
-
requestBackgroundLocationPermission
@JvmOverloads() final Boolean requestBackgroundLocationPermission(Activity activity, Integer requestCode)
Request Manifest.permission.ACCESS_BACKGROUND_LOCATION (Android 10+), required to keep collecting when the host app is backgrounded / screen-off and by route geofencing.
Equivalent to
requestPermissions(activity, setOf(LOCATION_ALWAYS), requestCode), kept as its own entry point because it is the mandatory second prompt on every Android version that has it. On Android 11+ the OS routes it to a Settings screen ("Allow all the time"); the result (when a dialog is shown) arrives at the activity'sonRequestPermissionsResult(requestCode, …).No-op — returning false — below API 29, when already granted, or when foreground location is not granted yet. That last case used to issue the request anyway, which Android 11+ answers with an instant auto-denial; spending the user's one real chance on a request the OS refuses to show is strictly worse than telling the caller to ask for foreground location first.
-
requestBackgroundLocationPermission
@JvmOverloads() final Boolean requestBackgroundLocationPermission(Activity activity)
Request Manifest.permission.ACCESS_BACKGROUND_LOCATION (Android 10+), required to keep collecting when the host app is backgrounded / screen-off and by route geofencing.
Equivalent to
requestPermissions(activity, setOf(LOCATION_ALWAYS), requestCode), kept as its own entry point because it is the mandatory second prompt on every Android version that has it. On Android 11+ the OS routes it to a Settings screen ("Allow all the time"); the result (when a dialog is shown) arrives at the activity'sonRequestPermissionsResult(requestCode, …).No-op — returning false — below API 29, when already granted, or when foreground location is not granted yet. That last case used to issue the request anyway, which Android 11+ answers with an instant auto-denial; spending the user's one real chance on a request the OS refuses to show is strictly worse than telling the caller to ask for foreground location first.
-
init
final Unit init(Context context, String notificationTitle, String notificationText, Function1<Result<Unit>, Unit> callback)
-
startDeliveryByPlaceID
final Unit startDeliveryByPlaceID(String placeID, String deliveryId, Function1<Result<String>, Unit> callback)
-
startDeliveryByPlaceID
final Unit startDeliveryByPlaceID(String placeID, String deliveryId, Double timeoutSeconds, Boolean manualForeground, Double autoStopAfterDropoffSeconds, String customerId, String driverId, Function1<Result<String>, Unit> callback)
-
retryGnssCallbacks
final Unit retryGnssCallbacks()
Retry GNSS callback registration after permissions have been granted. Call this after the user grants location permissions to enable GNSS data collection.
-
startDeliveryByPlusCode
@Deprecated(message = Use startDeliveryByAddressString(address, deliveryId, coordinates, timeoutSeconds, callback) instead.) final Unit startDeliveryByPlusCode(String plusCode, String deliveryId, Function1<Result<String>, Unit> callback)
-
startDeliveryByPlusCode
@Deprecated(message = Use startDeliveryByAddressString(address, deliveryId, coordinates, timeoutSeconds, callback) instead.) final Unit startDeliveryByPlusCode(String plusCode, String deliveryId, Double timeoutSeconds, String customerId, String driverId, Function1<Result<String>, Unit> callback)
-
startDeliveryByAddressString
final Unit startDeliveryByAddressString(String address, String deliveryId, Function1<Result<String>, Unit> callback)
-
startDeliveryByAddressString
final Unit startDeliveryByAddressString(String address, String deliveryId, Double timeoutSeconds, Function1<Result<String>, Unit> callback)
-
startDeliveryByAddressString
final Unit startDeliveryByAddressString(String address, String deliveryId, LatLngObject coordinates, Double timeoutSeconds, Boolean manualForeground, Double autoStopAfterDropoffSeconds, String customerId, String driverId, Function1<Result<String>, Unit> callback)
-
startDeliveryByLatLng
@Deprecated(message = Use startDeliveryByAddressType(...) or startDeliveryByAddressString(...) with coordinates instead.) final Unit startDeliveryByLatLng(Double latitude, Double longitude, String deliveryId, Function1<Result<String>, Unit> callback)
-
startDeliveryByLatLng
@Deprecated(message = Use startDeliveryByAddressType(...) or startDeliveryByAddressString(...) with coordinates instead.) final Unit startDeliveryByLatLng(Double latitude, Double longitude, String subUnit, String deliveryId, Double timeoutSeconds, String customerId, String driverId, Function1<Result<String>, Unit> callback)
-
startDeliveryByAddressType
final Unit startDeliveryByAddressType(AddressType address, String deliveryId, Function1<Result<String>, Unit> callback)
-
startDeliveryByAddressType
final Unit startDeliveryByAddressType(AddressType address, String deliveryId, Double timeoutSeconds, Function1<Result<String>, Unit> callback)
-
startDeliveryByAddressType
final Unit startDeliveryByAddressType(AddressType address, String deliveryId, LatLngObject coordinates, Double timeoutSeconds, Boolean manualForeground, Double autoStopAfterDropoffSeconds, String customerId, String driverId, Function1<Result<String>, Unit> callback)
-
newEvent
final Unit newEvent(String eventName, String deliveryId, Double timestamp, Function1<Result<String>, Unit> callback)
-
markDropoff
final Unit markDropoff(String deliveryId, DropoffType dropoffType)
-
stopDelivery
final Unit stopDelivery(String deliveryId)
Stop a delivery. If an auto-stop delay is configured for it (the
autoStopAfterDropoffSecondsargument tostartDelivery*, ormisc.autoStopAfterDropoffSecondsfrom server config), the actual teardown is DEFERRED by that many seconds — collection continues, then a Doze-safe alarm fires the real stop. A second stopDelivery during the delay is a no-op. No delay -> stops now.
-
startRouteGeofencing
final Unit startRouteGeofencing(List<DeliveryStop> stops, RouteGeofenceOptions options, Function1<Result<Unit>, Unit> callback)
Begin in-SDK route geofencing for stops. The SDK fences each stop and auto-starts/stops sessions on enter/exit (exit gated on markDropoff). Requires location permission; for background operation also requires
ACCESS_BACKGROUND_LOCATION("Allow all the time").
-
updateRouteStops
final Unit updateRouteStops(List<DeliveryStop> stops, Function1<Result<Unit>, Unit> callback)
Replace the active route's stop set mid-route (add/remove). Re-diffs geofence registration.
-
stopRouteGeofencing
final Unit stopRouteGeofencing()
Stop route geofencing: clear all geofences, stop any active route sessions, end the service.
-
resumeRouteGeofencingIfNeeded
final Unit resumeRouteGeofencingIfNeeded()
Idempotent restore of route geofencing from persisted state. The host should call this on every launch (including OS-initiated background relaunches) so the SDK re-asserts monitoring without the host re-supplying the stop list. No-op if no route is active.
-
setDoorstepGoApiKey
final Unit setDoorstepGoApiKey(String key)
Sets the API key used by DoorstepEmbedView to mint Doorstep Go links (
GET /v1/link/go).This is a different credential realm than the collection key passed to setAPIKey — a Go key carries the
GO_WEBAPPproduct; a collection key gets 401 from the link API. Call once at startup, before any embed view loads. When never called, the embed falls back to the collection key (valid only for orgs issued a single dual-realm key).
-
enableDevMode
final Boolean enableDevMode()
Securely enables dev mode after validating the API token. This function checks if the current API key has dev mode privileges before enabling it.
-
validateDevModeAccess
final Boolean validateDevModeAccess()
Validates whether the current API key has dev mode privileges without changing devMode state.
-
disableDevMode
final Unit disableDevMode()
Disables dev mode safely. This is the only way to disable dev mode since devMode has a private setter.
-
getDevMode
final Boolean getDevMode()
-
setDevMode
final Unit setDevMode(Boolean devMode)
-
getManualForeground
final Boolean getManualForeground()
When true, the SDK will NOT promote its internal TrackingService to the foreground. It expects the host app to already be running a foreground service that keeps the process alive for background tracking. Exposed read-only to the host app; set per-delivery via the
startDeliveryByX(...)functions and persisted to SharedPreferences so TrackingService can read it after process recreation.
-
setManualForeground
final Unit setManualForeground(Boolean manualForeground)
-
getAutoStopAfterDropoffSeconds
final Double getAutoStopAfterDropoffSeconds()
Host-app override for the post-dropoff auto-stop timer, in seconds.
If
null(default), the SDK falls back to the value in remote config (com.doorstepai.sdks.tracking.internal.MiscConfiguration.autoStopAfterDropoffSeconds).If non-null, this value ALWAYS wins over remote config.
If the resolved value is
nullor <= 0, no auto-stop is scheduled.
When scheduled, the timer is backed by android.app.AlarmManager with
setAndAllowWhileIdle, so it is Doze-safe and reliable for long values (10 minutes up to several hours). It does NOT require theSCHEDULE_EXACT_ALARMpermission.Exposed read-only to the host app; set per-delivery via the
startDeliveryByX(...)functions.
-
setAutoStopAfterDropoffSeconds
final Unit setAutoStopAfterDropoffSeconds(Double autoStopAfterDropoffSeconds)
-
getPERMISSION_REQUEST_CODE
final Integer getPERMISSION_REQUEST_CODE()
Request code used by requestPermissions when the caller doesn't supply one.
-
getBACKGROUND_LOCATION_REQUEST_CODE
final Integer getBACKGROUND_LOCATION_REQUEST_CODE()
Request code used by requestBackgroundLocationPermission when none is supplied.
-
getGeofenceSessionEvents
final Flow<GeofenceSessionEvent> getGeofenceSessionEvents()
Hot stream of route-geofencing session start/stop events, so the host can update UI without polling. Replays the most recent event to late subscribers.
-
getMonitoredStops
final List<DeliveryStop> getMonitoredStops()
-
getConfigFetched
final Flow<Long> getConfigFetched()
Hot stream of "config fetch succeeded" events. Each emission carries the wall-clock timestamp (ms since epoch) of the successful landing. Replays the most recent value so a late subscriber sees the current state immediately. Useful for surfacing "Config fetched at HH:mm:ss" in a host-app status panel without poking at SDK internals.
-
-
-
-