tight_flutter 0.0.1
tight_flutter: ^0.0.1 copied to clipboard
Flutter bridge to the Tight mileage tracking SDKs (iOS and Android) via platform channels: permissions, detection modes, semi-auto drives and a stream of native drive events.
tight_flutter #
Flutter bridge to the Tight mileage tracking SDKs for iOS and Android, exposed to Dart through platform channels.
Inspired in structure by intercom_flutter: a plain Dart API over
MethodChannel for calls and an EventChannel stream for the native
TightDelegate callbacks.
What it does (and does not) do #
- ✅ Initialize the SDK, request permissions, set the detection mode, start/stop semi-automatic drives, read the current drive, manage Bluetooth trigger devices.
- ✅ Surface native drive/permission callbacks as a
Stream<TightEvent>. - ✅ Bluetooth trigger devices (Android only — see below).
- ❌ No trip history. The SDK only exposes the current drive
(
getCurrentDrive). Full history is served by the Tight backend, not this plugin. - ❌ No GPS polyline / map.
TightDrivecarries only start/end coordinates- distance. The Tight SDK v6.0.0 exposes no map/route view on either platform, so this plugin does not provide one.
Requirements & configuration #
This package is a thin port of the public Tight SDKs (v6.0.0 on both
platforms). It ships no credentials: the integrating app provides its own
TightClientId (build config) and per-user accessToken (passed to
initialize). The Tight SDKs are publicly distributed — no private access is
required to build or use this package.
Detection mode parity #
The native detection-mode enums differ, so the Dart MileageDetectionMode is a
unified abstraction:
| Dart | iOS (OFF/AUTO) |
Android (OFF/AUTO/BLUETOOTH) |
|---|---|---|
disabled |
OFF |
OFF |
automatic |
AUTO |
AUTO |
bluetooth |
unsupported → throws | BLUETOOTH |
Bluetooth device management (getBluetoothDevices, saveBluetoothDevice,
requestBluetoothPermissions) is Android-only; these throw a
TightException on iOS.
iOS #
- The Tight iOS SDK (module
Tight, entry pointSDK.manager) is Swift Package Manager only and requires iOS 17.0. On older iOS versions every call throws aTightExceptionwith codeunsupported_os(see the gating notes inios/tight_flutter/Package.swift). - Enable Flutter's SPM support in the host app:
flutter config --enable-swift-package-manager. Info.plistkeys required by the host app:TightClientId(provided by Tight)NSLocationAlwaysAndWhenInUseUsageDescriptionNSLocationWhenInUseUsageDescriptionNSLocationUsageDescriptionNSMotionUsageDescriptionUIBackgroundModes=[location]
Android #
- Distributed via Maven Central (no private credentials).
minSdk 28. - Host app resources:
- string
tight_client_id(required) mileage_notification_icon_color,mileage_notification_icon(optional)
- string
- Host app
AndroidManifest.xmlpermissions (background location, activity recognition and Bluetooth are needed for automatic detection). Confirm the exact list against the Tight Android SDK before shipping:ACCESS_FINE_LOCATION,ACCESS_BACKGROUND_LOCATIONACTIVITY_RECOGNITIONBLUETOOTH_CONNECT,BLUETOOTH_SCAN
- The host
Activitymust be aComponentActivity(Flutter's defaultFlutterActivityis) so the permission launcher works.
Notes & open items #
- Drive resumption after app kill / device reboot is handled by the native SDK; verify it on-device as part of QA.
- Battery savers can suppress background tracking — surfaced via
TightPermissions.osBatterySaver/appBatterySaver.
Usage #
final tight = TightFlutter();
await tight.initialize(accessToken: backendMintedToken);
final permissions = await tight.requestMileagePermissions();
await tight.setMileageDetectionMode(MileageDetectionMode.automatic);
final sub = tight.events.listen((event) {
switch (event) {
case DidStartDrive(:final drive): /* ... */
case DidStopDrive(:final drive): /* ... */
case DidResumeDrive(:final drive): /* ... */
case DidPermissionsChange(:final permissions): /* ... */
case DidPermissionsError(): /* ... */
case TightUnknownEvent(): break;
}
});
await tight.startSemiAutoDrive();
// ...
await tight.stopDrive();
Status #
POC, verified against the public v6.0.0 SDKs (SPM module Tight /
com.tight:tight-android-sdk:6.0.0, both via the SDK.manager singleton).
Verified end-to-end:
- Android —
example/builds against the real SDK, runs on an emulator, and the method channel round-trips into the SDK (initializereaches native and surfaces a typedTightExceptionwhen no client id is configured). - iOS —
example/builds against the real SDK (SPM binary target, simulator slices present) and runs on the iOS 17+ simulator.
Before shipping, still to validate on-device with real credentials
(TightClientId + backend accessToken): the full permission / drive lifecycle,
background tracking, and drive resumption after app kill / reboot. Note the SPM
manifest pins the plugin to iOS 17, so host apps must target iOS 17 (or vendor a
prebuilt xcframework via the podspec to stay lower).