> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ones1ght.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Android SDK

> SDK Version 0.0.9

## Import

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  import co.onecheck.ones1ght.android.*           // OneS1ght · FloorSession · SdkError · listeners
  import co.onecheck.ones1ght.android.model.*     // Building · Floor · Zone · Coordinates · Trigger · ConfigChange
  import co.onecheck.ones1ght.android.network.ApiError
  import co.onecheck.ones1ght.android.runtime.LogLevel
  ```

  ```java Java icon="java" theme={null}
  import co.onecheck.ones1ght.android.*;          // OneS1ght · FloorSession · SdkError · Callback · listeners
  import co.onecheck.ones1ght.android.model.*;    // Building · Floor · Zone · Coordinates · Trigger · ConfigChange
  import co.onecheck.ones1ght.android.network.ApiError;
  import co.onecheck.ones1ght.android.runtime.LogLevel;
  ```
</CodeGroup>

## Initialization

### .initialize

Initializes the positioning engine with your OneS1ght API key. Pass `baseUrl` only if you run your own server (default `OneS1ght.DEFAULT_BASE_URL`).

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  OneS1ght.initialize(context = context.applicationContext, sdkKey = "YOUR_SDK_KEY")
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.initialize(context, "YOUR_SDK_KEY", new Callback<Void>() {
      @Override public void onSuccess(Void result) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .requestPermission

Requests the app permissions needed to use the positioning engine.

| Result | Meaning |
| - | - |
| `AUTHORIZED` | Positioning available |
| `DENIED` | Permission denied |
| `UNSUPPORTED` | Device without positioning support |

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val status = OneS1ght.requestPermission(activity)
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.requestPermission(activity, new Callback<PermissionStatus>() {
      @Override public void onSuccess(PermissionStatus status) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .setLanguage

Sets the language of SDK log messages.<br />
`ko`: Korean,  `ja`: Japanese,  `en`: English, `null`: system language

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  OneS1ght.setLanguage("en")
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.setLanguage("en");
  ```
</CodeGroup>

### .onDebugLog

Receives SDK logs.<br />
`level`: log level, `message`: log message

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  OneS1ght.onDebugLog = DebugLogListener { level, message ->
      if (level >= LogLevel.WARN) Log.w("OneS1ght", message)
  }
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.setOnDebugLog((level, message) -> {
      if (level.compareTo(LogLevel.WARN) >= 0) Log.w("OneS1ght", message);
  });
  ```
</CodeGroup>

### .reset

Discards the session, stops positioning, and clears the stored key and building context. Call `initialize` again afterwards (until then, `NotInitialized`, `E1001`).

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  OneS1ght.reset()
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.reset(new Callback<Void>() {
      @Override public void onSuccess(Void result) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

## State

### .isInitialized

Returns whether initialization succeeded.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val ready = OneS1ght.isInitialized
  ```

  ```java Java icon="java" theme={null}
  boolean ready = OneS1ght.isInitialized();
  ```
</CodeGroup>

### .deviceAvailability

Tells whether the device supports positioning and, if not, why. Read it after `initialize()` — before that it is `DEVICE_NOT_SUPPORTED` (`OS_VERSION_TOO_LOW` below Android 17).

| Value | Meaning |
| - | - |
| `AVAILABLE` | Positioning available |
| `OS_VERSION_TOO_LOW` | Below Android 17 (API 37) |
| `DEVICE_NOT_SUPPORTED` | Device without UWB |

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  when (OneS1ght.deviceAvailability) {   // initialize() after
      DeviceAvailability.AVAILABLE            -> Unit
      DeviceAvailability.OS_VERSION_TOO_LOW   -> Unit
      DeviceAvailability.DEVICE_NOT_SUPPORTED -> Unit
      else                                    -> Unit
  }
  ```

  ```java Java icon="java" theme={null}
  DeviceAvailability availability = OneS1ght.getDeviceAvailability();
  boolean available = OneS1ght.isDeviceAvailable();
  ```
</CodeGroup>

### .googleMapKey

Returns the Google Maps API key for displaying the floor plan.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val mapKey = OneS1ght.googleMapKey   // String?
  ```

  ```java Java icon="java" theme={null}
  String mapKey = OneS1ght.getGoogleMapKey();
  ```
</CodeGroup>

### .SDK\_VERSION

Returns the SDK version in use.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val version = OneS1ght.SDK_VERSION   // "0.0.9"
  ```

  ```java Java icon="java" theme={null}
  String version = OneS1ght.SDK_VERSION;
  ```
</CodeGroup>

## Profiles

### .createProfile

Creates a new personalization profile. Returns a unique profile ID on success.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val profileId = OneS1ght.createProfile(mapOf("gender" to "F", "ageBand" to "20s"))
  ```

  ```java Java icon="java" theme={null}
  Map<String, String> attributes = new HashMap<>();
  attributes.put("gender", "F");
  attributes.put("ageBand", "20s");
  OneS1ght.createProfile(attributes, new Callback<String>() {
      @Override public void onSuccess(String profileId) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .identify

Links the profile that collected positioning data is grouped under. Set `null` to unlink.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  OneS1ght.identify(profileId)
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.identify(profileId);
  ```
