---
title: "sdk/android"
description: "Chrome Custom Tabs、PKCE S256 認可コードフロー、Keystore バックアップの EncryptedSharedPreferences トークンストレージを使用した Android 向け Kotlin SDK。"
locale: "ja"
---

> Documentation Index
> Fetch the locale documentation index at: https://xid.dev/ja/llms.txt
> Use this file to discover all available pages before exploring further.

# sdk/android

## 状態

パッケージステータス：**実装済み・ローカル検証済み**。JVM 単体テスト（24 ケースパス）は PKCE 生成、OAuth state、メモリ内ストレージをカバーします。EncryptedSharedPreferences（Keystore AES-256-GCM）、Chrome Custom Tabs、App Links の動作は実際の Android デバイスまたはエミュレーターが必要です。実際の IdP ラウンドトリップは手動検証待ちです。このページは実装済みの動作を記録したものであり、本番対応の主張ではありません。

## 動作要件

- Android API 26+（Android 8.0）
- Kotlin 1.9+ および AndroidX

## インストール

アプリモジュールの build.gradle.kts に依存関係を追加します：

```kotlin
dependencies {
implementation("dev.xid:xid-android:0.1.0-alpha")
}

// Local development: add to settings.gradle.kts
includeBuild("../sdk/android")
```

## マニフェストセットアップ

インテントフィルターでコールバック Activity を登録します。カスタムスキームより App Links（autoVerify 付き HTTPS スキーム）が推奨されます：

```xml
<!-- AndroidManifest.xml -->
<activity android:name=".AuthCallbackActivity" android:exported="true">
<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https"
          android:host="yourapp.example.com"
          android:pathPrefix="/auth/callback" />
</intent-filter>
</activity>
```

## クイックスタート

```kotlin
import dev.xid.sdk.Xid
import dev.xid.sdk.model.XidConfig

// 1. Initialize in Application.onCreate
Xid.configure(
context = this,
config = XidConfig(
    issuer = "https://xid.dev",
    clientId = "your_client_id",
    redirectUri = "https://yourapp.example.com/auth/callback",
    scopes = listOf("openid", "profile", "email", "offline_access"),
)
)

// 2. Sign in (opens Chrome Custom Tabs)
lifecycleScope.launch { Xid.signIn(requireContext()) }

// 3. Handle redirect in AuthCallbackActivity
val session = Xid.handleRedirect(intent.data.toString())

// 4. Get current session (auto-refreshes near expiry)
val session = Xid.getSession()

// 5. Get access token
val token = Xid.getAccessToken()

// 6. Sign out
Xid.signOut(context = this, openEndSession = true)
```

## コア API

| 方式 | 署名 |
| --- | --- |
| `configure` | `fun configure(context: Context, config: XidConfig)` |
| `signIn` | `suspend fun signIn(context: Context, options: SignInOptions? = null)` |
| `handleRedirect` | `suspend fun handleRedirect(url: String): XidSession` |
| `getSession` | `suspend fun getSession(): XidSession?` |
| `getAccessToken` | `suspend fun getAccessToken(options: GetAccessTokenOptions? = null): String` |
| `signOut` | `suspend fun signOut(context: Context? = null, openEndSession: Boolean = false)` |
| `setTokenStorage` | `fun setTokenStorage(adapter: TokenStorageAdapter)` |

## エラー型

すべての SDK エラーは sealed クラス XidException のサブタイプです：

| サブクラス | トリガー |
| --- | --- |
| `NotConfigured` | configure() が呼び出されていません |
| `UserCancelled` | ユーザーが完了せずに Custom Tabs を閉じました |
| `StateMismatch` | OAuth state 不一致 — CSRF の可能性があります |
| `TokenExchangeFailed` | トークンエンドポイントがエラーを返しました |
| `TokenRefreshFailed` | リフレッシュトークンの有効期限切れまたは取り消し |
| `NoSession` | サインアウト中に呼び出されたセッションメソッド |

## セキュリティ

- パブリッククライアント — クライアントシークレットは保存・送信されません。
- PKCE S256 のみ。サーバーは plain チャレンジメソッドを拒否します。
- Android Keystore（AES-256-GCM）を使用した EncryptedSharedPreferences が保存時のトークンストアを保護します。
- リクエストごとに生成されるランダムな OAuth state。CSRF を防ぐためリダイレクト時に検証されます。

## 既知の制限事項

- JWKS による ID token 検証は実装済みでローカル単体テスト済みです。L4 には Android 実機または emulator と IdP の検証が必要です。
- ユーザーが認可を完了せずに Custom Tabs を閉じたことを検出するメカニズムがありません。
- シングルアカウント専用 — ストレージレイヤーは固定キーを使用します。

Source: https://xid.dev/ja/sdks/android/index.mdx
