Skip to main content
Preview — not an official release. The Flutter SDK is provided for evaluation and its API may change. The supported SDKs are the iOS and Android SDKs.
The Flutter SDK is a plugin that wraps the OneS1ght iOS and Android SDKs. Positioning, zone enter / exit / dwell judgement, upload and retries all run in the native SDK; Dart only forwards calls and turns the results into Dart types. So when the app goes to the background and Dart pauses, the SDK behaves exactly as in a native app.
The Dart API follows the iOS SDK names, and native callbacks (onZoneEnter, onPosition, …) are Streams with the same names.

Requirements

On devices that cannot position, the app keeps working and only positioning stays inactive. Before the SDK can actually work, the following must be in place. See the checklist before installing the SDK for details.

Installation

Add it to pubspec.yaml as a git dependency. As a preview, it is not published to pub.dev.
Put a tag (v0.0.1) in ref. With main, your app build silently changes every time the repository changes.

iOS setup

Swift Package Manager only. CocoaPods is not supported — the positioning engine ships as dynamic frameworks that CocoaPods does not embed, and the app would crash at launch. If Swift Package Manager is off, pod install stops and tells you to run:
Raise the iOS deployment target to 18.0 (ios/Runner.xcodeproj → IPHONEOS_DEPLOYMENT_TARGET). Add these keys to ios/Runner/Info.plist. Without the first three, the app crashes as soon as the permission is requested.
The key inside NSLocationTemporaryUsageDescriptionDictionary must be Positioning. Otherwise iOS ignores the request with no error and no log.
From iOS 27.2, location permission must be “Always” for the floor to be found. Add NSLocationAlwaysAndWhenInUseUsageDescription and, once “While Using” is granted, request “Always” from your app (for example with Permission.locationAlways.request() from permission_handler). The SDK does not request it. See the iOS integration guide for why.
Do not add bluetooth-central to UIBackgroundModes. The SDK stops positioning in the background and does not use this mode, and App Review can reject unused background modes (2.5.4).

Android setup

Change MainActivity to extend FlutterFragmentActivity. The SDK’s permission request needs a ComponentActivity, and Flutter’s default FlutterActivity is not one.
Match the build versions in android/app/build.gradle.kts.
The positioning permissions (RANGING, ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, BLUETOOTH_SCAN) and INTERNET are merged automatically from the Android SDK’s manifest. You do not add them yourself.

Initializing the SDK

Call it once at app start. It validates the key and loads the tenant settings.
  • On failure it throws OneS1ghtException — calling it again retries.
  • Calling it again after success is ignored; calling it with a different key rebuilds the session.
  • Device support is not checked here. Buildings, floors and zones can be read even on devices that cannot position.

Using API keys per environment

The OneS1ght console issues API keys for Development and Production separately. We recommend passing the key at build time instead of writing it in code.

Checking device support

On Android, read deviceAvailability() after initialize(). Before that the UWB chip cannot be checked, so it returns deviceNotSupported and leaves a warning in the debug log. On iOS you can read it at any time.

Requesting permissions

  • If the permission was already answered, it returns right away without a dialog. You can call it before initialize.
  • iOS asks for Nearby Interaction permission; the location permission is requested by the SDK when positioning starts. Android asks for UWB, precise location and nearby devices at once.
  • On Android, if MainActivity is not a FlutterFragmentActivity, it fails with code unsupportedActivity.

Creating and connecting a profile

  • Attributes are up to you. For age, we recommend an age group ("20s") instead of an exact value.
  • To disconnect (for example on logout), call identify(profileId: null).
  • Read, replace, delete: fetchProfile(id) · replaceProfile(id, attributes: …) (full replace) · deleteProfile(id).

Selecting a building and floor (optional)

Without setFloorMap, the positioning engine finds the floor over BLE. Pass buildingId the first time (otherwise E3001). setFloorMap(null) clears the floor.

Following the floor the engine finds

Displaying the floor plan

The floors() list leaves the floor plan image empty. Fetch only the floor you draw with floor(buildingId:, floorId:) and image (raw bytes) is filled in. Coordinates are floor-local metres; convert them to screen coordinates with originX, originY, widthM and heightM.

Starting and stopping positioning

If begin() fails it throws OneS1ghtException — E1001 (not initialized) · E1004 (identify not called) · E2001 (OS too low) · E2002 (device not supported).

Pausing and resuming

When positioning closes

Receiving events

All events are Streams. You can listen from several places at once.

Refreshing zone data

Receiving console changes

The SDK does nothing with this signal. Every zone reload restarts enter / exit judgement from scratch, so collapse bursts of ZonesChanged and handle them once.

Controlling data upload

Resetting the session

Handling errors

Every failure is a OneS1ghtException. code is the native SDK’s error code and is the same on iOS and Android.

Debug logs

See How to use logs for log levels and how to read them. We recommend not subscribing in production builds. The language of SDK logs and messages can be set with OneS1ght.setLanguage('en') ('ko', 'ja', 'en'; null follows the device language).

Background behavior

UWB positioning is foreground only on both iOS and Android. When the app goes to the background, the native SDK stops positioning and uploads the remaining positions. This is done by the native SDK, not Dart, so it is the same in Flutter apps.
Actual positioning cannot be checked on simulators or emulators. Install on a real device that supports UWB to test.

Differences from the native SDKs

Troubleshooting

How to use logs

How to use logs during development.

Error codes

Errors that can occur during development.