| title | Architecture |
|---|---|
| weight | 5 |
Three layers: detection logic → plugin bridge → lifecycle manager.
Pure detection algorithm. No Android imports. Takes sensor values, returns events.
Sensor data → GestureTrigger<T> → Event
Testable on JVM — no device or emulator needed.
observe() returns Flow<T> — default is emptyFlow(). Override to expose a persistent event stream (e.g. orientation changes, sound level).
Bridge between trigger and Android. Implements onRegister / onUnregister.
- Sensor plugins: write a
GestureTrigger<T>, wrap inTypedSensorDetector, callsensey.registerSensorDetector(). Sensey handlesSensorManager. - Compose plugins: create a
ComposeGestureProvider, callsensey.registerComposeGestureProvider().
Plugins register via Sensey.register(plugin).
Plugin registry + lifecycle manager.
senseyRegister(lifecycle) {}— lifecycle-bound DSLSenseyGestureEffect {}— Compose touch integration- Auto-cleanup on
ON_DESTROY - Manual:
senseyStop()
Flow-based lifecycle-aware plugin collection.
context.senseyFlow(lifecycle) {}— creates aSenseyFlowScopethat collects plugin flows while lifecycle isSTARTED.SenseyFlowEffect {}— Compose wrapper usingDisposableEffect.- Internally uses
callbackFlowto bridge plugin dispatchers into KotlinFlow<T>.
GesturePlugin
↓ (registers with system)
SensorManager → GestureTrigger<T>
↓ (gesture events)
User callback
GesturePlugin
↓ (registers with system)
SensorManager → GestureTrigger<T>
↓ (callbackFlow bridge)
Flow<T> → SenseyFlowScope → User collector
com.github.nisrulz.sensey/
├── Sensey.kt # Facade + registerSensorDetector()
├── SenseyExtensions.kt # senseyRegister() / senseyStop()
├── SenseyPluginRegistry.kt # Builder DSL
├── SensorDetector.kt # TypedSensorDetector bridge
├── internal/
│ ├── AudioCapture.kt # Shared AudioRecord coroutine wrapper
│ ├── EmaSmoother.kt # Single-pole EMA filter
│ ├── GyroIntegrator.kt # Gyroscope integration
│ └── Util.kt # Math helpers (magnitude, angle, etc.)
├── contract/
│ ├── GesturePlugin.kt # Plugin interface
│ └── GestureTrigger.kt # Trigger interface (+ observe() flow)
├── flow/
│ └── SenseyFlow.kt # SenseyFlowScope + senseyFlow()
├── gesture/
│ ├── GesturePlugins.kt # DSL builder functions
│ ├── compose/ # Compose touch integration (senseyGestures)
│ │ └── SenseyComposeFlow.kt # SenseyFlowEffect composable
│ ├── audio/clap/ # Clap detection (AudioRecord)
│ ├── shake/ # Shake detection
│ ├── flip/ # Flip detection
│ ├── chop/ # Chop gesture
│ ├── wristtwist/ # Wrist twist gesture
│ ├── wave/ # Proximity wave gesture
│ ├── scoop/ # Scoop/lift gesture
│ ├── pickupdevice/ # Pickup / put-down detection
│ ├── orientation/ # Screen orientation detection
│ ├── tiltdirection/ # Gyro tilt axis detection
│ ├── rotationangle/ # Euler angle reporting
│ ├── taponback/ # Back-tap double-tap detection
│ ├── movement/ # Device movement / stationary
│ ├── light/ # Ambient light transitions
│ ├── proximity/ # Near / far proximity
│ ├── soundlevel/ # Mic-based dB level
│ ├── step/ # Step counter / activity
│ ├── turnover/ # Gyro-based 180° flip
│ ├── devicespin/ # Rapid spin detection
│ ├── raisetoear/ # Proximity + gravity ear detection
│ ├── pinchscale/ # Compose pinch-to-zoom
│ └── touchtype/ # Compose tap/swipe/scroll
Each gesture directory:
{Gesture}Event.kt— sealed interface for events{Gesture}Trigger.kt— pure detection logic