> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Add Login to Your Android Application using the Auth0.Android SDK

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

<HowToSchema />

<Accordion title="Use AI to integrate Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  If you use an AI coding assistant like Claude Code, Cursor, or GitHub Copilot, you can add Auth0 authentication automatically in minutes using [agent skills](https://agentskills.io/home).

  **Install:**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-android
  ```

  **Then ask your AI assistant:**

  ```text theme={null}
  Add Auth0 authentication to my Android app
  ```

  Your AI assistant will automatically create your Auth0 application, fetch credentials, add the Auth0 Android SDK dependency, configure manifest placeholders, and implement login/logout flows. [Full agent skills documentation →](/docs/quickstart/agent-skills)
</Accordion>

## Get Started

<Steps>
  <Step title="Create a new Android project" stepNumber={1}>
    Create a new Android project for this quickstart.

    **In Android Studio:**

    1. **File** → **New** → **New Project**
    2. Select **Phone and Tablet** → **Empty Activity** template
    3. Configure your project:
       * **Name**: `Auth0-Android-Sample`
       * **Package name**: `com.auth0.samples.android`
       * **Language**: **Kotlin**
       * **Minimum SDK**: **API 24 (Android 7.0)**
       * **Build configuration language**: **Kotlin DSL**
    4. Click **Finish**

    <Tip>
      This creates a modern Android app with Kotlin and Gradle Kotlin DSL, following current Android development best practices.
    </Tip>
  </Step>

  <Step title="Add Auth0 SDK via Gradle" stepNumber={2}>
    Add the Auth0 Android SDK to your project using Gradle.

    **Update your app-level `build.gradle.kts` file:**

    ```kotlin app/build.gradle.kts lines theme={null}
    dependencies {   
        // Auth0 SDK
        implementation("com.auth0.android:auth0:3.14.0")
    }
    ```

    **Add manifest placeholders in your app-level `build.gradle.kts`:**

    ```kotlin app/build.gradle.kts lines theme={null}
    android {
        defaultConfig {
            // Add these manifest placeholders
            manifestPlaceholders += mapOf(
                "auth0Domain" to "@string/com_auth0_domain", // this will be set in the next step
                "auth0Scheme" to "https"
            )
        }
    }

    ```

    **Add Internet permission to `AndroidManifest.xml`:**

    ```xml app/src/main/AndroidManifest.xml lines theme={null}
    <?xml version="1.0" encoding="utf-8"?>
    <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>
    ```

    <Tip>
      The Auth0 SDK automatically handles dependency resolution and includes secure token storage capabilities.
    </Tip>
  </Step>

  <Step title="Setup your Auth0 App" stepNumber={3}>
    Next up, you need to create a new app on your Auth0 tenant and add the configuration to your Android project.

    First, prepare your `app/src/main/res/values/strings.xml` file with placeholder values:

    ```xml app/src/main/res/values/strings.xml theme={null}
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="com_auth0_domain">{yourDomain}</string>
        <string name="com_auth0_client_id">YOUR_AUTH0_CLIENT_ID</string>
        <string name="com_auth0_scheme">https</string>
    </resources>
    ```

    1. Head to the [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
    2. Click on **Applications** > **Applications** > **Create Application**
    3. In the popup, enter a name for your app, select `Native` as the app type and click **Create**
    4. Switch to the **Settings** tab on the Application Details page
    5. Replace `{yourDomain}` and `YOUR_AUTH0_CLIENT_ID` in the `strings.xml` file with the **Domain** and **Client ID** values from the dashboard

    Finally, on the **Settings** tab of your Application Details page, configure the following URLs:

    **Allowed Callback URLs:**

    ```
    https://{yourDomain}/android/PACKAGE_NAME/callback
    ```

    **Allowed Logout URLs:**

    ```
    https://{yourDomain}/android/PACKAGE_NAME/callback
    ```

    Replace `{yourDomain}` with your actual Auth0 domain (e.g., `dev-abc123.us.auth0.com`).

    <Info>
      **Allowed Callback URLs** are a critical security measure to ensure users are safely returned to your application after authentication. Without a matching URL, the login process will fail, and users will be blocked by an Auth0 error page instead of accessing your app.

      **Allowed Logout URLs** are essential for providing a seamless user experience upon signing out. Without a matching URL, users will not be redirected back to your application after logout and will instead be left on a generic Auth0 page.

      The URL scheme includes your package name (`com.auth0.samples.android`) to ensure the callback is routed to your specific app.
    </Info>

    <Warning>
      **Important**: Ensure the package name in your callback URLs matches your `applicationId` in `build.gradle.kts`. If authentication fails, verify these values are identical.
    </Warning>

    <Tip>
      When using the `https` scheme (as configured above), you must set up Android App Links so that Android routes the callback URL directly to your app instead of opening it in a browser. See the **Configure Android App Links** section under [Troubleshooting & Advanced](#troubleshooting--advanced) below.
    </Tip>
  </Step>

  <Step title="Initialize the Auth0 SDK" stepNumber={4}>
    Create an Auth0 instance in your Activity to communicate with Auth0.

    **In your `MainActivity.kt`:**

    ```kotlin MainActivity.kt lines theme={null}
    import com.auth0.android.Auth0
    import com.auth0.android.authentication.AuthenticationException
    import com.auth0.android.callback.Callback
    import com.auth0.android.provider.WebAuthProvider
    import com.auth0.android.result.Credentials

    class MainActivity : ComponentActivity() {
        private lateinit var auth0: Auth0

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            
            // Initialize Auth0
            auth0 = Auth0.getInstance(
                getString(R.string.com_auth0_client_id),
                getString(R.string.com_auth0_domain)
            )
        }
    }
    ```

    <Tip>
      The Auth0 instance is initialized with your client ID and domain from the `strings.xml` file you configured earlier. This instance will be used for all authentication operations.
    </Tip>
  </Step>

  <Step title="Implement Login and Logout" stepNumber={5}>
    **Implement Login:** Use WebAuthProvider to launch the universal login page.

    Add these methods to your `MainActivity`:

    <Tabs>
      <Tab title="Kotlin Callback">
        ```kotlin MainActivity.kt lines theme={null}
        private fun login() {
            WebAuthProvider.login(auth0)
                .withScheme("https")
                .withScope("openid profile email offline_access")
                .start(this, object : Callback<Credentials, AuthenticationException> {
                    override fun onSuccess(credentials: Credentials) {
                        // Save the credentials
                        // User is authenticated
                    }

                    override fun onFailure(exception: AuthenticationException) {
                        // Handle error cases
                    }
                })
        }
        ```
      </Tab>

      <Tab title="Coroutine">
        ```kotlin MainActivity.kt lines theme={null}
        private fun login() {
            lifecycleScope.launch {
                try {
                    val credentials = WebAuthProvider.login(auth0)
                        .withScheme("https")
                        .withScope("openid profile email offline_access")
                        .await(this@MainActivity)
                    // Save the credentials
                    // User is authenticated
                } catch (exception: AuthenticationException) {
                    // Handle error
                }
            }
        }
        ```
      </Tab>
    </Tabs>

    **Implement Logout:** Use WebAuthProvider to clear the user's session.

    <Tabs>
      <Tab title="Kotlin Callback">
        ```kotlin MainActivity.kt lines theme={null}
        private fun logout() {
            WebAuthProvider.logout(auth0)
                .withScheme("https")
                .start(this, object : Callback<Void?, AuthenticationException> {
                    override fun onSuccess(result: Void?) {
                        // Clear saved credentials
                        // User is logged out
                    }

                    override fun onFailure(exception: AuthenticationException) {
                        // Handle error
                    }
                })
        }
        ```
      </Tab>

      <Tab title="Coroutine">
        ```kotlin MainActivity.kt lines theme={null}
        private fun logout() {
            lifecycleScope.launch {
                try {
                    WebAuthProvider.logout(auth0)
                        .withScheme("https")
                        .await(this@MainActivity)
                    // Clear saved credentials
                    // User is logged out
                } catch (exception: AuthenticationException) {
                    // Handle error
                }
            }
        }
        ```
      </Tab>
    </Tabs>

    <Info>
      The `login()` and `logout()` methods should be called when the user taps the respective buttons in your UI. The code uses `this` (referring to the Activity) as the context parameter, which is required for WebAuthProvider to launch Chrome Custom Tabs and handle the authentication flow.
    </Info>
  </Step>

  <Step title="Run your app" stepNumber={6}>
    Build and run your Android application.

    **In Android Studio:**

    ```shellscript theme={null}
    # Sync project with Gradle files (or use Android Studio's "Sync Now")
    ./gradlew clean build

    # Build and install on connected device or emulator
    ./gradlew installDebug

    # Or run directly from Android Studio
    # Click the "Run" button or press Shift+F10
    ```

    **Expected flow:**

    1. App launches with "Log In" button and shield icon
    2. Tap "Log In" → Chrome Custom Tab opens → Complete login
    3. Returns to app automatically
    4. Success!!

    <Warning>
      Android will show a browser selection dialog if multiple browsers are installed. Chrome Custom Tabs provide the best user experience for Auth0 authentication.
    </Warning>
  </Step>
</Steps>

<Check>
  **Checkpoint**

  You should now have a fully functional Auth0 login experience running on your Android device or emulator. The app uses Chrome Custom Tabs for secure authentication and automatically stores credentials.
</Check>

***

## Troubleshooting & Advanced

<Accordion title="Common Issues & Solutions">
  ### Chrome Custom Tab doesn't redirect back to app

  **Solutions:**

  1. Check **Allowed Callback URLs** in Auth0 Dashboard match your `applicationId` exactly
  2. Verify manifest placeholders in `build.gradle.kts` are correct
  3. Ensure both HTTPS and custom scheme URLs are configured
  4. Clean and rebuild: **Build** → **Clean Project** → **Rebuild Project**

  ### App crashes: 'Auth0 domain not found'

  **Fix:**

  1. Check `com_auth0_domain` and `com_auth0_client_id` values are correct
  2. Ensure no typos in domain format (should not include `https://`)

  ### Build errors with dependencies

  **Fix:**

  1. Update to latest Android Gradle Plugin in `build.gradle` (project level)
  2. Sync project: **File** → **Sync Project with Gradle Files**
  3. Clean build: `./gradlew clean build`

  ### Authentication cancelled by user

  Handle gracefully in your error callback:

  ```kotlin {3,4,5,6} expandable theme={null}
  override fun onFailure(exception: AuthenticationException) {
      when {
          exception.isAuthenticationCanceled -> 
              showMessage("Login was cancelled")
          exception.isBrowserAppNotAvailable -> 
              showMessage("No browser available")
          else -> 
              showMessage("Login failed: ${exception.getDescription()}")
      }
  }
  ```

  ### No compatible browser error

  * Install Chrome or another modern browser on your device/emulator
  * Enable Chrome Custom Tabs for better user experience
  * Test on real device with Chrome installed
