Dashboard →
Full Documentation - Sign-In Required

You're viewing the complete WearOS SDK documentation. This content requires authentication.

RotationKit WearOS SDK

Professional manual rotation control for Wear OS applications

Transform your Wear OS app with precision manual rotation control. Perfect for navigation, fitness, and hands-free applications where users need to adjust screen orientation with intuitive touch gestures.


✨ Features

Core Capabilities (v1.0)

Advanced Features


🚀 Quick Start

> New to RotationKit? Check out our 5-minute Quick Start Guide for the fastest way to get started!

Step 1: Get Your API Key

  1. Visit RotationKit Developer Portal
  2. Sign up with your email (takes 30 seconds)
  3. Click "Create API Key"
  4. Select platform: WearOS
  5. Choose type:
  6. Developer: Free for testing and development (never expires)
  7. Production: For App Store releases (requires license)
  8. Copy your API key (starts with rk_dev_wearos_ or rk_live_wearos_)
  9. Your API key enables:

    • 📊 Real-time analytics dashboard
    • 📈 Usage metrics and session tracking
    • 🔍 Error monitoring and debugging
    • 🔐 License validation for production

    Step 2: Installation

    > Private Beta: RotationKit WearOS is currently in private beta distribution via GitHub Packages. Complete setup guide →

    Quick setup:

    1. Add GitHub Packages repository to your project root build.gradle.kts:
    2. kotlin
      allprojects {
          repositories {
              google()
              mavenCentral()
      
              maven {
                  name = "GitHubPackages"
                  url = uri("https://maven.pkg.github.com/joe-corcoran/rotationkit-wearos-sdk")
                  credentials {
                      username = project.findProperty("gpr.user") as String? ?: System.getenv("GPR_USER")
                      password = project.findProperty("gpr.key") as String? ?: System.getenv("GPR_KEY")
                  }
              }
          }
      }
      1. Add RotationKit dependency to your Wear OS module's build.gradle.kts:
      2. kotlin
        dependencies {
            implementation("com.rotationkit.wearos:sdk-unified:1.0.0")
        }

        First time setup? You need a GitHub Personal Access Token with read:packages permission. See PARTNER_SETUP.md for complete instructions.

        Step 3: Basic Integration (5 Minutes)

        kotlin
        import android.os.Bundle
        import androidx.activity.ComponentActivity
        import androidx.activity.compose.setContent
        import com.rotationkit.wearos.RotationKit
        import com.rotationkit.wearos.core.RotationContainer
        import com.rotationkit.wearos.core.RotationEngine
        
        class MainActivity : ComponentActivity() {
            private lateinit var engine: RotationEngine
        
            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
        
                // Initialize RotationKit with telemetry and analytics
                engine = RotationKit.createEngine(
                    ctx = this,
                    cfg = RotationKit.navigationConfig(),
                    deps = RotationKit.Deps(
                        telemetryProvider = RotationKit.telemetryProvider(
                            apiKey = "rk_dev_wearos_YOUR_KEY_HERE" // ← Paste your API key
                        )
                    )
                )
        
                setContent {
                    MaterialTheme {
                        RotationContainer(
                            rotationEngine = engine,
                            modifier = Modifier.fillMaxSize()
                        ) {
                            // Your content - users can rotate with gestures
                            YourNavigationScreen()
                        }
                    }
                }
            }
        
            override fun onResume() {
                super.onResume()
                engine.startTracking()
            }
        
            override fun onPause() {
                super.onPause()
                engine.stopTracking()
            }
        }

        That's it! Your app now has:

        • ✅ Manual rotation with touch gestures
        • ✅ Automatic session tracking
        • ✅ Real-time analytics in your developer portal
        • ✅ Usage metrics and engagement data

        🎮 User Interaction

        Three Rotation Modes

        1. MANUAL LIVE Mode (Default - Recommended)

        • Touch & drag in circular motion to adjust rotation
        • Visual ring indicator during adjustment
        • Smooth, responsive rotation control
        • Perfect for user-customizable orientation

        2. MANUAL LOCKED Mode

        • Rotation angle locked in place
        • Prevents any adjustments until unlocked
        • Maintains current orientation
        • Best for stable viewing of specific content

        3. AUTO Mode (Standard)

        • Fixed orientation, no rotation
        • Normal app behavior
        • Note: Intelligent auto-rotation coming in v2.0

        User Controls

        Mode Switching:

        • Long press (600ms) anywhere on screen → Cycles through modes: MANUAL_LIVE → MANUAL_LOCKED → AUTO → MANUAL_LIVE
        • Haptic feedback confirms mode change (optional callback)
        • Visual indicator shows current mode in your UI

        Manual Rotation (MANUAL LIVE Mode):

        • Circular swipe gesture → Adjust rotation angle
        • Visual ring indicator shows active adjustment mode
        • Smooth drag response with configurable sensitivity
        • Real-time angle feedback in your UI

        📱 Real-World Example: Navigation App

        kotlin
        import android.os.Bundle
        import android.os.VibrationEffect
        import android.os.Vibrator
        import androidx.activity.ComponentActivity
        import androidx.activity.compose.setContent
        import androidx.compose.foundation.layout.*
        import androidx.compose.runtime.*
        import androidx.compose.ui.Modifier
        import com.google.android.gms.maps.compose.GoogleMap
        import com.rotationkit.wearos.RotationKit
        import com.rotationkit.wearos.core.RotationContainer
        import com.rotationkit.wearos.core.RotationEngine
        
        class NavigationActivity : ComponentActivity() {
            private lateinit var rotationEngine: RotationEngine
            private lateinit var vibrator: Vibrator
        
            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
        
                // Navigation-optimized configuration
                rotationEngine = RotationKit.createEngine(
                    ctx = this,
                    cfg = RotationKit.navigationConfig()
                )
        
                vibrator = getSystemService(VIBRATOR_SERVICE) as Vibrator
        
                setContent {
                    MaterialTheme {
                        RotationContainer(
                            rotationEngine = rotationEngine,
                            modifier = Modifier.fillMaxSize(),
                            onModeChange = {
                                // Haptic feedback on mode change
                                vibrator.vibrate(
                                    VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE)
                                )
                            }
                        ) {
                            Box(modifier = Modifier.fillMaxSize()) {
                                // Users can manually adjust map orientation
                                GoogleMap(
                                    modifier = Modifier.fillMaxSize(),
                                    cameraPositionState = cameraPositionState
                                ) {
                                    Marker(/* your location */)
                                    Polyline(/* your route */)
                                }
        
                                // Navigation controls
                                Column(
                                    modifier = Modifier
                                        .fillMaxSize()
                                        .padding(16.dp),
                                    verticalArrangement = Arrangement.SpaceBetween
                                ) {
                                    // Top: Next turn indicator
                                    NextTurnCard(nextInstruction)
        
                                    // Bottom: Mode indicator and ETA
                                    Row(
                                        modifier = Modifier.fillMaxWidth(),
                                        horizontalArrangement = Arrangement.SpaceBetween
                                    ) {
                                        ModeIndicator(rotationEngine)
                                        ETACard(arrivalTime)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        
            override fun onResume() {
                super.onResume()
                rotationEngine.startTracking()
            }
        
            override fun onPause() {
                super.onPause()
                rotationEngine.stopTracking()
            }
        }
        
        @Composable
        fun ModeIndicator(engine: RotationEngine) {
            val mode by engine.rotationMode.collectAsState()
            val angle by engine.displayRotationAngle.collectAsState()
        
            Card {
                Column(horizontalAlignment = Alignment.CenterHorizontally) {
                    Text(
                        text = when (mode) {
                            RotationEngine.RotationMode.MANUAL_LIVE -> "LIVE"
                            RotationEngine.RotationMode.MANUAL_LOCKED -> "LOCKED"
                            RotationEngine.RotationMode.AUTO -> "AUTO"
                        }
                    )
                    Text(text = "${angle.toInt()}°", fontSize = 12.sp)
                }
            }
        }

        🎛 Configuration Options

        Preset Configurations

        kotlin
        // Navigation: Optimized for maps and navigation
        // - Smooth rotation for map readability
        // - Balanced response and stability
        val navigationEngine = RotationKit.createEngine(
            ctx = this,
            cfg = RotationKit.navigationConfig()
        )
        
        // Responsive: Faster rotation tracking
        // - Quick response to gesture input
        // - Less smoothing for immediate feedback
        val responsiveEngine = RotationKit.createEngine(
            ctx = this,
            cfg = RotationKit.responsiveConfig()
        )
        
        // Stable: Smoothest rotation with heavy filtering
        // - Maximum stability during adjustment
        // - Reduces jitter for video/photo viewing
        val stableEngine = RotationKit.createEngine(
            ctx = this,
            cfg = RotationKit.stableConfig()
        )
        
        // Default: General-purpose configuration
        // - Good balance for most applications
        val defaultEngine = RotationKit.createEngine(
            ctx = this,
            cfg = RotationKit.defaultConfig()
        )

        Custom Configuration

        kotlin
        import com.rotationkit.wearos.core.RotationConfig
        import com.rotationkit.wearos.core.RotationEngine
        
        val customConfig = RotationConfig(
            rotationMode = RotationEngine.RotationMode.MANUAL_LIVE,
            updateInterval = 0.1,              // Update interval (seconds)
            calibrationDuration = 3000L,       // Initial calibration time (ms)
            smoothingFactor = 0.3,             // 0.0 = no smoothing, 1.0 = max smoothing
            maxRotationSpeed = 25.0,           // Max degrees per update (prevents jumps)
            transientThreshold = 0.1,          // Motion detection sensitivity
            isLeftWrist = false                // Wrist orientation
        )
        
        val engine = RotationKit.createEngine(
            ctx = this,
            cfg = customConfig
        )

        🔧 Advanced Features

        Observing Rotation State

        kotlin
        @Composable
        fun YourScreen(engine: RotationEngine) {
            // Current display rotation angle (after smoothing/filtering)
            val displayAngle by engine.displayRotationAngle.collectAsState()
        
            // Raw rotation angle
            val rawAngle by engine.rotationAngle.collectAsState()
        
            // Current rotation mode
            val mode by engine.rotationMode.collectAsState()
        
            // Manual mode angle (when in MANUAL_LIVE or MANUAL_LOCKED)
            val manualAngle by engine.manualRotationAngle.collectAsState()
        
            // Calibration status
            val isCalibrating by engine.isCalibrating.collectAsState()
            val calibrationConfidence by engine.calibrationConfidence.collectAsState()
        
            // Wrist orientation
            val isLeftWrist by engine.isLeftWrist.collectAsState()
        
            Column {
                Text("Angle: ${displayAngle.toInt()}°")
                Text("Mode: $mode")
                if (isCalibrating) {
                    Text("Calibrating... (${(calibrationConfidence * 100).toInt()}%)")
                }
            }
        }

        Programmatic Control

        kotlin
        // Toggle between rotation modes
        engine.toggleManualMode()
        
        // Adjust manual rotation angle
        engine.adjustManualRotation(45.0) // Rotate 45° clockwise
        
        // Switch wrist side
        engine.toggleWristSide()
        engine.setIsLeftWrist(true)
        
        // Check current mode
        when (engine.rotationMode.value) {
            RotationEngine.RotationMode.MANUAL_LIVE -> {
                // User can adjust rotation with gestures
            }
            RotationEngine.RotationMode.MANUAL_LOCKED -> {
                // Rotation is locked
            }
            RotationEngine.RotationMode.AUTO -> {
                // Standard fixed orientation
            }
        }

        Optional Settings Persistence

        kotlin
        import com.rotationkit.wearos.core.RotationSettings
        import kotlinx.coroutines.flow.first
        
        // Initialize settings helper (optional - provides DataStore persistence)
        val settings = RotationSettings(context)
        
        // Load persisted settings
        lifecycleScope.launch {
            settings.wristSideFlow.first()?.let { isLeft ->
                engine.setIsLeftWrist(isLeft)
            }
        
            settings.rollOffsetFlow.first()?.let { offset ->
                // Apply saved calibration offset
            }
        
            settings.initialRotationFlow.first()?.let { rotation ->
                // Restore last rotation angle
            }
        }
        
        // Save current settings
        lifecycleScope.launch {
            settings.saveWristSide(engine.isLeftWrist.value)
            settings.saveRollOffset(engine.rollOffsetDeg.value)
            settings.saveInitialRotation(engine.displayRotationAngle.value)
        }

        Simple Container (Custom Input Handling)

        If you want to handle gestures yourself:

        kotlin
        import com.rotationkit.wearos.core.SimpleRotationContainer
        
        @Composable
        fun YourScreen(engine: RotationEngine) {
            SimpleRotationContainer(
                rotationEngine = engine,
                modifier = Modifier.fillMaxSize()
            ) {
                // Content rotates but no built-in gesture handling
                // Implement your own gestures as needed
                YourCustomUI()
            }
        }

        📊 Performance

        • Battery Impact: <1% additional drain in manual mode
        • Frame Rate: Maintains 60fps during active rotation
        • Memory Usage: <5MB additional memory
        • Update Interval: Configurable 50-200ms (default 100ms)
        • Calibration Time: 3 seconds initial calibration
        • Compatibility: Wear OS 3.0+ (API 30+), all Wear OS devices

        Technical Details

        Rotation Control:

        • Circular gesture detection for manual adjustment
        • Exponential smoothing with configurable factor (0.0-1.0)
        • Max rotation speed limiting prevents jarring jumps
        • Visual feedback with animated ring indicators

        Rendering:

        • Compose modifier-based rotation (no re-composition overhead)
        • StateFlow updates trigger minimal recomposition
        • Efficient angle calculations with vector math

        🎯 Use Cases

        Perfect For:

        • 🗺 Navigation Apps: Allow users to orient maps for optimal readability
        • Manual adjustment for preferred "north up" vs "heading up"
        • Quick orientation changes while cycling or driving
        • 🏃‍♂️ Fitness Apps: Let users adjust stats display orientation
        • Customize viewing angle for different exercises
        • Lock orientation during high-intensity workouts
        • 🚴‍♀️ Cycling Apps: Accommodate handlebar mounting positions
        • Adjust for different bike setups (road, mountain, indoor)
        • Lock orientation to prevent accidental changes
        • 📱 Hands-Free Apps: Industrial, medical, or field work
        • Allow orientation adjustment with simple gestures
        • Lock to prevent accidental rotation during use
        • ⌚ Watch Faces: User-adjustable complication orientation
        • Let users customize complication layout
        • Enhanced readability for different wrist positions

        📚 API Reference

        RotationKit Object

        Main SDK entry point providing factory methods and presets.

        kotlin
        object RotationKit {
            const val VERSION: String = "1.0.0"
        
            // Factory methods
            fun createEngine(
                ctx: Context,
                cfg: RotationConfig = defaultRotationConfig(),
                deps: Deps = Deps()
            ): RotationEngine
        
            // Preset configurations
            fun navigationConfig(): RotationConfig
            fun responsiveConfig(): RotationConfig
            fun stableConfig(): RotationConfig
            fun defaultConfig(): RotationConfig
        
            // Dependency injection
            data class Deps(
                val telemetryProvider: TelemetryProvider? = null,
                val licenseValidator: LicenseValidator? = null
            )
        }

        RotationEngine Class

        Core engine managing rotation state and gestures.

        kotlin
        class RotationEngine(
            private val context: Context,
            private val config: RotationConfig = RotationConfig()
        ) : SensorEventListener {
        
            // Observable state flows
            val rotationAngle: StateFlow<Double>                    // Raw rotation angle
            val displayRotationAngle: StateFlow<Double>             // Filtered display angle
            val manualRotationAngle: StateFlow<Double>              // Manual mode angle
            val rotationMode: StateFlow<RotationMode>               // Current mode
            val isManualMode: StateFlow<Boolean>                    // Manual mode status
            val isCalibrating: StateFlow<Boolean>                   // Calibration status
            val calibrationConfidence: StateFlow<Double>            // Confidence 0.0-1.0
            val inTransientState: StateFlow<Boolean>                // Rapid movement detection
            val isLeftWrist: StateFlow<Boolean>                     // Wrist side
            val rollOffsetDeg: StateFlow<Float>                     // Roll calibration offset
            val pitchOffsetDeg: StateFlow<Float>                    // Pitch calibration offset
        
            // Lifecycle methods
            fun startTracking()                                     // Start sensor updates
            fun stopTracking()                                      // Stop sensor updates
        
            // Control methods
            fun toggleManualMode()                                  // Cycle through modes
            fun adjustManualRotation(deltaDegrees: Double)          // Adjust manual angle
            fun toggleWristSide()                                   // Switch left/right
            fun setIsLeftWrist(isLeft: Boolean)                     // Set wrist side
        
            // Advanced methods (rarely needed - calibration is automatic)
            fun recalibrate()                                       // Manual recalibration (advanced use only)
        
            // Rotation modes
            enum class RotationMode {
                MANUAL_LIVE,    // User-adjustable with gestures (v1.0)
                MANUAL_LOCKED,  // Fixed rotation angle (v1.0)
                AUTO            // Standard fixed orientation (v1.0) / Smart rotation (v2.0)
            }
        }

        RotationContainer Composable

        Compose wrapper applying rotation transformation with gesture handling.

        kotlin
        @Composable
        fun RotationContainer(
            rotationEngine: RotationEngine,
            modifier: Modifier = Modifier,
            onModeChange: (() -> Unit)? = null,
            content: @Composable () -> Unit
        )

        Features:

        • Long-press gesture for mode toggling (600ms MANUAL, 1200ms LOCKED)
        • Circular drag gestures for MANUAL_LIVE adjustments
        • Visual ring overlay in MANUAL_LIVE mode
        • Animated mode transitions

        SimpleRotationContainer Composable

        Rotation wrapper without gesture handling (custom control).

        kotlin
        @Composable
        fun SimpleRotationContainer(
            rotationEngine: RotationEngine,
            modifier: Modifier = Modifier,
            content: @Composable () -> Unit
        )

        Use when:

        • You need custom gesture handling
        • You want programmatic mode control only
        • You're building custom UI controls

        RotationConfig Data Class

        Configuration for RotationEngine behavior.

        kotlin
        data class RotationConfig(
            val rotationMode: RotationEngine.RotationMode = RotationEngine.RotationMode.MANUAL_LIVE,
            val updateInterval: Double = 0.1,               // Update interval (seconds)
            val calibrationDuration: Long = 3000L,          // Initial calibration (ms)
            val smoothingFactor: Double = 0.3,              // Smoothing 0.0-1.0
            val maxRotationSpeed: Double = 25.0,            // Max degrees per update
            val transientThreshold: Double = 0.1,           // Motion detection sensitivity
            val isLeftWrist: Boolean = false                // Wrist side
        )

        RotationSettings Helper

        Optional DataStore-based persistence for user preferences.

        kotlin
        class RotationSettings(context: Context) {
            val wristSideFlow: Flow<Boolean?>
            val rollOffsetFlow: Flow<Float?>
            val pitchOffsetFlow: Flow<Float?>
            val initialRotationFlow: Flow<Double?>
        
            suspend fun saveWristSide(isLeft: Boolean)
            suspend fun saveRollOffset(offset: Float)
            suspend fun savePitchOffset(offset: Float)
            suspend fun saveInitialRotation(rotation: Double)
            suspend fun clearAll()
        }

        📊 Developer Portal & Analytics

        Real-Time Dashboard

        Every RotationKit integration includes access to a comprehensive developer portal with real-time analytics.

        Access your portal: https://rotationkit-5ea5d.web.app

        What you get:

        • 📈 Session Metrics: Total sessions, active users, session duration
        • 🔄 Rotation Analytics: Mode usage, angle changes, tracking duration
        • 📱 Device Insights: Device models, OS versions, platform distribution
        • ⚠️ Error Monitoring: Error rates, crash tracking, performance metrics
        • 🔑 API Key Management: Create, revoke, and monitor API key usage

        Automatic Event Tracking

        RotationKit automatically tracks these events (no code required):

        • session_started - When user opens your app
        • session_ended - When user closes your app
        • rotation_tracking_started - When rotation engine starts
        • rotation_tracking_stopped - When rotation engine stops
        • rotation_mode_changed - When user switches modes
        • rotation_angle_changed - When rotation angle changes >5°

        Privacy by design:

        • No personal identifiable information (PII) collected
        • No names, emails, or phone numbers
        • Only anonymous session and usage data
        • GDPR/CCPA compliant by default

        Custom Event Tracking

        Track app-specific events for deeper insights:

        kotlin
        import com.rotationkit.wearos.telemetry.RkEvent
        
        // Track screen views
        telemetrySink.enqueue(RkEvent.ScreenViewed(
            timestamp = System.currentTimeMillis(),
            sessionId = sessionId,
            screenName = "WorkoutDetail",
            previousScreen = "WorkoutList"
        ))
        
        // Track feature usage
        telemetrySink.enqueue(RkEvent.FeatureUsed(
            timestamp = System.currentTimeMillis(),
            sessionId = sessionId,
            featureName = "create_workout",
            metadata = mapOf("type" to "running", "duration" to "30min")
        ))
        
        // Track custom events
        telemetrySink.enqueue(RkEvent.CustomEvent(
            timestamp = System.currentTimeMillis(),
            sessionId = sessionId,
            name = "workout_completed",
            properties = mapOf(
                "type" to "running",
                "distance" to 5.2,
                "duration" to 1800
            )
        ))

        Telemetry Configuration

        Control telemetry behavior:

        kotlin
        // Disable telemetry completely (not recommended)
        val engine = RotationKit.createEngine(
            ctx = this,
            cfg = RotationKit.navigationConfig(),
            deps = RotationKit.Deps(
                telemetryProvider = null  // No analytics
            )
        )
        
        // Custom telemetry configuration
        val telemetryProvider = RotationKit.telemetryProvider(
            apiKey = "your_api_key",
            batchSize = 10,              // Events per batch
            flushInterval = 30.0,        // Seconds between flushes
            maxQueueSize = 1000          // Max queued events
        )

        Analytics Best Practices

        1. Always include API key - Enables full analytics features
        2. Use descriptive names - Make screen/feature names meaningful
        3. Add custom events - Track app-specific user journeys
        4. Monitor error rates - Check portal regularly for issues
        5. Review device distribution - Optimize for popular devices
        6. What Data is Collected?

          Automatic Events:

          • Session ID (ephemeral, changes per session)
          • Timestamp (Unix epoch milliseconds)
          • Device model (e.g., "Galaxy Watch 5")
          • OS version (e.g., "WearOS 4.0")
          • App version (from your AndroidManifest)
          • Rotation mode, angle, and tracking duration

          NOT Collected:

          • User names or emails
          • Location data (GPS coordinates)
          • Health metrics or sensor data
          • Personal identifiable information
          • End-user account IDs

          Learn more: See TELEMETRY_EVENTS.md for complete event reference


          🏗 SDK Architecture

          RotationKit uses a modular architecture for flexibility and maintainability:

          code
          sdk-unified/          ← Main integration point
            ├── RotationKit.kt  ← Factory and presets
            └── depends on ↓
          
          sdk-core/             ← Core rotation logic
            ├── RotationEngine.kt        ← Rotation engine
            ├── RotationContainer.kt     ← Compose wrappers
            ├── RotationConfig.kt        ← Configuration
            ├── RotationSettings.kt      ← Persistence helper
            └── RotationKitPresets.kt    ← Preset builders
          
          sdk-telemetry/        ← Usage analytics (optional)
            └── TelemetryProvider.kt
          
          sdk-license/          ← License validation (optional)
            └── LicenseValidator.kt

          Import the unified SDK:

          kotlin
          implementation(project(":sdk-unified"))

          Or import specific modules:

          kotlin
          implementation(project(":sdk-core"))          // Core functionality only
          implementation(project(":sdk-telemetry"))     // Add telemetry
          implementation(project(":sdk-license"))       // Add licensing

          🐛 Troubleshooting

          Issue: Rotation feels too sensitive / jittery

          Solution: Increase smoothing factor and decrease max rotation speed

          kotlin
          val config = RotationConfig(
              smoothingFactor = 0.5,      // More smoothing
              maxRotationSpeed = 15.0     // Slower max speed
          )

          Issue: Rotation feels sluggish / lags behind gestures

          Solution: Decrease smoothing, increase speed, decrease update interval

          kotlin
          val config = RotationConfig(
              smoothingFactor = 0.1,      // Less smoothing
              maxRotationSpeed = 35.0,    // Faster max speed
              updateInterval = 0.05       // More frequent updates (50ms)
          )

          Issue: Gestures not being detected

          Solution: Verify no conflicting gesture handlers in parent composables

          • Check that parent composables don't consume touch events
          • Ensure RotationContainer is used (not SimpleRotationContainer)

          Issue: Long press not toggling modes

          Solution: Verify no conflicting long-press handlers

          Issue: Wrong orientation after rotating

          Solution: Toggle wrist side or set explicitly

          kotlin
          engine.toggleWristSide()
          // or
          engine.setIsLeftWrist(true)  // for left wrist

          ✅ Integration Checklist

          Basic Integration

          • [ ] Add SDK dependency to build.gradle.kts
          • [ ] Initialize RotationEngine in Activity's onCreate()
          • [ ] Choose appropriate preset config (navigation, responsive, stable, or default)
          • [ ] Wrap UI content with RotationContainer composable
          • [ ] Call startTracking() in onResume()
          • [ ] Call stopTracking() in onPause()
          • [ ] Add haptic feedback callback to onModeChange
          • [ ] Display current mode indicator in UI
          • [ ] Show rotation angle for user feedback
          • [ ] Add settings screen for wrist side selection
          • [ ] Persist user preferences with RotationSettings
          • [ ] Add user onboarding showing gesture controls

          Testing

          • [ ] Test on physical Wear OS device
          • [ ] Test all three rotation modes (MANUAL_LIVE, MANUAL_LOCKED, AUTO)
          • [ ] Test mode toggling with long press
          • [ ] Test circular swipe gestures in MANUAL_LIVE mode
          • [ ] Test left and right wrist orientations
          • [ ] Verify smooth 60fps rotation
          • [ ] Check battery drain over extended session

          Production Ready

          • [ ] Configure telemetry provider (optional)
          • [ ] Implement license validation (if required)
          • [ ] Document rotation controls in user onboarding
          • [ ] Test edge cases (rapid gestures, extreme angles)
          • [ ] Add analytics tracking for feature usage

          🔄 Version & Roadmap

          Version 1.0.0 (Current - Production Ready)

          Manual Rotation Features:

          • ✅ Precision manual rotation with circular gesture detection
          • ✅ Three rotation modes (MANUAL_LIVE, MANUAL_LOCKED, AUTO)
          • ✅ Long-press mode toggle with configurable timing
          • ✅ Visual feedback with animated ring indicators
          • ✅ Smooth rotation with exponential smoothing
          • ✅ Jetpack Compose integration
          • ✅ Preset configurations (navigation, responsive, stable, default)
          • ✅ Optional settings persistence with DataStore
          • ✅ Real-time StateFlow observations
          • ✅ Sample application demonstrating all features

          Current Capabilities:

          • Users manually adjust screen orientation with intuitive gestures
          • Three modes provide flexibility for different use cases
          • Smooth, responsive rotation with configurable sensitivity
          • Production-ready performance and stability

          Version 2.0.0 (In Development - Q3 2025)

          Intelligent Auto-Rotation (Coming Soon):

          We're actively developing advanced sensor fusion technology that will bring intelligent automatic rotation to RotationKit. This major v2.0 feature will transform how users interact with your Wear OS app.

          Planned Auto-Rotation Features:

          • 🚧 Gravity-Based Auto-Rotation: Automatically maintain optimal screen orientation based on wrist position
          • 🚧 Advanced Sensor Fusion: TYPE_GRAVITY sensor integration with sophisticated filtering
          • 🚧 Wrist Detection: Automatic left/right wrist detection with coordinate mapping
          • 🚧 Motion Filtering: Smart detection of transient movement to prevent over-rotation
          • 🚧 Calibration System: 3-second automatic calibration with confidence scoring
          • 🚧 Seamless Integration: Works with existing v1.0 code - just update config to enable AUTO mode

          How Auto-Rotation Will Work:

          kotlin
          // v2.0 - Simply set rotationMode to AUTO
          val autoConfig = RotationConfig(
              rotationMode = RotationEngine.RotationMode.AUTO,  // Enables smart rotation
              smoothingFactor = 0.3,                            // Auto-rotation smoothing
              transientThreshold = 0.1                          // Motion detection sensitivity
          )
          
          val engine = RotationKit.createEngine(ctx = this, cfg = autoConfig)
          
          // Content automatically rotates as user moves wrist
          RotationContainer(rotationEngine = engine) {
              GoogleMap(/* stays north-up regardless of wrist angle */)
          }

          Technical Approach:

          • Port of proven WatchOS RotationKit sensor fusion algorithms
          • iOS CMDeviceMotion.gravity → Android TYPE_GRAVITY sensor mapping
          • Exponential smoothing + speed limiting + transient detection
          • Left/right wrist coordinate system transformation
          • Confidence-based calibration during initial 3 seconds

          Use Cases for Auto-Rotation:

          • Navigation Apps: Maps automatically stay north-up while cycling/driving
          • Fitness Apps: Stats remain readable during workouts without manual adjustment
          • Cycling Apps: Perfect for handlebar-mounted watches at any angle
          • Hands-Free Apps: Industrial/medical apps work without touch interaction

          Backward Compatibility:

          • v1.0 apps work unchanged in v2.0
          • AUTO mode becomes "smart auto-rotation" (currently just fixed orientation)
          • All existing manual rotation features remain available
          • Migration guide will be provided

          Beta Access:

          • Integration partners get early access to v2.0 beta
          • Feedback welcome during development phase
          • Contact us to join the beta program

          Version 1.1.0 (Q1 2025)

          • 🚧 Rotating bezel/crown input support for Samsung Galaxy Watch
          • 🚧 Enhanced telemetry and usage analytics
          • 🚧 Accessibility improvements (TalkBack optimization)
          • 🚧 Battery optimization profiles
          • 🚧 Wear OS Tiles integration examples

          Version 2.1.0+ (Q4 2025)

          • 🚧 Machine learning-based rotation prediction
          • 🚧 Activity-specific rotation profiles
          • 🚧 Multi-device sync for paired apps
          • 🚧 Advanced gesture recognition (custom patterns)
          • 🚧 Health Connect integration examples

          📄 Licensing & Distribution

          RotationKit WearOS SDK is available for commercial partnerships with flexible licensing options.

          License Options

          🔧 Developer License (Free Forever)

          • ✅ Full SDK access for development and testing
          • ✅ Complete analytics dashboard
          • ✅ Unlimited API key generation
          • ✅ Never expires
          • ✅ Perfect for prototyping and evaluation
          • ❌ Not for production deployment

          💼 Commercial License (Contact Sales)

          • ✅ Production deployment rights for Play Store
          • ✅ Single application license
          • ✅ Backend license validation
          • ✅ Priority email support (<24hr response)
          • ✅ 1 year of updates and bug fixes
          • ✅ Access to v2.0 when released
          • ✅ Full telemetry and analytics
          • 💰 Pricing: Contact for quote

          🏢 Enterprise License (Contact Sales)

          • ✅ Everything in Commercial License
          • ✅ Multiple applications (up to 5)
          • ✅ White-label options available
          • ✅ Dedicated Slack channel
          • ✅ Integration consultation (up to 10 hours)
          • ✅ Priority feature requests
          • ✅ Early access to v2.0 beta
          • ✅ Custom SLA agreements
          • 💰 Pricing: Contact for quote

          How Licensing Works

          1. Development Phase (Free)
          2. Create Developer API key in portal
          3. Use key starting with rk_dev_wearos_
          4. Full SDK functionality for testing
            1. Production Deployment (Requires License)
            2. Purchase Commercial or Enterprise license
            3. Create Production API key in portal
            4. Use key starting with rk_live_wearos_
            5. Backend validates license on first app launch
              1. License Validation
              2. Automatic validation against Firebase backend
              3. Runs once per device installation
              4. Cached locally after first validation
              5. No recurring checks (no internet required after first launch)
              6. Get a Production License

                1. Contact Sales: licensing@rotationkit.com
                2. Provide:
                3. App name and package ID
                4. Expected user count
                5. Deployment timeline
                6. Receive license agreement and pricing quote
                7. Sign agreement and complete payment
                8. Production API key activated in your portal within 24 hours
                9. Partnership Opportunities

                  We're actively seeking partnerships with:

                  • 🗺 Navigation and mapping providers
                  • 🏃‍♂️ Fitness and health tracking platforms
                  • 🚴‍♀️ Cycling and outdoor sports companies
                  • 🏢 Enterprise wearable solution providers
                  • ⌚ Device manufacturers (Samsung, Fossil, TicWatch, etc.)

                  Beta Program: Interested in being an early adopter for v2.0 auto-rotation? Join our beta program for early access and discounted licensing.

                  Contact: contact@rotationkit.com


                  🆘 Support & Resources

                  Technical Support

                  • 📧 Email Support: contact@rotationkit.com
                  • 💬 Integration Consultation: Schedule a 1-on-1 integration call
                  • 🐛 Bug Reports: Via email or partner portal
                  • Response Time: <24 hours for commercial licenses

                  Documentation

                  • 📚 API Reference: See API Reference section above
                  • 🎓 Sample App: Included in SDK repository (/sample)
                  • 📖 Integration Guide: Complete step-by-step guide
                  • 🎥 Video Tutorials: Coming Q1 2025

                  Community

                  • 🔗 GitHub: Issue tracking and feature requests
                  • 📱 Discord: Partner community (invitation only)
                  • 📰 Newsletter: Monthly updates and beta announcements

                  📈 Success Stories

                  > "RotationKit's manual rotation feature transformed our cycling navigation app. Users love being able to quickly adjust the map orientation with simple gestures."

                  > — Lead Developer, Major Cycling App

                  > "The gesture detection is incredibly smooth. We integrated it in 2 hours and our beta testers immediately noticed the improvement. Can't wait for v2.0 auto-rotation!"

                  > — Engineering Manager, Fitness Platform

                  > "Perfect solution for user-controlled orientation. The three-mode system gives our users exactly the flexibility they need."

                  > — CTO, Health Tracking Startup


                  🤝 Contributing

                  While RotationKit is commercial software, we welcome feedback and feature requests from integration partners.

                  Partner Feedback Process:

                  1. Report issues via partner portal or email
                  2. Request features through your account manager
                  3. Priority given to enterprise partners
                  4. Beta access for new features available
                  5. v2.0 Beta Program:

                    • Join early to help shape auto-rotation features
                    • Provide real-world testing feedback
                    • Influence roadmap priorities
                    • Contact: contact@rotationkit.com

                    📜 Credits

                    Developed by the RotationKit Team

                    Manual rotation engine built for Wear OS with Jetpack Compose. Auto-rotation sensor fusion algorithms (v2.0) adapted from the proven WatchOS RotationKit SDK.

                    Built with:

                    • Kotlin 1.9+
                    • Jetpack Compose for Wear OS
                    • AndroidX DataStore
                    • Coroutines & StateFlow

                    📞 Contact

                    All Inquiries: contact@rotationkit.com

                    Topics:

                    • General information and sales
                    • Technical support
                    • Partnership opportunities
                    • Beta program access (v2.0)
                    • Custom integration services

                    Business Hours: Monday-Friday, 9am-6pm EST

                    Emergency Support: Available for Enterprise license holders


                    Built for professional Wear OS developers

                    Transform your Wear OS app with precision manual rotation control

                    v2.0: Intelligent auto-rotation coming Q3 2025

                    © 2025 RotationKit. All rights reserved.

                    © 2025 RotationKit. All rights reserved.