|
| 1 | +--- |
| 2 | +description: >- |
| 3 | + Learn how to set up Seam Mobile Components in your Android project using GitHub |
| 4 | + Packages, drop in SeamAccessView for a complete unlock flow, and |
| 5 | + customize the look with SeamComponentsTheme. |
| 6 | +--- |
| 7 | + |
| 8 | +# Seam Mobile Components for Android |
| 9 | + |
| 10 | +#### Prerequisites |
| 11 | + |
| 12 | +* **Compile SDK:** 35 |
| 13 | +* **Kotlin Version:** 2.1.0 or greater |
| 14 | +* **Minimum Android SDK:** The required `minSdk` depends on the specific Seam integration modules you include: |
| 15 | + * Base SDK (Core, API, Common, Network, Analytics): **API Level 24** (Android 7.0) |
| 16 | + * Including `saltoks` or `saltospace`: **API Level 24** (Android 7.0) |
| 17 | + * Including `latch`: **API Level 26** (Android 8.0) |
| 18 | + * Including `assaabloy`: **API Level 28** (Android 9.0) |
| 19 | + |
| 20 | + Your application's `minSdk` must be set to the **highest** level required by any of the Seam modules you use. |
| 21 | + |
| 22 | + |
| 23 | +You should already have a Seam workspace and API key set up. If you’re new to Seam, start with the [Seam Mobile SDK](https://docs.seam.co/latest/developer-tools/mobile-sdks/android-sdk). |
| 24 | + |
| 25 | +*** |
| 26 | + |
| 27 | +### Installation |
| 28 | + |
| 29 | +Setup your project to get the Android SDK Packages form GitHub, as described [here](https://docs.seam.co/latest/capability-guides/mobile-access/mobile-device-sdks/initializing-the-seam-mobile-sdk). |
| 30 | + |
| 31 | +Add the Seam Components library and required SDK modules to your app's `build.gradle.kts` (or `build.gradle` for Groovy): |
| 32 | + |
| 33 | +**Kotlin DSL (`build.gradle.kts`):** |
| 34 | +```kotlin |
| 35 | +dependencies { |
| 36 | + val seamVersion = "3.1.1" // Check for latest version |
| 37 | + |
| 38 | + // Required: Seam Components UI library |
| 39 | + implementation("co.seam:seam-phone-sdk-android-seamcomponents:$seamVersion") |
| 40 | + |
| 41 | + // Required: Core SDK functionality |
| 42 | + implementation("co.seam:seam-phone-sdk-android-core:$seamVersion") |
| 43 | + |
| 44 | + // Optional: Add integration modules as needed based on your lock providers |
| 45 | + implementation("co.seam:seam-phone-sdk-android-assaabloy:$seamVersion") // minSdk 28 |
| 46 | + implementation("co.seam:seam-phone-sdk-android-latch:$seamVersion") // minSdk 26 |
| 47 | + implementation("co.seam:seam-phone-sdk-android-saltoks:$seamVersion") // minSdk 24 |
| 48 | + implementation("co.seam:seam-phone-sdk-android-saltospace:$seamVersion") // minSdk 24 |
| 49 | +} |
| 50 | +``` |
| 51 | + |
| 52 | +**Groovy (`build.gradle`):** |
| 53 | +```groovy |
| 54 | +dependencies { |
| 55 | + def seamVersion = "3.1.1" // Check for latest version |
| 56 | +
|
| 57 | + // Required: Seam Components UI library |
| 58 | + implementation "co.seam:seam-phone-sdk-android-seamcomponents:$seamVersion" |
| 59 | +
|
| 60 | + // Required: Core SDK functionality |
| 61 | + implementation "co.seam:seam-phone-sdk-android-core:$seamVersion" |
| 62 | +
|
| 63 | + // Optional: Add integration modules as needed |
| 64 | + implementation "co.seam:seam-phone-sdk-android-assaabloy:$seamVersion" // minSdk 28 |
| 65 | + implementation "co.seam:seam-phone-sdk-android-latch:$seamVersion" // minSdk 26 |
| 66 | + implementation "co.seam:seam-phone-sdk-android-saltoks:$seamVersion" // minSdk 24 |
| 67 | + implementation "co.seam:seam-phone-sdk-android-saltospace:$seamVersion" // minSdk 24 |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +### Quick Start: `SeamAccessView` |
| 72 | + |
| 73 | +### Quick Start - Complete Integration |
| 74 | + |
| 75 | +#### SeamAccessView - Your Complete Solution |
| 76 | + |
| 77 | +`SeamAccessView` is the main entry point composable for the Seam access management interface. This powerful component manages the entire user flow for accessing and managing credentials through the Seam SDK, making it the perfect choice for most applications. |
| 78 | + |
| 79 | +**What SeamAccessView handles for you:** |
| 80 | +- **SDK Initialization**: Automatically initializes the Seam SDK with your session token |
| 81 | +- **Navigation Management**: Handles screen transitions and navigation state |
| 82 | +- **UI State Management**: Manages loading, error handling, and different application states |
| 83 | +- **OTP Authorization**: Automatically handles OTP verification flows when required |
| 84 | +- **Bluetooth Permissions**: Guides users through Bluetooth setup when needed for credential operations |
| 85 | + |
| 86 | +**Screen Orchestration:** |
| 87 | +SeamAccessView automatically navigates between these screens based on application state: |
| 88 | +- **Credentials List Screen**: For viewing available keys with pull-to-refresh functionality |
| 89 | +- **OTP Authorization Screen**: For completing authentication flows in a WebView |
| 90 | +- **Bluetooth Redirect Screen**: For handling Bluetooth permission and setup |
| 91 | +- **Unlock Overlay**: For interacting with individual credentials through a modal interface |
| 92 | + |
| 93 | +#### Basic Usage |
| 94 | + |
| 95 | +For most use cases, you can use `SeamAccessView` as a complete solution: |
| 96 | + |
| 97 | +```kotlin |
| 98 | +@Composable |
| 99 | +fun MyApp() { |
| 100 | + MyAppTheme { |
| 101 | + SeamAccessView( |
| 102 | + clientSessionToken = "your-session-token-here" |
| 103 | + ) |
| 104 | + } |
| 105 | +} |
| 106 | +``` |
| 107 | + |
| 108 | +#### With Custom Navigation |
| 109 | + |
| 110 | +If you need more control over navigation or want to integrate with your existing navigation setup: |
| 111 | + |
| 112 | +```kotlin |
| 113 | +@Composable |
| 114 | +fun MyApp() { |
| 115 | + val navController = rememberNavController() |
| 116 | + |
| 117 | + MyAppTheme { |
| 118 | + SeamAccessView( |
| 119 | + clientSessionToken = "your-session-token-here", |
| 120 | + context = LocalContext.current, |
| 121 | + navController = navController |
| 122 | + ) |
| 123 | + } |
| 124 | +} |
| 125 | +``` |
| 126 | + |
| 127 | +**Parameters:** |
| 128 | +- `clientSessionToken`: Required session token for SDK authentication and initialization |
| 129 | +- `context`: Android context (defaults to current composition's local context) |
| 130 | +- `navController`: Navigation controller for screen transitions (defaults to a new instance) |
| 131 | + |
| 132 | +### Initialization & Authentication |
| 133 | + |
| 134 | +#### Client Session Token (CST) Management |
| 135 | + |
| 136 | +Client Session Tokens authenticate your mobile app with Seam's backend. These tokens should be generated by your backend server using Seam's API. |
| 137 | + |
| 138 | +#### Obtaining a CST |
| 139 | +Ask Seam about how to obtain a CST. |
| 140 | +For more details see [Seam's Client Session Token documentation](https://docs.seam.co/latest/core-concepts/authentication/client-session-tokens). |
| 141 | + |
| 142 | + |
| 143 | +#### SDK Initialization |
| 144 | + |
| 145 | +When using individual components instead of `SeamAccessView`, you must manually initialize the Seam SDK: |
| 146 | + |
| 147 | +```kotlin |
| 148 | +@Composable |
| 149 | +fun MyCredentialsScreen(clientSessionToken: String) { |
| 150 | + val context = LocalContext.current |
| 151 | + |
| 152 | + LaunchedEffect(clientSessionToken) { |
| 153 | + try { |
| 154 | + // Initialize the SDK. This part is usually done in a ViewModel |
| 155 | + SeamSDK.initialize( |
| 156 | + context = context, |
| 157 | + clientSessionToken = clientSessionToken |
| 158 | + ) |
| 159 | + |
| 160 | + // Activate the SDK after initialization |
| 161 | + SeamSDK.getInstance().activate() |
| 162 | + } catch (error: SeamError) { |
| 163 | + // handle error |
| 164 | + } |
| 165 | + } |
| 166 | + |
| 167 | + SeamCredentialsView( |
| 168 | + onNavigateToUnlock = { /* Handle navigation */ } |
| 169 | + ) |
| 170 | +} |
| 171 | +``` |
| 172 | + |
| 173 | +### Screen Components |
| 174 | + |
| 175 | +When you need more granular control than `SeamAccessView` provides, you can use individual screen components to build custom flows while still benefiting from Seam's pre-built UI. |
| 176 | + |
| 177 | +#### SeamCredentialsView |
| 178 | + |
| 179 | +**What it does:** A composable screen that displays cards for user credentials (keys) with comprehensive state management and user interaction support. |
| 180 | + |
| 181 | +**Key Features:** |
| 182 | +- **State Management**: Automatically handles loading, success with data, and empty states |
| 183 | +- **Pull-to-Refresh**: Built-in refresh functionality for updating credential data |
| 184 | +- **Error Handling**: Displays appropriate user feedback for error states |
| 185 | +- **Navigation Integration**: Provides callback for seamless navigation to unlock interfaces |
| 186 | +- **Internet Status**: Shows connection status and handles offline scenarios |
| 187 | + |
| 188 | +**When to use:** When you want a complete credentials listing screen but need to customize the navigation or integrate with your own view models and navigation system. |
| 189 | + |
| 190 | +```kotlin |
| 191 | +@Composable |
| 192 | +fun CredentialsScreen() { |
| 193 | + // viewModel is optional |
| 194 | + val viewModel: KeysViewModel = viewModel() |
| 195 | + |
| 196 | + // Remember to initialize the SDK before using the view. See previous section for details. |
| 197 | + SeamCredentialsView( |
| 198 | + viewModel = viewModel, |
| 199 | + onNavigateToUnlock = { keyCard -> |
| 200 | + // Navigate to unlock screen |
| 201 | + println("Unlocking key: ${keyCard.name}") |
| 202 | + } |
| 203 | + ) |
| 204 | +} |
| 205 | +``` |
| 206 | + |
| 207 | +#### SeamUnlockCardView |
| 208 | + |
| 209 | +**What it does:** A modal bottom sheet composable that provides a complete user interface for unlocking credentials with phase-based state management. |
| 210 | + |
| 211 | +**Key Features:** |
| 212 | +- **Modal Presentation**: Displays as an overlay bottom sheet that doesn't disrupt the main UI |
| 213 | +- **Unlock Phases**: Manages different states (idle, scanning, success, failed) with appropriate UI feedback |
| 214 | +- **Theme Integration**: Supports customization through SeamUnlockCardStyle theming |
| 215 | +- **Automatic State Reset**: Handles cleanup when dismissed or navigation occurs |
| 216 | +- **Error Recovery**: Built-in error states with retry functionality |
| 217 | + |
| 218 | +**When to use:** When you want to provide unlock functionality in a modal format, either triggered from your custom credential list or integrated into your own navigation flow. |
| 219 | + |
| 220 | +```kotlin |
| 221 | +@Composable |
| 222 | +fun UnlockModal(keyCard: KeyCard) { |
| 223 | + |
| 224 | + val viewModel: KeysViewModel = viewModel() |
| 225 | + |
| 226 | + var showUnlock by remember { mutableStateOf(false) } |
| 227 | + var selectedKeyCard by remember { mutableStateOf<KeyCard?>(null) } |
| 228 | + |
| 229 | + // Remember to initialize the SDK before using the view. See previous section for details. |
| 230 | + SeamCredentialsView( |
| 231 | + viewModel = viewModel, |
| 232 | + onNavigateToUnlock = { keyCard -> |
| 233 | + // Navigate to unlock screen |
| 234 | + selectedKeyCard = keyCard |
| 235 | + showUnlock = true |
| 236 | + } |
| 237 | + ) |
| 238 | + |
| 239 | + // The simplest way to use the unlock view is to call it on `onNavigateToUnlock` |
| 240 | + // callback from `SeamCredentialsView`, as it already provides the keyCard |
| 241 | + |
| 242 | + SeamUnlockCardView( |
| 243 | + keyCard = keyCard, |
| 244 | + onNavigateBack = { showUnlock = false } |
| 245 | + ) |
| 246 | +} |
| 247 | +``` |
| 248 | + |
| 249 | +#### SeamOtpView |
| 250 | + |
| 251 | +**What it does:** A full-screen dialog composable that displays an OTP (One-Time Password) verification interface using a WebView for interactive authentication flows. |
| 252 | + |
| 253 | +**Key Features:** |
| 254 | +- **Full-Screen Presentation**: Renders as a dialog that overlays the host app's UI completely |
| 255 | +- **WebView Integration**: Handles OTP verification flows with JavaScript enabled for interactivity |
| 256 | +- **Custom Navigation**: Includes a styled top bar with back navigation controls |
| 257 | +- **URL Handling**: Loads the provided OTP URL and manages the verification process |
| 258 | +- **Dialog Management**: Proper dismissal handling that integrates with your app's navigation |
| 259 | + |
| 260 | +**When to use:** When your authentication flow requires OTP verification and you want a seamless, full-screen experience that doesn't disrupt your main app navigation. |
| 261 | + |
| 262 | +```kotlin |
| 263 | +@Composable |
| 264 | +fun OtpScreen() { |
| 265 | + SeamOtpView( |
| 266 | + otpUrl = "https://example.com/otp-verification", |
| 267 | + onNavigateBack = { |
| 268 | + // Handle navigation back |
| 269 | + } |
| 270 | + ) |
| 271 | +} |
| 272 | +``` |
| 273 | + |
| 274 | +#### See Also |
| 275 | + |
| 276 | +* Explore [Seam Mobile SDK](https://docs.seam.co/latest/developer-tools/mobile-sdks/android-sdk) |
0 commit comments