# Android Quickstart

**Example Repository**

- [Android Quickstart Repo](https://github.com/clerk/clerk-android/tree/main/samples/quickstart)

**Before you start**

- [Set up a Clerk application](https://clerk.com/docs/getting-started/quickstart/setup-clerk.md?sdk=android)

1. ## Enable Native API

   In the Clerk Dashboard, navigate to the [**Native applications**](https://dashboard.clerk.com/~/native-applications) page and enable the Native API. This is required to integrate Clerk in your native application or browser extension.

   > Enabling the Native API opens a public request pathway that bypasses browser-based CAPTCHA challenges. Learn more about [how the Native API affects bot protection](https://clerk.com/docs/guides/secure/bot-protection.md?sdk=android#native-api-and-captcha).
2. ## Create a new Android app

   1. If you don't already have an Android app, create a new project in Android Studio using the **Empty Activity** template. This tutorial uses `MyClerkApp` as the app name. If your app has a different name, be sure to update any code examples accordingly to match your app's name.

   2. Open the `app/build.gradle.kts` file and ensure that your project's minimum SDK version is set to 24 or higher, and that your project's Java version is set to 17 or higher, as these are the minimum requirements for the Clerk Android SDK.

   3. In `app/build.gradle.kts`, add the following libraries to your `dependencies` block:

      - The Clerk Android SDK. Check the [GitHub release page](https://github.com/clerk/clerk-android/releases) for the latest version. The SDK is split into two packages:
        - `com.clerk:clerk-android-api` - The core Clerk SDK for authentication and user management.
        - `com.clerk:clerk-android-ui` - The Clerk UI components for authentication and user management.

      - [Android's Lifecycle ViewModel Compose library](https://developer.android.com/reference/kotlin/androidx/lifecycle/viewmodel/compose/package-summary).

        ```gradle
        dependencies {
            ...
            // Only if you're using the Clerk API without the Clerk UI components
            implementation("com.clerk:clerk-android-api:<latest-version>")

            implementation("com.clerk:clerk-android-ui:<latest-version>")
            implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.9.2")
            ...
        }
        ```

   4. Sync your project to apply the changes after adding the dependencies.
3. ## Initialize Clerk

   In `app/src/main/java/com/example/myclerkapp/`, create a Kotlin class named `MyClerkApp`. Add the following code to:

   1. Create a subclass of `Application` named after your application (e.g., `MyClerkApp`).
   2. In this subclass, override the `onCreate()` method and call `Clerk.initialize()` to initialize the Clerk Android SDK with your application context (`this`) and Clerk Publishable Key.

   1) Create a subclass of `Application` named after your application (e.g., `MyClerkApp`).
   2) In this subclass, override the `onCreate()` method and call `Clerk.initialize()` to initialize the Clerk Android SDK with your application context (`this`) and Clerk Publishable Key.

   To find your Publishable Key:

   1. In the Clerk Dashboard, navigate to the [**API keys**](https://dashboard.clerk.com/~/api-keys) page.
   2. Copy your Clerk Publishable Key. It's prefixed with `pk_test_` for development instances and `pk_live_` for production instances.

   filename: app/src/main/java/com/example/myclerkapp/MyClerkApp.kt

   ```kotlin
     package com.example.myclerkapp

     import android.app.Application
     import com.clerk.api.Clerk

     class MyClerkApp: Application() {
         override fun onCreate() {
           super.onCreate()
           Clerk.initialize(
               this,
               publishableKey = "{{pub_key}}"
           )
         }
     }
   ```
4. ## Configure the `AndroidManifest.xml`

   In `app/src/main/AndroidManifest.xml`, add the following configuration:

   1. Inside the root `<manifest>` tag, add the following line to enable internet permission on your Android device.

      ```xml
      <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
          <uses-permission android:name="android.permission.INTERNET"/>
          ...
      </manifest>
      ```

   2. Inside the `<application>` tag, add the following line to use the `MyClerkApp` class as the entry point for app-level configuration.

      ```xml
      <application android:name=".MyClerkApp">
          ...
      </application>
      ```
5. ## Listen for SDK initialization and authentication events

   Let's start building out your home page.

   In your `app/src/main/java/com/example/myclerkapp/` directory, create a Kotlin class named `MainViewModel` with the following code. `MainViewModel` is a `ViewModel` that sets the state as `Loading` when the Clerk SDK is initializing, `SignedIn` when the user is signed in, or `SignedOut` when the user is signed out. The Clerk SDK initialization is non-blocking. Therefore, it's recommended to listen for the SDK to emit a success from Clerk's `isInitialized` global object to know when it's ready to use.

   filename: app/src/main/java/com/example/myclerkapp/MainViewModel.kt

   ```kotlin
   package com.example.myclerkapp

   import android.util.Log
   import androidx.lifecycle.ViewModel
   import androidx.lifecycle.viewModelScope
   import com.clerk.api.Clerk
   import kotlinx.coroutines.flow.MutableStateFlow
   import kotlinx.coroutines.flow.asStateFlow
   import kotlinx.coroutines.flow.combine
   import kotlinx.coroutines.flow.launchIn

   class MainViewModel: ViewModel() {
       private val _uiState = MutableStateFlow<MainUiState>(MainUiState.Loading)
       val uiState = _uiState.asStateFlow()
       init {
           combine(Clerk.isInitialized, Clerk.userFlow) { isInitialized, user ->
               _uiState.value = when {
                 !isInitialized -> MainUiState.Loading
                 user != null -> MainUiState.SignedIn
                 else -> MainUiState.SignedOut
               }
           }
           .launchIn(viewModelScope)
       }
   }
   sealed interface MainUiState {
       data object Loading : MainUiState
       data object SignedIn : MainUiState
       data object SignedOut : MainUiState
   }
   ```
6. ## Conditionally render content

   Now that you're listening for initialization and authentication events, set up your UI to react to them. In your `MainActivity.kt`, add the following code. This will show a loading indicator while the Clerk SDK is initializing, and a signed in or signed out experience based on the user's authentication state.

   filename: app/src/main/java/com/example/myclerkapp/MainActivity.kt

   ```kotlin
   package com.example.myclerkapp

   import android.os.Bundle
   import androidx.activity.ComponentActivity
   import androidx.activity.compose.setContent
   import androidx.activity.viewModels
   import androidx.compose.runtime.getValue
   import androidx.compose.foundation.layout.Box
   import androidx.compose.foundation.layout.fillMaxSize
   import androidx.compose.material3.CircularProgressIndicator
   import androidx.compose.material3.Text
   import androidx.compose.ui.Alignment
   import androidx.compose.ui.Modifier
   import androidx.lifecycle.compose.collectAsStateWithLifecycle

   class MainActivity : ComponentActivity() {

     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContent {

             val viewModel: MainViewModel by viewModels()
             val state by viewModel.uiState.collectAsStateWithLifecycle()

             Box(
                 modifier = Modifier.fillMaxSize(),
                 contentAlignment = Alignment.Center
             ) {
                 when (state) {
                     MainUiState.Loading -> CircularProgressIndicator()
                     MainUiState.SignedOut -> Text("You're signed out")
                     MainUiState.SignedIn -> Text("You're signed in")
                 }
             }
         }
     }
   }
   ```
7. ## Choose an authentication approach

   Choose hosted authentication for the fastest setup, native components for a prebuilt Jetpack Compose experience, or a custom flow for complete control over the UI.

   **Hosted authentication**

   [Hosted authentication](https://clerk.com/docs/android/guides/account-portal/hosted-auth.md) opens Account Portal in a browser authentication session. Account Portal supports the sign-in and sign-up methods enabled for your Clerk application.

   In the Clerk Dashboard, navigate to the [**Native applications**](https://dashboard.clerk.com/~/native-applications) page and add your app's **namespace** and **package name**. Production instances use them to validate the default callback to your app, so add them before you create a production build.

   In `MainActivity.kt`, add the imports shown below. Then, inside `setContent`, replace the `Box` you added in the previous step with the following code. After authentication, the SDK updates `Clerk.userFlow` with the signed-in user.

   filename: app/src/main/java/com/example/myclerkapp/MainActivity.kt

   ```kotlin
   import androidx.compose.material3.Button
   import androidx.compose.runtime.rememberCoroutineScope
   import com.clerk.api.Clerk
   import com.clerk.api.auth.HostedAuthMode
   import com.clerk.api.network.serialization.onFailure
   import kotlinx.coroutines.launch

   val scope = rememberCoroutineScope()

   Box(
       modifier = Modifier.fillMaxSize(),
       contentAlignment = Alignment.Center
   ) {
       when (state) {
           MainUiState.Loading -> CircularProgressIndicator()
           MainUiState.SignedOut -> Button(
               onClick = {
                   scope.launch {
                       Clerk.auth.startHostedAuth(mode = HostedAuthMode.SIGN_UP).onFailure {
                           // The user dismissed the browser, or authentication failed.
                       }
                   }
               },
           ) {
               Text("Sign up")
           }
           MainUiState.SignedIn -> Text("You're signed in")
       }
   }
   ```

   **Native components**

   Clerk's [AuthView](https://clerk.com/docs/android/reference/views/authentication/auth-view.md) handles sign-in and sign-up flows without custom forms.

   In `MainActivity.kt`, import `AuthView` and `UserButton`. Then, inside `setContent`, replace the `Box` you added in the previous step with the following code:

   filename: app/src/main/java/com/example/myclerkapp/MainActivity.kt

   ```kotlin
   import com.clerk.ui.auth.AuthView
   import com.clerk.ui.userbutton.UserButton

   Box(
       modifier = Modifier.fillMaxSize(),
       contentAlignment = Alignment.Center
   ) {
       when (state) {
           MainUiState.Loading -> CircularProgressIndicator()
           MainUiState.SignedOut -> AuthView()
           MainUiState.SignedIn -> UserButton()
       }
   }
   ```

   **Custom flow**

   Custom flows use the Clerk API with your own Jetpack Compose views. The following example builds an email and password sign-up view, then renders it when the user is signed out.

   Create a Kotlin class named `SignUpViewModel` with the following code. It allows users to sign up using their email address and password, and sends an email verification code to confirm their email address.

   filename: app/src/main/java/com/example/myclerkapp/SignUpViewModel.kt

   ```kotlin
   package com.example.myclerkapp

   import android.util.Log
   import androidx.lifecycle.ViewModel
   import androidx.lifecycle.viewModelScope
   import com.clerk.api.Clerk
   import com.clerk.api.network.serialization.errorMessage
   import com.clerk.api.network.serialization.onFailure
   import com.clerk.api.network.serialization.onSuccess
   import com.clerk.api.signup.SignUp
   import com.clerk.api.signup.attemptVerification
   import com.clerk.api.signup.prepareVerification
   import kotlinx.coroutines.flow.MutableStateFlow
   import kotlinx.coroutines.flow.asStateFlow
   import kotlinx.coroutines.launch


   class SignUpViewModel : ViewModel() {
     private val _uiState = MutableStateFlow<SignUpUiState>(SignUpUiState.SignedOut)
     val uiState = _uiState.asStateFlow()

     fun signUp(email: String, password: String) {
         viewModelScope.launch {
             SignUp.create(SignUp.CreateParams.Standard(emailAddress = email, password = password))
                 .onSuccess {
                     if (it.status == SignUp.Status.COMPLETE) {
                         _uiState.value = SignUpUiState.Success
                     } else {
                         _uiState.value = SignUpUiState.NeedsVerification
                         it.prepareVerification(SignUp.PrepareVerificationParams.Strategy.EmailCode())
                     }
                 }
                 .onFailure {
                     // See https://clerk.com/docs/guides/development/custom-flows/error-handling
                     // for more info on error handling
                     Log.e("SignUpViewModel", it.errorMessage, it.throwable)
                 }
         }
     }

     fun verify(code: String) {
         val inProgressSignUp = Clerk.auth.currentSignUp ?: return

         viewModelScope.launch {
             inProgressSignUp
                 .attemptVerification(SignUp.AttemptVerificationParams.EmailCode(code))
                 .onSuccess { _uiState.value = SignUpUiState.Success }
                 .onFailure {
                     // See https://clerk.com/docs/guides/development/custom-flows/error-handling
                     // for more info on error handling
                     Log.e("SignUpViewModel", it.errorMessage, it.throwable)
                 }
         }
     }

     sealed interface SignUpUiState {
         data object SignedOut : SignUpUiState
         data object Success : SignUpUiState
         data object NeedsVerification : SignUpUiState
     }
   }
   ```

   Then, create a `SignUpView` file with the following code to use the `SignUpViewModel`.

   filename: app/src/main/java/com/example/myclerkapp/SignUpView\.kt

   ```kotlin
   package com.example.myclerkapp

   import androidx.compose.foundation.layout.Arrangement
   import androidx.compose.foundation.layout.Column
   import androidx.compose.material3.Button
   import androidx.compose.material3.Text
   import androidx.compose.material3.TextField
   import androidx.compose.runtime.Composable
   import androidx.compose.runtime.collectAsState
   import androidx.compose.runtime.mutableStateOf
   import androidx.compose.runtime.remember
   import androidx.compose.runtime.getValue
   import androidx.compose.runtime.setValue
   import androidx.compose.ui.Alignment
   import androidx.compose.ui.text.input.PasswordVisualTransformation
   import androidx.compose.ui.unit.dp
   import androidx.lifecycle.viewmodel.compose.viewModel


   @Composable
   fun SignUpView(viewModel: SignUpViewModel = viewModel()) {

     val state by viewModel.uiState.collectAsState()

     Column(
         horizontalAlignment = Alignment.CenterHorizontally,
         verticalArrangement = Arrangement.spacedBy(24.dp, Alignment.CenterVertically)
     ) {
         Text("Sign Up")

         if (state is SignUpViewModel.SignUpUiState.NeedsVerification) {
             var code by remember { mutableStateOf("") }

             TextField(value = code, onValueChange = { code = it })

             Button(onClick = { viewModel.verify(code) }) { Text("Verify") }
         } else {
             var email by remember { mutableStateOf("") }
             var password by remember { mutableStateOf("") }

             TextField(value = email, onValueChange = { email = it }, placeholder = { Text("Email") })

             TextField(
                 value = password,
                 placeholder = { Text("Password") },
                 onValueChange = { password = it },
                 visualTransformation = PasswordVisualTransformation(),
             )

             Button(onClick = { viewModel.signUp(email, password) }) { Text("Sign Up") }
         }
     }
   }
   ```

   Then, in your `MainActivity` file, render `SignUpView` when the user isn't signed in.

   filename: app/src/main/java/com/example/myclerkapp/MainActivity.kt

   ```kotlin
   package com.example.myclerkapp

   import android.os.Bundle
   import androidx.activity.ComponentActivity
   import androidx.activity.compose.setContent
   import androidx.activity.viewModels
   import androidx.compose.runtime.getValue
   import androidx.compose.foundation.layout.Box
   import androidx.compose.foundation.layout.fillMaxSize
   import androidx.compose.material3.CircularProgressIndicator
   import androidx.compose.material3.Text
   import androidx.compose.ui.Alignment
   import androidx.compose.ui.Modifier
   import androidx.lifecycle.compose.collectAsStateWithLifecycle

   class MainActivity : ComponentActivity() {

     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContent {

             val viewModel: MainViewModel by viewModels()
             val state by viewModel.uiState.collectAsStateWithLifecycle()

             Box(
                 modifier = Modifier.fillMaxSize(),
                 contentAlignment = Alignment.Center
             ) {
                 when (state) {
                     MainUiState.Loading -> CircularProgressIndicator()
                     MainUiState.SignedOut -> SignUpView()
                     MainUiState.SignedIn -> Text("You're signed in")
                 }
             }
         }
     }
   }
   ```

   See the [Android authentication reference](https://clerk.com/docs/android/reference/native-mobile/auth.md) for the other strategies available through `Clerk.auth`.
8. ## Run your project

   In Android Studio, select `Run ▶︎` to build and launch the app.
9. ## Create your first user

   Once the app launches successfully, select **Sign up** and complete the authentication flow to create your first user.

## Next steps

Explore the most relevant next steps for your SDK using the following guides.

- [Prebuilt views](https://clerk.com/docs/android/reference/views/overview.md): Learn how to quickly add authentication to your app using Clerk's suite of views.
- [Customization with ClerkTheme](https://clerk.com/docs/android/guides/customizing-clerk/clerk-theme.md): Learn how to customize Clerk views using&#x20;
- [Add native Sign in with Google](https://clerk.com/docs/guides/configure/auth-strategies/sign-in-with-google.md?sdk=android): Learn how to add native Sign in with Google to your Clerk apps on Android platforms.
- [Clerk Android SDK reference](https://clerk.com/docs/reference/native-mobile/overview.md?sdk=android): Learn about the Clerk Android SDK and how to integrate it into your app.

---

## Sitemap

[Overview of all docs pages](https://clerk.com/docs/llms.txt)