</Accordion>

<Accordion title="Configure Android App Links">
  [Android App Links](https://developer.android.com/training/app-links) allow your app to designate itself as the default handler for Auth0 callback URLs, providing a more secure and seamless authentication experience. Without App Links, Android may show a disambiguation dialog asking the user to choose between your app and a browser.

  <Note>
    App Links use verified `https` scheme callbacks. This is more secure than custom URL schemes, which can be subject to [client impersonation attacks](https://datatracker.ietf.org/doc/html/rfc8252#section-8.6).
  </Note>

  ### Get your signing certificate fingerprint

  You need the SHA256 fingerprint of your app's signing certificate. Run the following command in your terminal:

  ```shellscript theme={null}
  # For debug builds
  keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

  # For release builds
  keytool -list -v -keystore my-release-key.keystore
  ```

  Copy the **SHA256** fingerprint value from the output.

  ### Configure in the Auth0 Dashboard

  1. Go to [Auth0 Dashboard > Applications > Applications](https://manage.auth0.com/#/applications), and select your application
  2. Scroll to the bottom of the **Settings** page and select **Show Advanced Settings**
  3. Select the **Device Settings** tab
  4. Under **Android**, provide:
     * **App Package Name**: Your `applicationId` (e.g., `com.auth0.samples.android`)
     * **SHA256 Cert Fingerprints**: The fingerprint you copied above
  5. Click **Save Changes**

  ### Verify the configuration

  Auth0 automatically generates the `assetlinks.json` file used by Android to verify your app. Test it by navigating to:

  ```
  https://{yourDomain}/.well-known/assetlinks.json
  ```

  You should see a JSON response containing your package name and certificate fingerprint:

  ```json theme={null}
  [{
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "[YOUR_PACKAGE_NAME]",
      "sha256_cert_fingerprints": ["YOUR_SHA256_FINGERPRINT"]
    }
  }]
  ```

  <Info>
    The quickstart already uses `https` as the scheme in the manifest placeholders and `WebAuthProvider` calls, which is required for App Links. No code changes are needed if you followed the steps above.
  </Info>

  To learn more, see the [Enable Android App Links Support](/docs/get-started/applications/enable-android-app-links-support) documentation and Android's [Verify App Links](https://developer.android.com/training/app-links/verify-site-associations) guide.
</Accordion>

<Accordion title="Use a custom URL scheme">
  If you cannot use Android App Links (for example, when targeting Android API versions below 23), you can configure a custom URL scheme instead.

  <Warning>
    Custom URL schemes are less secure than App Links because they can be subject to [client impersonation attacks](https://datatracker.ietf.org/doc/html/rfc8252#section-8.6). Use App Links whenever possible.
  </Warning>

  1. Update the `auth0Scheme` manifest placeholder in your `app/build.gradle.kts`:

  ```kotlin app/build.gradle.kts lines theme={null}
  android {
      defaultConfig {
          manifestPlaceholders += mapOf(
              "auth0Domain" to "@string/com_auth0_domain",
              "auth0Scheme" to "myapp" // Use a unique custom scheme
          )
      }
  }
  ```

  2. Update the **Allowed Callback URLs** and **Allowed Logout URLs** in your [Auth0 Dashboard](https://manage.auth0.com/#/applications) application settings to use the custom scheme:

  ```
  myapp://{yourDomain}/android/PACKAGE_NAME/callback
  ```

  3. Pass the custom scheme when calling `WebAuthProvider`:

  ```kotlin MainActivity.kt lines theme={null}
  WebAuthProvider.login(auth0)
      .withScheme("myapp")
      .withScope("openid profile email offline_access")
      .start(this, callback)
  ```

  <Note>
    Custom schemes [can only contain lowercase letters](https://developer.android.com/guide/topics/manifest/data-element).
  </Note>
</Accordion>

<Accordion title="Production Deployment">
  ### App Store Preparation

  * Configure Android App Links for seamless authentication
  * Test on multiple Android versions and screen sizes
  * Implement proper error handling for network failures
  * Add ProGuard rules for Auth0 SDK if using code obfuscation
  * Follow Google Play Store policies for authentication flows

  ### Security Considerations

  * Use `SecureCredentialsManager` for production credential storage
  * Implement certificate pinning for additional API security
  * Consider Android Keystore for enhanced credential protection
  * Enable biometric authentication for sensitive operations
</Accordion>

<Accordion title="Advanced Android Integration">
  ### Enhanced Credential Security

  Implement biometric authentication for credential access:

  ```kotlin AuthenticationManager.kt expandable lines theme={null}
  class AuthenticationManager(private val context: Context) {
      
      private val credentialsManager: SecureCredentialsManager
      
      init {
          val authentication = AuthenticationAPIClient(auth0)
          val storage = SharedPreferencesStorage(context)
          credentialsManager = SecureCredentialsManager(context, authentication, storage)
          
          // Enable biometric authentication
          credentialsManager.requireAuthentication(
              context as FragmentActivity,
              REQUEST_CODE_BIOMETRIC,
              "Biometric Authentication",
              "Please authenticate to access your account"
          )
      }
      
      companion object {
          private const val REQUEST_CODE_BIOMETRIC = 321
      }
  }
  ```

  ### Custom Scopes and Audience

  Request specific scopes and audience for your API:

  ```kotlin AuthenticationManager.kt expandable lines theme={null}
  fun login() {
      WebAuthProvider.login(auth0)
          .withScheme("https")
          .withScope("openid profile email offline_access read:posts")
          .withAudience("https://myapi.example.com")
          .withParameter("prompt", "login")
          .start(context as MainActivity, loginCallback)
  }
  ```

  ### Network Configuration

  Handle network security and certificate pinning:

  ```xml app/src/main/res/xml/network_security_config.xml expandable lines theme={null}
  <?xml version="1.0" encoding="utf-8"?>
  <network-security-config>
      <domain-config>
          <domain includeSubdomains="true">your-auth0-domain.auth0.com</domain>
          <pin-set>
              <pin digest="SHA-256">AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</pin>
          </pin-set>
      </domain-config>
  </network-security-config>
  ```

  Add to `AndroidManifest.xml`:

  ```xml theme={null}
  <application
      android:networkSecurityConfig="@xml/network_security_config"
      ... />
  ```
</Accordion>