</CodeGroup>

### .fetchProfile

Fetches the profile's attributes.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val attributes = OneS1ght.fetchProfile(profileId)
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.fetchProfile(profileId, new Callback<Map<String, String>>() {
      @Override public void onSuccess(Map<String, String> attributes) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .replaceProfile

Replaces the profile's attributes. The previous data is deleted.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  OneS1ght.replaceProfile(profileId, mapOf("gender" to "F", "ageBand" to "30s"))
  ```

  ```java Java icon="java" theme={null}
  Map<String, String> attributes = new HashMap<>();
  attributes.put("gender", "F");
  attributes.put("ageBand", "30s");
  OneS1ght.replaceProfile(profileId, attributes, new Callback<Void>() {
      @Override public void onSuccess(Void result) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .deleteProfile

Permanently deletes the profile.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  OneS1ght.deleteProfile(profileId)
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.deleteProfile(profileId, new Callback<Void>() {
      @Override public void onSuccess(Void result) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

## Space lookup

### .buildings

Fetches every building that belongs to the tenant.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val buildings = OneS1ght.buildings()
  val building = OneS1ght.building(id = buildingId)
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.buildings(new Callback<List<Building>>() {
      @Override public void onSuccess(List<Building> buildings) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .floors

Fetches the floors of a building.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val floors = OneS1ght.floors(buildingId)
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.floors(buildingId, new Callback<List<Floor>>() {
      @Override public void onSuccess(List<Floor> floors) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .floor

Fetches the details of the selected floor.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val floor = OneS1ght.floor(buildingId, floorId)
  val png = floor.image   // ByteArray?
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.floor(buildingId, floorId, new Callback<Floor>() {
      @Override public void onSuccess(Floor floor) { byte[] png = floor.getImage(); }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .zones

Fetches every zone on the selected floor.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val zones = OneS1ght.zones(buildingId, floorId)
  val zone = OneS1ght.zone(buildingId, floorId, zoneId)
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.zones(buildingId, floorId, new Callback<List<Zone>>() {
      @Override public void onSuccess(List<Zone> zones) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .locators

Fetches the locators on the selected floor.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val floorLocators = OneS1ght.locators(buildingId, floorId)
  val ready = floorLocators.positioningReady
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.locators(buildingId, floorId, new Callback<FloorLocators>() {
      @Override public void onSuccess(FloorLocators floorLocators) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

## Setting the floor

### .setFloorMap

Sets the floor used for zone events (optional). Coordinates arrive without it, but zone events and campaigns need it.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val floor = OneS1ght.floor(buildingId, floorId)
  OneS1ght.setFloorMap(floor, buildingId)
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.floor(buildingId, floorId, new Callback<Floor>() {
      @Override public void onSuccess(Floor floor) {
          OneS1ght.setFloorMap(floor, buildingId, new Callback<Void>() {
              @Override public void onSuccess(Void result) { }
              @Override public void onError(Throwable error) { }
          });
      }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .refreshZones

Fetches the latest zone data.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val zones = OneS1ght.refreshZones()
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.refreshZones(new Callback<List<Zone>>() {
      @Override public void onSuccess(List<Zone> zones) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

## Positioning session

### .floorSession

Returns the positioning session. It is a single app-wide instance not tied to a floor, and throws `NotInitialized` before `initialize`.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val session = OneS1ght.floorSession()
  ```

  ```java Java icon="java" theme={null}
  FloorSession session = OneS1ght.floorSession();
  ```
</CodeGroup>

### .begin

Starts positioning the user.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  session.begin()
  ```

  ```java Java icon="java" theme={null}
  session.begin(new Callback<Void>() {
      @Override public void onSuccess(Void result) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .end

Stops positioning the user.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  session.end()
  ```

  ```java Java icon="java" theme={null}
  session.end(new Callback<Void>() {
      @Override public void onSuccess(Void result) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .pause · .resume

Pauses and resumes positioning. Unlike `end`, the positioning engine inside the SDK keeps running.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  session.pause()
  session.resume()
  ```

  ```java Java icon="java" theme={null}
  session.pause();
  session.resume();
  ```
</CodeGroup>

### .isRunning · .isPaused

Returns whether positioning is running and whether it is paused.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  val running = session.isRunning
  val paused = session.isPaused
  val current = session.floor   // Floor?
  ```

  ```java Java icon="java" theme={null}
  boolean running = session.isRunning();
  boolean paused = session.isPaused();
  Floor current = session.getFloor();
  ```
</CodeGroup>

## Session events

### .onPosition

Delivers the user's coordinates in real time, at the rate the engine produces them; only server uploads are downsampled to the console setting (4 per second by default).

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  session.onPosition = PositionListener { coordinates -> Log.d("OneS1ght", "${coordinates.x}, ${coordinates.y}") }
  ```

  ```java Java icon="java" theme={null}
  session.setOnPosition(coordinates -> Log.d("OneS1ght", coordinates.getX() + ", " + coordinates.getY()));
  ```
</CodeGroup>

### .onZoneEnter · .onZoneExit

Fires when the user enters or exits a zone.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  session.onZoneEnter = ZoneListener { zone -> Log.d("OneS1ght", "IN ${zone.name}") }
  session.onZoneExit  = ZoneListener { zone -> Log.d("OneS1ght", "OUT ${zone.name}") }
  ```

  ```java Java icon="java" theme={null}
  session.setOnZoneEnter(zone -> Log.d("OneS1ght", "IN " + zone.getName()));
  session.setOnZoneExit(zone -> Log.d("OneS1ght", "OUT " + zone.getName()));
  ```
</CodeGroup>

### .onZoneDwell

Fires when the dwell time in a zone exceeds the threshold (`dwellSeconds`).

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  session.onZoneDwell = DwellListener { zone, seconds -> Log.d("OneS1ght", "DWELL ${zone.name} ${seconds}s") }
  ```

  ```java Java icon="java" theme={null}
  session.setOnZoneDwell((zone, seconds) -> Log.d("OneS1ght", "DWELL " + zone.getName() + " " + seconds));
  ```
</CodeGroup>

### .onTriggers

Fires when an in-space event (campaign) is triggered.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  session.onTriggers = TriggersListener { zoneId, triggers ->
      triggers.forEach { trigger -> Log.d("OneS1ght", "${trigger.type} ${trigger.payload}") }
  }
  ```

  ```java Java icon="java" theme={null}
  session.setOnTriggers((zoneId, triggers) -> {
      for (Trigger trigger : triggers) Log.d("OneS1ght", trigger.getType());
  });
  ```
</CodeGroup>

### .onFloorDetected

Called with the floor ID when the engine finds a floor from locator BLE signals, and with `null` when the floor is lost.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  session.onFloorDetected = SessionFloorListener { floorId ->
      if (floorId == null) return@SessionFloorListener
      lifecycleScope.launch {
          val floor = OneS1ght.floor(buildingId, floorId)
          OneS1ght.setFloorMap(floor, buildingId)
      }
  }
  ```

  ```java Java icon="java" theme={null}
  session.setOnFloorDetected(floorId -> {
      if (floorId == null) return;
      OneS1ght.floor(buildingId, floorId, new Callback<Floor>() {
          @Override public void onSuccess(Floor floor) {
              OneS1ght.setFloorMap(floor, buildingId, new Callback<Void>() {
                  @Override public void onSuccess(Void result) { }
                  @Override public void onError(Throwable error) { }
              });
          }
          @Override public void onError(Throwable error) { }
      });
  });
  ```
</CodeGroup>

### .onStopped

Fires when positioning stops.

| Reason | Meaning |
| - | - |
| `ENDED` | `end()` · `reset` · key change |
| `ENGINE_FAILED` | The positioning engine failed to run |

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  session.onStopped = SessionStoppedListener { reason ->
      when (reason) {
          FloorSession.StopReason.ENDED         -> Unit
          FloorSession.StopReason.ENGINE_FAILED -> Unit
          else                                  -> Unit
      }
  }
  ```

  ```java Java icon="java" theme={null}
  session.setOnStopped(reason -> {
      if (reason == FloorSession.StopReason.ENGINE_FAILED) { }
  });
  ```
</CodeGroup>

### .onConfigChanged

Fires when settings change in the console.

| Signal | Meaning |
| - | - |
| `ZonesChanged(floorId)` | Zones changed |
| `PlanChanged(floorId)` | Floor plan changed |
| `RulesChanged(zoneId)` | Campaigns changed |
| `SdkConfigChanged` | Remote config changed |
| `ResyncNeeded` | Reconnected · events missed |

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  session.onConfigChanged = ConfigChangeListener { change ->
      when (change) {
          is ConfigChange.ZonesChanged, is ConfigChange.ResyncNeeded -> lifecycleScope.launch { OneS1ght.refreshZones() }
          is ConfigChange.PlanChanged -> redrawFloor()
          else -> Unit
      }
  }
  ```

  ```java Java icon="java" theme={null}
  session.setOnConfigChanged(change -> {
      if (change instanceof ConfigChange.ZonesChanged || change instanceof ConfigChange.ResyncNeeded) {
          OneS1ght.refreshZones(new Callback<List<Zone>>() {
              @Override public void onSuccess(List<Zone> zones) { }
              @Override public void onError(Throwable error) { }
          });
      }
  });
  ```
</CodeGroup>

## Data upload

Coordinates are uploaded automatically every 300 entries or 60 seconds, as well as when the app goes to the background and on `end()`.

### .uploadPendingPositions

Uploads buffered coordinates immediately.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  OneS1ght.uploadPendingPositions()
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.uploadPendingPositions(new Callback<Void>() {
      @Override public void onSuccess(Void result) { }
      @Override public void onError(Throwable error) { }
  });
  ```
</CodeGroup>

### .discardPendingPositions

Discards buffered coordinates.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  OneS1ght.discardPendingPositions()
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.discardPendingPositions();
  ```
</CodeGroup>

## Error handling

Failures arrive as `SdkError` (SDK state) and `ApiError` (communication, `co.onecheck.ones1ght.android.network.ApiError`). See [Error codes](/en/sdk/troubleshooting/error-codes) for details.

<CodeGroup>
  ```kotlin Kotlin icon="https://mintcdn.com/onecheck/wv66PbaB8dD4xd9I/images/icons/kotlin.svg?fit=max&auto=format&n=wv66PbaB8dD4xd9I&q=85&s=3721cc48a6f44aef50ea7a0151e369f2" theme={null}
  try {
      OneS1ght.initialize(context = context.applicationContext, sdkKey = key)
  } catch (e: SdkError) {
      Log.w("OneS1ght", e.code.code)                     // "E1003"
  } catch (e: ApiError) {
      Log.w("OneS1ght", "${e.code.code} ${e.message}")   // "E5005 …"
  }
  ```

  ```java Java icon="java" theme={null}
  OneS1ght.initialize(context, key, new Callback<Void>() {
      @Override public void onSuccess(Void result) { }
      @Override public void onError(Throwable error) {
          if (error instanceof SdkError) {
              Log.w("OneS1ght", ((SdkError) error).getCode().getCode());   // "E1003"
          } else if (error instanceof ApiError) {
              Log.w("OneS1ght", ((ApiError) error).getCode().getCode() + " " + error.getMessage());
          }
      }
  });
  ```
</CodeGroup>

## Models

Lists are `List<T>`, bytes are `ByteArray`.

### Coordinates

| Field | Type | Description |
| - | - | - |
| `x` · `y` | `Double` | Meters, local to the floor plan |
| `z` | `Double` | Height |

### Building · Floor

| Type | Field | Description |
| - | - | - |
| `Building` | `id` · `name` | Building ID · name |
| | `floorCount: Int?` | Number of floors |
| `Floor` | `id` · `name` | Floor ID · name |
| | `image: ByteArray?` | Decoded floor plan PNG bytes — `null` in list results |
| | `hasPlan: Boolean` | Whether a floor plan is registered |
| | `originX` · `originY` | Floor plan origin (meters) |
| | `widthM` · `heightM` | Floor plan size (meters) |
| | `minX` · `minY` · `maxX` · `maxY` | Placement bounds |

### Locator · FloorLocators

| Type | Field | Description |
| - | - | - |
| `Locator` | `address: Int` | Last 2 bytes of the UWB MAC |
| | `x` · `y` · `z` | Meters, local to the floor plan |
| `FloorLocators` | `locators` | Locators on the floor |
| | `sessionId: Int?` | UWB session — differs per floor |
| | `positioningReady: Boolean` | Whether both locators and a session exist |

### Zone

| Field | Type | Description |
| - | - | - |
| `id` · `name` | `String` | Zone ID · name |
| `polygon` | `List<Position>` | Vertices (`x`, `y` in meters) |
| `dwellSeconds` | `Int?` | Dwell event threshold (seconds) |

### Trigger

| Field | Type | Description |
| - | - | - |
| `triggerId` | `String` | Trigger ID |
| `type` | `String` | `signage` · `coupon` · `tracking` · `merch` · `generic` |
| `payload` | `Map<String, String>?` | Extra data per type |

Enums (`ConfigChange` · `StopReason` · `PermissionStatus` · `DeviceAvailability` · `LogLevel`) may gain values in minor versions — keep an `else` branch in `when`.

## Limitations

* `suspend` APIs can be called from any coroutine. Call `identify` · `discardPendingPositions` · `pause` · `resume` on the main thread.
* UWB positioning is foreground only. In the background positioning stops, the zone the user was in is treated as exited (`onZoneExit`), and the live stream is cut. On return positioning restarts and `ResyncNeeded` arrives.
* The coordinate buffer is kept in app memory — unsent coordinates are lost if the app is force-quit.
* Positioning does not work on the emulator.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.