# ANDROID - Adapty Documentation (Full Content) This file contains the complete content of all documentation pages for this platform. Locale: ja Generated on: 2026-06-24T14:36:28.434Z Total files: 40 --- # File: sdk-installation-android --- --- title: "Android SDKのインストールと設定" description: "サブスクリプションアプリ向けに、Android に Adapty SDK をインストールするステップバイステップのガイドです。" --- Adapty SDK には、モバイルアプリにシームレスに統合するための2つの主要モジュールが含まれています。 - **Core Adapty**: Adapty をアプリで正しく動作させるために必須の SDK です。 - **AdaptyUI**: クロスプラットフォームのペイウォールを簡単に作成できるノーコードツール、[Adapty ペイウォールビルダー](adapty-paywall-builder)を使用する場合に必要なモジュールです。AdaptyUI はコアモジュールと同時に自動的に有効化されます。 :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を確認したい方は、ペイウォールの表示・購入処理・その他の基本機能を含むフルセットアップを示す[サンプルアプリ](https://github.com/adaptyteam/AdaptySDK-Android/tree/master/app)をご覧ください。 ::: ## 要件 \{#requirements\} 最低 SDK 要件: `minSdkVersion 21` :::info Adapty は Google Play Billing Library 8.x まで対応しています。デフォルトでは Google Play Billing Library v7.0.0 で動作しますが、より新しいバージョンを使用したい場合は、手動で[依存関係を追加](https://developer.android.com/google/play/billing/integrate#dependency)できます。 ::: --- no_index: true --- import Callout from '../../../components/Callout.astro'; SDKのインストールは、Adaptyセットアップのステップ5です。アプリ内で課金が機能するようにするには、アプリをストアに接続し、Adapty ダッシュボードでプロダクト、ペイウォール、プレースメントを作成する必要があります。[クイックスタートガイド](quickstart)では、必要なすべての手順を説明しています。 ## Adapty SDK をインストールする \{#install-adapty-sdk\} 依存関係の設定方法を選択してください: - Standard Gradle: **モジュールレベル**の `build.gradle` に依存関係を追加する - プロジェクトで `.gradle.kts` ファイルを使用している場合は、モジュールレベルの `build.gradle.kts` に依存関係を追加する - バージョンカタログを使用している場合は、`libs.versions.toml` ファイルに依存関係を追加し、`build.gradle.kts` で参照する [![Release](https://img.shields.io/github/v/release/adaptyteam/AdaptySDK-Android.svg?style=flat&logo=android)](https://github.com/adaptyteam/AdaptySDK-Android/releases) ```groovy showLineNumbers dependencies { ... implementation platform('io.adapty:adapty-bom:') implementation 'io.adapty:android-sdk' // Only add this line if you plan to use Paywall Builder implementation 'io.adapty:android-ui' } ``` ```kotlin showLineNumbers dependencies { ... implementation(platform("io.adapty:adapty-bom:")) implementation("io.adapty:android-sdk") // Only add this line if you plan to use Paywall Builder: implementation("io.adapty:android-ui") } ``` ```toml showLineNumbers //libs.versions.toml [versions] .. adaptyBom = "" [libraries] .. adapty-bom = { module = "io.adapty:adapty-bom", version.ref = "adaptyBom" } adapty = { module = "io.adapty:android-sdk" } // Only add this line if you plan to use Paywall Builder: adapty-ui = { module = "io.adapty:android-ui" } //module-level build.gradle.kts dependencies { ... implementation(platform(libs.adapty.bom)) implementation(libs.adapty) // Only add this line if you plan to use Paywall Builder: implementation(libs.adapty.ui) } ``` 依存関係が解決されない場合は、Gradle スクリプトに `mavenCentral()` が含まれているか確認してください。
追加方法の手順 プロジェクトの `settings.gradle` に `dependencyResolutionManagement` がない場合は、トップレベルの `build.gradle` のリポジトリの末尾に以下を追加してください: ```groovy showLineNumbers title="top-level build.gradle" allprojects { repositories { ... mavenCentral() } } ``` それ以外の場合は、`settings.gradle` の `dependencyResolutionManagement` セクション内の `repositories` に以下を追加してください: ```groovy showLineNumbers title="settings.gradle" dependencyResolutionManagement { ... repositories { ... mavenCentral() } } ```
## Adapty SDK の Adapty モジュールを有効化する \{#activate-adapty-module-of-adapty-sdk\} ### 基本セットアップ \{#basic-setup\} アプリのコードで Adapty SDK を有効化します。 :::note Adapty SDK はアプリ内で一度だけ有効化すれば十分です。 ::: **Public SDK Key** を取得するには: 1. Adapty ダッシュボードを開き、[**App settings → General**](https://app.adapty.io/settings/general) に移動します。 2. **Api keys** セクションから **Public SDK Key**(Secret Key ではない方)をコピーします。 3. コード内の `"YOUR_PUBLIC_SDK_KEY"` を置き換えます。 :::important - Adapty の初期化には必ず **Public SDK key** を使用してください。**Secret key** は[サーバーサイド API](getting-started-with-server-side-api) 専用です。 - **SDK keys** はアプリごとに固有です。複数のアプリがある場合は、正しいキーを選択してください。 ::: ```kotlin showLineNumbers // In your Application class class MyApplication : Application() { override fun onCreate() { super.onCreate() Adapty.activate( applicationContext, AdaptyConfig.Builder("PUBLIC_SDK_KEY") .build() ) } } ``` ```java showLineNumbers // In your Application class public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); Adapty.activate( getApplicationContext(), new AdaptyConfig.Builder("PUBLIC_SDK_KEY") .build() ); } } ``` :::important `Adapty.activate` が完了するまで待ってから、他の Adapty SDK メソッドを呼び出してください。完全な呼び出し順序については、[Android SDK の呼び出し順序](android-sdk-call-order)を参照してください。 ::: 次に、アプリにペイウォールを設定します: - [Adapty ペイウォールビルダー](adapty-paywall-builder)を使用する場合は、[ペイウォールビルダーのクイックスタート](android-quickstart-paywalls)に従ってください。 - 独自のペイウォール UI を構築する場合は、[カスタムペイウォールのクイックスタート](android-quickstart-manual)を参照してください。 ## Adapty SDK の AdaptyUI モジュールを有効化する \{#activate-adaptyui-module-of-adapty-sdk\} [ペイウォールビルダー](adapty-paywall-builder)を使用する予定の場合、AdaptyUI モジュールが必要です。コアモジュールを有効化すると自動的に有効化されるため、追加の操作は不要です。 ## Proguard を設定する \{#configure-proguard\} 本番環境でアプリを公開する前に、Proguard の設定に `-keep class com.adapty.** { *; }` を追加してください。 ## オプションの設定 \{#optional-setup\} ### ログ \{#logging\} #### ログシステムを設定する \{#set-up-the-logging-system\} Adapty は、何が起きているかを把握するためにエラーやその他の重要な情報をログに記録します。利用可能なレベルは以下のとおりです: | レベル | 説明 | | :----------------------- | :------------------------------------------------------------------------------------------------------------------------ | | `AdaptyLogLevel.NONE` | 何もログに記録されません。デフォルト値 | | `AdaptyLogLevel.ERROR` | エラーのみログに記録されます | | `AdaptyLogLevel.WARN` | エラーと、重大なエラーではないが注意が必要な SDK からのメッセージがログに記録されます。 | | `AdaptyLogLevel.INFO` | エラー、警告、およびさまざまな情報メッセージがログに記録されます。 | | `AdaptyLogLevel.VERBOSE` | 関数呼び出しや API クエリなど、デバッグ時に役立つ追加情報がすべてログに記録されます。 | Adapty を設定する前に、アプリでログレベルを設定できます。 ```kotlin showLineNumbers Adapty.logLevel = AdaptyLogLevel.VERBOSE //recommended for development and the first production release ``` ```java showLineNumbers Adapty.setLogLevel(AdaptyLogLevel.VERBOSE); //recommended for development and the first production release ``` #### ログシステムのメッセージをリダイレクトする \{#redirect-the-logging-system-messages\} 何らかの理由で Adapty からのメッセージを独自のシステムに送信したり、ファイルに保存したりする必要がある場合は、デフォルトの動作をオーバーライドできます: ```kotlin showLineNumbers Adapty.setLogHandler { level, message -> //handle the log } ``` ```java showLineNumbers Adapty.setLogHandler((level, message) -> { //handle the log }); ``` ### データポリシー \{#data-policies\} Adapty は明示的に送信しない限りユーザーの個人データを保存しませんが、ストアや国のガイドラインに準拠するために追加のデータセキュリティポリシーを実装することができます。 #### IP アドレスの収集と共有を無効にする \{#disable-ip-address-collection-and-sharing\} Adapty モジュールを有効化する際に、`ipAddressCollectionDisabled` を `true` に設定すると、ユーザーの IP アドレスの収集と共有を無効にできます。デフォルト値は `false` です。 このパラメータは、ユーザーのプライバシーを強化したり、地域のデータ保護規制(GDPR や CCPA など)に準拠したり、IP ベースの機能がアプリに不要な場合に不必要なデータ収集を削減するために使用します。 ```kotlin showLineNumbers AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withIpAddressCollectionDisabled(true) .build() ``` ```java showLineNumbers new AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withIpAddressCollectionDisabled(true) .build(); ``` #### 広告 ID(Ad ID)の収集と共有を無効にする \{#disable-advertising-id-ad-id-collection-and-sharing\} Adapty モジュールを有効化する際に、`adIdCollectionDisabled` を `true` に設定すると、ユーザーの[広告 ID](https://support.google.com/googleplay/android-developer/answer/6048248) の収集を無効にできます。デフォルト値は `false` です。 このパラメータは、Play Store のポリシーに準拠したり、広告 ID の権限プロンプトの表示を避けたり、Ad ID に基づく広告アトリビューションやアナリティクスがアプリに不要な場合に使用します。 ```kotlin showLineNumbers AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withAdIdCollectionDisabled(true) .build() ``` ```java showLineNumbers new AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withAdIdCollectionDisabled(true) .build(); ``` #### AdaptyUI のメディアキャッシュ設定をセットアップする \{#set-up-media-cache-configuration-for-adaptyui\} デフォルトでは、AdaptyUI はパフォーマンスの向上とネットワーク使用量の削減のために、画像や動画などのメディアをキャッシュします。カスタム設定を指定することでキャッシュの設定をカスタマイズできます。 `AdaptyUI.configureMediaCache` を使用して、デフォルトのキャッシュサイズと有効期間をオーバーライドします。これはオプションです。このメソッドを呼び出さない場合、デフォルト値(ディスクサイズ 100MB、有効期間 7 日)が使用されます。 ```kotlin showLineNumbers val cacheConfig = MediaCacheConfiguration.Builder() .overrideDiskStorageSizeLimit(200L * 1024 * 1024) // 200 MB .overrideDiskCacheValidityTime(3.days) .build() AdaptyUI.configureMediaCache(cacheConfig) ``` ```java showLineNumbers MediaCacheConfiguration cacheConfig = new MediaCacheConfiguration.Builder() .overrideDiskStorageSizeLimit(200L * 1024 * 1024) // 200 MB .overrideDiskCacheValidityTime(TimeInterval.days(3)) .build(); AdaptyUI.configureMediaCache(cacheConfig); ``` **パラメータ:** | パラメータ | 必須/任意 | 説明 | |-------------------------|----------|-----------------------------------------------------------------------------| | diskStorageSizeLimit | 任意 | ディスク上の合計キャッシュサイズ(バイト単位)。デフォルトは 100 MB。 | | diskCacheValidityTime | 任意 | キャッシュされたファイルが有効とみなされる期間。デフォルトは 7 日。 | :::tip `AdaptyUI.clearMediaCache(strategy)` を使用して、実行時にメディアキャッシュをクリアできます。`strategy` には `CLEAR_ALL` または `CLEAR_EXPIRED_ONLY` を指定します。 ::: ### 難読化アカウント ID を設定する \{#set-obfuscated-account-ids\} Google Play では、ユーザーのプライバシーとセキュリティを強化するために、特定のユースケースで難読化アカウント ID が必要です。これらの ID により、Google Play はユーザー情報を匿名に保ちながら購入を識別できます。これは特に不正防止とアナリティクスにおいて重要です。 アプリが機密性の高いユーザーデータを扱う場合や、特定のプライバシー規制に準拠する必要がある場合は、これらの ID を設定する必要があります。難読化された ID により、Google Play は実際のユーザー識別子を公開せずに購入を追跡できます。 ```kotlin showLineNumbers AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withObfuscatedAccountId("YOUR_OBFUSCATED_ACCOUNT_ID") .build() ``` ```java showLineNumbers new AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withObfuscatedAccountId("YOUR_OBFUSCATED_ACCOUNT_ID") .build(); ``` ### カスタムプロセスで Adapty を実行する \{#run-adapty-in-a-custom-process\} デフォルトでは、Adapty はアプリのメインプロセスでのみ実行できます。 アプリが複数のプロセスを使用する場合は、Adapty の初期化を一度だけ行ってください。そうしないと予期しない動作が発生する可能性があります。 別のプロセスで Adapty を実行する必要がある場合は、設定でプロセスを指定してください: ```kotlin showLineNumbers AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withProcessName(":custom") .build() ``` ```java showLineNumbers new AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withProcessName(":custom") .build(); ``` この値を設定せずに別のプロセスで Adapty を有効化しようとすると、SDK は警告をログに記録し、有効化をスキップします。 ### ローカルアクセスレベルを有効にする \{#enable-local-access-levels\} デフォルトでは、Android では[ローカルアクセスレベル](local-access-levels)が無効になっています。有効にするには、`withLocalAccessLevelAllowed` を `true` に設定してください: ```kotlin showLineNumbers AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withLocalAccessLevelAllowed(true) .build() ``` ```java showLineNumbers new AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withLocalAccessLevelAllowed(true) .build(); ``` ## トラブルシューティング \{#troubleshooting\} #### Android バックアップルール(自動バックアップの設定) \{#android-backup-rules-auto-backup-configuration\} 一部の SDK(Adapty を含む)は独自の Android 自動バックアップ設定を同梱しています。バックアップルールを定義する複数の SDK を使用している場合、Android マニフェストマージャーが `android:fullBackupContent`、`android:dataExtractionRules`、または `android:allowBackup` に関するエラーで失敗することがあります。 エラーの典型的な症状: `Manifest merger failed: Attribute application@dataExtractionRules value=(@xml/sample_data_extraction_rules) is also present at [com.other.sdk:library:1.0.0] value=(@xml/other_sdk_data_extraction_rules)` これを解決するには: - マニフェストマージャーにバックアップ関連の属性についてアプリの値を使用するよう指定する。 - Adapty と他の SDK のバックアップルールを単一の XML ファイル(Android 12 以上の場合はファイルのペア)にまとめる。 #### 1. マニフェストに `tools` 名前空間を追加する \{#1-add-the-tools-namespace-to-your-manifest\} まだ存在しない場合は、ルートの `` タグに `tools` 名前空間を追加してください: ```xml ... ``` #### 2. `` でバックアップ属性をオーバーライドする \{#2-override-backup-attributes-in-application\} アプリの `AndroidManifest.xml` で、`` タグを更新して、アプリが最終的な値を提供し、マニフェストマージャーにライブラリの値を置き換えるよう指示します: ```xml ... ``` いずれかの SDK でも `android:allowBackup` が設定されている場合は、`tools:replace` に含めてください: ```xml tools:replace="android:allowBackup,android:fullBackupContent,android:dataExtractionRules" ``` #### 3. マージされたバックアップルールファイルを作成する \{#3-create-merged-backup-rules-files\} `app/src/main/res/xml/` 以下に、Adapty のルールと他の SDK のルールを組み合わせた XML ファイルを作成します。Android は OS バージョンによって異なるバックアップルール形式を使用するため、両方のファイルを作成することでアプリがサポートするすべての Android バージョンとの互換性が確保されます。 :::note 以下の例では、サードパーティ SDK のサンプルとして AppsFlyer を使用しています。アプリで使用している他の SDK のルールに置き換えるか追加してください。 ::: **Android 12 以上向け**(新しいデータ抽出ルール形式を使用): ```xml title="sample_data_extraction_rules.xml" ``` **Android 11 以下向け**(従来のフルバックアップコンテンツ形式を使用): ```xml title="sample_backup_rules.xml" ``` この設定により: - Adapty のバックアップ除外設定(`AdaptySDKPrefs.xml`)が維持されます。 - 他の SDK の除外設定(例: `appsflyer-data`)も適用されます。 - マニフェストマージャーはアプリの設定を使用し、競合するバックアップ属性での失敗がなくなります。 #### 別のアプリから戻った後に購入が失敗する \{#purchases-fail-after-returning-from-another-app\} 購入フローを開始する Activity が非デフォルトの `launchMode` を使用している場合、ユーザーが Google Play、銀行アプリ、またはブラウザから戻ってきたときに Android が誤って Activity を再作成または再利用することがあります。これにより、購入結果が失われたり、キャンセルとして処理されたりする可能性があります。 購入が正しく機能するよう、購入フローを開始する Activity には `standard` または `singleTop` の起動モードのみを使用し、他のモードは避けてください。 `AndroidManifest.xml` で、購入フローを開始する Activity が `standard` または `singleTop` に設定されていることを確認してください: ```xml ``` --- # File: android-quickstart-paywalls --- --- title: "Android SDKのペイウォールを使ってアプリ内課金を有効にする" description: "アプリ内サブスクリプション管理のためのAdaptyセットアップクイックスタートガイド。" --- アプリ内課金を有効にするには、以下の3つの重要な概念を理解する必要があります。 - [**プロダクト**](product) – ユーザーが購入できるもの(サブスクリプション、消耗型アイテム、永続アクセスなど) - [**ペイウォール**](paywalls) – どのプロダクトを提供するかを定義する設定です。Adaptyでは、プロダクトを取得する唯一の方法がペイウォールです。この設計により、アプリのコードを変更せずに、提供内容・価格・プロダクトの組み合わせを変更できます。 - [**プレースメント**](placements) – アプリ内でペイウォールを表示する場所とタイミング(`main`、`onboarding`、`settings` など)。ダッシュボードでプレースメントにペイウォールを設定し、コードでプレースメントIDを指定して取得します。A/B テストの実施や、ユーザーごとに異なるペイウォールを表示するのも簡単です。 Adaptyでは、アプリ内課金を有効にする方法が3つあります。アプリの要件に合わせて選択してください。 | 実装方法 | 複雑さ | 適しているケース | |------------------------|------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Adapty ペイウォールビルダー | ✅ 簡単 | [ノーコードビルダーで完全な購入対応ペイウォールを作成する](quickstart-paywalls)場合。Adaptyが自動的にレンダリングし、複雑な購入フロー・レシート検証・サブスクリプション管理をすべてバックグラウンドで処理します。 | | 手動作成のペイウォール | 🟡 中程度 | アプリのコードでペイウォールUIを実装しつつ、プロダクト提供の柔軟性を維持するためにAdaptyからペイウォールオブジェクトを取得する場合。[ガイド](android-quickstart-manual)を参照してください。 | | オブザーバーモード | 🔴 難しい | 独自の購入処理インフラがすでにあり、そのまま利用したい場合。ただし、オブザーバーモードにはAdaptyでの制限があります。[記事](observer-vs-full-mode)を参照してください。 | :::important **以下の手順は、Adaptyペイウォールビルダーで作成したペイウォールを実装する方法を説明しています。** ペイウォールビルダーを使用しない場合は、[手動作成のペイウォールで購入を処理するガイド](android-making-purchases)を参照してください。 ::: Adaptyペイウォールビルダーで作成したペイウォールを表示するには、アプリのコードで以下の手順を実行するだけです。 1. **ペイウォールを取得する**: AdaptyからペイウォールOBJECTを取得します。 2. **ペイウォールを表示し、Adaptyが購入を処理する**: 取得したペイウォールコンテナをアプリに表示します。 3. **ボタンアクションを処理する**: ペイウォール上のユーザー操作とアプリの反応を関連付けます。例えば、ユーザーがボタンをクリックしたときにリンクを開いたり、ペイウォールを閉じたりします。 ## 始める前に \{#before-you-start\} 始める前に、以下の手順を完了してください。 1. Adapty ダッシュボードで[アプリをGoogle Playに接続する](initial-android)。 2. Adaptyで[プロダクトを作成する](create-product)。 3. [ペイウォールを作成してプロダクトを追加する](create-paywall)。 4. [プレースメントを作成してペイウォールを追加する](create-placement)。 5. アプリのコードに[Adapty SDKをインストールして有効化する](sdk-installation-android)。 :::tip これらの手順を最短で完了するには、[クイックスタートガイド](quickstart)に従うか、[Developer CLI](developer-cli-quickstart)を使ってペイウォールとプレースメントを作成してください。 ::: ## 1. ペイウォールを取得する \{#1-get-the-paywall\} ペイウォールはダッシュボードで設定したプレースメントに関連付けられています。プレースメントを使うと、異なるオーディエンスに異なるペイウォールを表示したり、[A/B テスト](ab-tests)を実施したりできます。 Adaptyペイウォールビルダーで作成したペイウォールを取得するには、以下の手順が必要です。 1. `getPaywall`メソッドを使って[プレースメント](placements)IDで`paywall`オブジェクトを取得し、それがビルダーで作成されたペイウォールかどうかを確認します。 2. `getViewConfiguration`メソッドを使ってペイウォールのビュー設定を取得します。ビュー設定には、ペイウォールを表示するためのUI要素とスタイリング情報が含まれています。 :::important ビュー設定を取得するには、ペイウォールビルダーの **Show on device** トグルをオンにする必要があります。オフのままでは空のビュー設定が返され、ペイウォールが表示されません。 ::: ```kotlin showLineNumbers Adapty.getPaywall("YOUR_PLACEMENT_ID") { result -> if (result is AdaptyResult.Success) { val paywall = result.value if (!paywall.hasViewConfiguration) { return@getPaywall } AdaptyUI.getViewConfiguration(paywall) { configResult -> if (configResult is AdaptyResult.Success) { val viewConfiguration = configResult.value } } } } ``` ```java showLineNumbers Adapty.getPaywall("YOUR_PLACEMENT_ID", result -> { if (result instanceof AdaptyResult.Success) { AdaptyPaywall paywall = ((AdaptyResult.Success) result).getValue(); if (!paywall.hasViewConfiguration()) { return; } AdaptyUI.getViewConfiguration(paywall, configResult -> { if (configResult instanceof AdaptyResult.Success) { AdaptyUI.LocalizedViewConfiguration viewConfiguration = ((AdaptyResult.Success) configResult).getValue(); // use loaded configuration } }); } }); ``` ## 2. ペイウォールを表示する \{#2-display-the-paywall\} ペイウォールの設定が取得できたら、数行のコードを追加するだけでペイウォールを表示できます。 デバイスの画面にビジュアルペイウォールを表示するには、まず設定を行う必要があります。`AdaptyUI.getPaywallView()`メソッドを呼び出すか、`AdaptyPaywallView`を直接作成してください。 ```kotlin showLineNumbers val paywallView = AdaptyUI.getPaywallView( activity, viewConfiguration, null, // products = null means auto-fetch eventListener, ) ``` ```kotlin showLineNumbers val paywallView = AdaptyPaywallView(activity) // or retrieve it from xml ... with(paywallView) { showPaywall( viewConfiguration, null, // products = null means auto-fetch eventListener, ) } ``` ```java showLineNumbers AdaptyPaywallView paywallView = AdaptyUI.getPaywallView( activity, viewConfiguration, null, // products = null means auto-fetch eventListener, ); ``` ```java showLineNumbers AdaptyPaywallView paywallView = new AdaptyPaywallView(activity); //add to the view hierarchy if needed, or you receive it from xml ... paywallView.showPaywall(viewConfiguration, products, eventListener); ``` ```xml showLineNumbers ``` ビューが正常に作成されたら、ビュー階層に追加してデバイスの画面に表示できます。 :::tip ペイウォールの表示方法の詳細については、[ガイド](android-present-paywalls)を参照してください。 ::: ## 3. ボタンアクションを処理する \{#3-handle-button-actions\} ユーザーがペイウォールのボタンをクリックすると、Android SDKは購入・復元・ペイウォールのクローズ・リンクのオープンを自動的に処理します。 ただし、カスタムまたは事前定義されたIDを持つボタンは、コード内でアクションを処理する必要があります。または、デフォルトの動作をオーバーライドしたい場合もあります。 例えば、以下はクローズボタンのデフォルト動作です。コードに追加する必要はありませんが、必要な場合の実装方法を確認できます。 :::tip ボタンの[アクション](android-handle-paywall-actions)と[イベント](android-handling-events)の処理方法については、ガイドを参照してください。 ::: ```kotlin showLineNumbers title="Kotlin" override fun onActionPerformed(action: AdaptyUI.Action, context: Context) { when (action) { AdaptyUI.Action.Close -> (context as? Activity)?.onBackPressed() // default behavior } } ``` ```java showLineNumbers @Override public void onActionPerformed(@NonNull AdaptyUI.Action action, @NonNull Context context) { if (action instanceof AdaptyUI.Action.Close) { if (context instanceof Activity) { ((Activity) context).onBackPressed(); } } } ``` ## 次のステップ \{#next-steps\} --- no_index: true --- import Callout from '../../../components/Callout.astro'; ご質問やお困りのことがあれば、[サポートフォーラム](https://adapty.featurebase.app/)をご覧ください。よくある質問への回答を見つけたり、ご自身の質問を投稿することができます。チームとコミュニティがサポートいたします! ペイウォールをアプリに表示する準備が整いました。[Google Play Storeでのテスト購入](testing-on-android)を行い、ペイウォールからテスト購入を完了できることを確認してください。 次に、適切なユーザーにペイウォールを表示したり有料機能へのアクセスを付与したりするために、[ユーザーのアクセスレベルを確認する](android-check-subscription-status)必要があります。 ## 完全な実装例 \{#full-example\} 以下は、これらのすべての手順をアプリに統合した例です。 ```kotlin showLineNumbers title="Kotlin" class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Adapty.getPaywall("YOUR_PLACEMENT_ID") { paywallResult -> if (paywallResult is AdaptyResult.Success) { val paywall = paywallResult.value if (!paywall.hasViewConfiguration) { // Use custom logic return@getPaywall } AdaptyUI.getViewConfiguration(paywall) { configResult -> if (configResult is AdaptyResult.Success) { val viewConfiguration = configResult.value val paywallView = AdaptyUI.getPaywallView( this, viewConfiguration, null, // products = null means auto-fetch object : AdaptyUIEventListener { override fun onActionPerformed(action: AdaptyUI.Action, context: Context) { when (action) { is AdaptyUI.Action.Close -> { (context as? Activity)?.onBackPressed() } } } } ) setContentView(paywallView) } } } } } } ``` ```java showLineNumbers public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Adapty.getPaywall("YOUR_PLACEMENT_ID", paywallResult -> { if (paywallResult instanceof AdaptyResult.Success) { AdaptyPaywall paywall = ((AdaptyResult.Success) paywallResult).getValue(); if (!paywall.hasViewConfiguration()) { // Use custom logic return; } AdaptyUI.getViewConfiguration(paywall, configResult -> { if (configResult instanceof AdaptyResult.Success) { AdaptyUI.LocalizedViewConfiguration viewConfiguration = ((AdaptyResult.Success) configResult).getValue(); AdaptyPaywallView paywallView = AdaptyUI.getPaywallView( this, viewConfiguration, null, // products = null means auto-fetch new AdaptyUIEventListener() { @Override public void onActionPerformed(@NonNull AdaptyUI.Action action, @NonNull Context context) { if (action instanceof AdaptyUI.Action.Close) { if (context instanceof Activity) { ((Activity) context).onBackPressed(); } } } } ); setContentView(paywallView); } }); } }); } } ``` --- # File: android-check-subscription-status --- --- title: "Android SDKでサブスクリプションステータスを確認する" description: "AdaptyでAndroidアプリのサブスクリプションステータスを確認する方法を学びましょう。" --- 有料コンテンツへのアクセス許可やペイウォールの表示を判断するには、プロファイル内の[アクセスレベル](access-level)を確認する必要があります。 この記事では、プロファイルの状態にアクセスして、ペイウォールを表示するか有料機能へのアクセスを許可するかを決める方法を説明します。 ## サブスクリプションステータスを取得する \{#get-subscription-status\} ペイウォールを表示するか有料コンテンツを見せるかを判断するとき、プロファイルの[アクセスレベル](access-level)を確認します。方法は2つあります: - 最新のプロファイルデータがすぐに必要な場合(アプリ起動時など)や強制更新したい場合は、`getProfile` を呼び出す。 - **プロファイルの自動更新**を設定して、サブスクリプションステータスが変わるたびに自動でリフレッシュされるローカルコピーを保持する。 ### プロファイルを取得する \{#get-profile\} サブスクリプションステータスを取得する最もシンプルな方法は、`getProfile` メソッドを使ってプロファイルにアクセスすることです: ```kotlin showLineNumbers Adapty.getProfile { result -> when (result) { is AdaptyResult.Success -> { val profile = result.value // check the access } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` ```java showLineNumbers Adapty.getProfile(result -> { if (result instanceof AdaptyResult.Success) { AdaptyProfile profile = ((AdaptyResult.Success) result).getValue(); // check the access } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` ### サブスクリプション更新を監視する \{#listen-to-subscription-updates\} アプリでプロファイルの更新を自動的に受け取るには: 1. `Adapty.setOnProfileUpdatedListener()` を使ってプロファイルの変更を監視する。ユーザーのサブスクリプションステータスが変わると、Adaptyが自動でこのメソッドを呼び出します。 2. このメソッドが呼び出されたら更新されたプロファイルデータを保存し、追加のネットワークリクエストなしにアプリ全体で利用できるようにする。 ```kotlin class SubscriptionManager { private var currentProfile: AdaptyProfile? = null init { // Listen for profile updates Adapty.setOnProfileUpdatedListener { profile -> currentProfile = profile // Update UI, unlock content, etc. } } // Use stored profile instead of calling getProfile() fun hasAccess(): Boolean { return currentProfile?.accessLevels["YOUR_ACCESS_LEVEL"]?.isActive == true } } ``` ```java public class SubscriptionManager { private AdaptyProfile currentProfile; public SubscriptionManager() { // Listen for profile updates Adapty.setOnProfileUpdatedListener(profile -> { this.currentProfile = profile; // Update UI, unlock content, etc. }); } // Use stored profile instead of calling getProfile() public boolean hasAccess() { if (currentProfile == null) { return false; } AdaptyAccessLevel premiumAccess = currentProfile.getAccessLevels().get("YOUR_ACCESS_LEVEL"); return premiumAccess != null && premiumAccess.isActive(); } } ``` :::note Adaptyはアプリ起動時にプロファイル更新リスナーを自動で呼び出し、デバイスがオフラインでもキャッシュされたサブスクリプションデータを提供します。 ::: ## プロファイルとペイウォールのロジックを連携させる \{#connect-profile-with-paywall-logic\} ペイウォールの表示や有料機能へのアクセス許可をすぐに判断する必要がある場合、ユーザーのプロファイルを直接確認できます。このアプローチは、アプリ起動時、プレミアムセクションへの遷移時、特定コンテンツの表示前など、さまざまなシナリオで役立ちます。 ```kotlin private fun initializePaywall() { loadPaywall { paywallView -> checkAccessLevel { result -> when (result) { is AdaptyResult.Success -> { if (!result.value && paywallView != null) { setContentView(paywallView) // Show paywall if no access } } is AdaptyResult.Error -> { if (paywallView != null) { setContentView(paywallView) // Show paywall if access check fails } } } } } } private fun checkAccessLevel(callback: ResultCallback) { Adapty.getProfile { result -> when (result) { is AdaptyResult.Success -> { val hasAccess = result.value.accessLevels["YOUR_ACCESS_LEVEL"]?.isActive == true callback.onResult(AdaptyResult.Success(hasAccess)) } is AdaptyResult.Error -> { callback.onResult(AdaptyResult.Error(result.error)) } } } } ``` ```java private void initializePaywall() { loadPaywall(paywallView -> { checkAccessLevel(result -> { if (result instanceof AdaptyResult.Success) { boolean hasAccess = ((AdaptyResult.Success) result).getValue(); if (!hasAccess && paywallView != null) { setContentView(paywallView); // Show paywall if no access } } else if (result instanceof AdaptyResult.Error) { if (paywallView != null) { setContentView(paywallView); // Show paywall if access check fails } } }); }); } private void checkAccessLevel(ResultCallback callback) { Adapty.getProfile(result -> { if (result instanceof AdaptyResult.Success) { AdaptyProfile profile = ((AdaptyResult.Success) result).getValue(); AdaptyAccessLevel premiumAccess = profile.getAccessLevels().get("YOUR_ACCESS_LEVEL"); boolean hasAccess = premiumAccess != null && premiumAccess.isActive(); callback.onResult(AdaptyResult.success(hasAccess)); } else if (result instanceof AdaptyResult.Error) { callback.onResult(AdaptyResult.error(((AdaptyResult.Error) result).getError())); } }); } ``` ## 次のステップ \{#next-steps\} サブスクリプションステータスの確認方法を習得したら、次は[ユーザープロファイルの操作](android-quickstart-identify)を学び、ユーザーが購入済みのコンテンツにアクセスできるようにしましょう。 --- # File: android-quickstart-identify --- --- title: "Android SDKでのユーザー識別" description: "AndroidアプリにおけるAdaptyのアプリ内サブスクリプション管理のクイックスタートガイド。" --- :::important このガイドは、独自の認証システムを持つ方を対象としています。ここでは、既存の認証システムと連携させるために、Adaptyのユーザープロファイルを操作する方法を説明します。 ::: ユーザーの購入履歴の管理方法は、アプリの認証モデルによって異なります。 - アプリにバックエンド認証がなく、ユーザーデータを保存しない場合は、[匿名ユーザーに関するセクション](#anonymous-users)を参照してください。 - アプリにバックエンド認証がある(または今後追加する予定の)場合は、[識別済みユーザーに関するセクション](#identified-users)を参照してください。 **主要な概念**: - **プロファイル**はSDKが動作するために必要なエンティティです。Adaptyが自動的に作成します。 - プロファイルは匿名(**カスタマーユーザーIDなし**)または識別済み(**カスタマーユーザーIDあり**)のいずれかです。 - **カスタマーユーザーID**を提供することで、Adaptyのプロファイルと内部認証システムを相互参照できます。 匿名ユーザーと識別済みユーザーの違いは以下の通りです。 | | 匿名ユーザー | 識別済みユーザー | |-------------------------|---------------------------------------------------|-------------------------------------------------------------------------| | **購入の管理** | ストアレベルでの購入履歴の復元 | カスタマーユーザーIDを通じて端末をまたいで購入履歴を維持 | | **プロファイルの管理** | 再インストールのたびに新しいプロファイルが作成される | セッションや端末をまたいで同一プロファイルが使われる | | **データの永続性** | 匿名ユーザーのデータはアプリのインストールに紐づく | 識別済みユーザーのデータはアプリの再インストール後も維持される | ## 匿名ユーザー \{#anonymous-users\} バックエンド認証を使用しない場合、**アプリのコードで認証処理を実装する必要はありません**。 1. アプリの初回起動時にSDKが有効化されると、Adaptyは**ユーザーの新しいプロファイルを作成します**。 2. ユーザーがアプリ内で何かを購入すると、その購入は**Adaptyプロファイルとストアアカウントに関連付けられます**。 3. ユーザーがアプリを**再インストール**したり、**新しい端末**にインストールしたりすると、Adaptyは**有効化時に新しい匿名プロファイルを作成します**。 4. ユーザーが過去にアプリで購入を行っている場合、デフォルトではSDKの有効化時にApp Storeから購入履歴が自動的に同期されます。 匿名ユーザーの場合、インストールのたびに新しいプロファイルが作成されますが、Adaptyのアナリティクスでは[新規インストールとみなす条件を設定](general#4-installs-definition-for-analytics)できるため、これは問題になりません。 匿名ユーザーの場合、**デバイスID**でインストールをカウントする必要があります。この場合、端末への各アプリインストール(再インストールを含む)が1回のインストールとしてカウントされます。 ## 識別済みユーザー \{#identified-users\} アプリでユーザーを識別するには、2つの方法があります。 - [**ログイン/サインアップ時:**](#during-loginsignup) ユーザーがアプリ起動後にサインインする場合、認証時にカスタマーユーザーIDを指定して`identify()`を呼び出します。 - [**SDK有効化時:**](#during-the-sdk-activation) アプリ起動時にすでにカスタマーユーザーIDが保存されている場合、`activate()`を呼び出す際に一緒に送信します。 :::important デフォルトでは、Adaptyが別のカスタマーユーザーIDに現在関連付けられているカスタマーユーザーIDからの購入を受け取った場合、アクセスレベルは共有され、両方のプロファイルが有料アクセスを持ちます。この設定を変更して、有料アクセスを一方のプロファイルから別のプロファイルに移行したり、共有を完全に無効にしたりすることができます。詳細は[こちらの記事](general#6-sharing-paid-access-between-user-accounts)をご覧ください。 ::: ### ログイン/サインアップ時 \{#during-loginsignup\} アプリ起動後にユーザーを識別する場合(例:ログインまたはサインアップ後)、`identify`メソッドを使用してカスタマーユーザーIDを設定します。 - このカスタマーユーザーIDを**まだ使用したことがない場合**、Adaptyは自動的に現在のプロファイルにリンクします。 - このカスタマーユーザーIDを**以前にユーザーの識別に使用したことがある場合**、Adaptyはそのカスタマーユーザーに紐づくプロファイルに切り替えます。 :::important カスタマーユーザーIDは各ユーザーに対して一意である必要があります。パラメータの値をハードコードすると、すべてのユーザーが同一人物とみなされます。 ::: 他のSDKメソッドを呼び出す前に、`identify`の完了コールバックが呼ばれるまで待機してください。同時に呼び出すと、識別済みプロファイルではなく匿名プロファイルに処理が紐づく場合があります。詳細は[Android SDKの呼び出し順序](android-sdk-call-order)をご覧ください。 ```kotlin showLineNumbers Adapty.identify("YOUR_USER_ID") { error -> // Unique for each user if (error == null) { // successful identify } } ``` ```java showLineNumbers // User IDs must be unique for each user Adapty.identify("YOUR_USER_ID", error -> { if (error == null) { // successful identify } }); ``` ### SDK有効化時 \{#during-the-sdk-activation\} SDKを有効化する時点でカスタマーユーザーIDが分かっている場合、`identify`を別途呼び出す代わりに、`activate`メソッドに含めて送信できます。 カスタマーユーザーIDが分かっていても有効化後に設定する場合、有効化時にAdaptyは新しい匿名プロファイルを作成し、`identify`を呼び出した後にのみ既存のプロファイルに切り替えます。 既存のカスタマーユーザーID(以前に使用したもの)でも新しいものでも渡すことができます。新しいカスタマーユーザーIDを渡した場合、有効化時に作成された新しいプロファイルが自動的にそのカスタマーユーザーIDにリンクされます。 :::note デフォルトでは、匿名プロファイルの作成はアナリティクスのダッシュボードに影響しません。インストールはデバイスIDに基づいてカウントされるためです。 デバイスIDはストアからの端末へのアプリの単一インストールを表し、アプリを再インストールした場合にのみ再生成されます。 初回インストールか再インストールか、または既存のカスタマーユーザーIDが使用されているかどうかは関係ありません。 プロファイルの作成(SDKの有効化またはログアウト時)、ログイン、アプリの再インストールを伴わないアップグレードでは、追加のインストールイベントは発生しません。 デバイスではなく一意のユーザーに基づいてインストールをカウントしたい場合は、**App settings**から[**Installs definition for analytics**](general#4-installs-definition-for-analytics)を設定してください。 ::: ```kotlin showLineNumbers AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withCustomerUserId("user123") // Customer user IDs must be unique for each user. If you hardcode the parameter value, all users will be considered as one. .build() ``` ```java showLineNumbers new AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withCustomerUserId("user123") // Customer user IDs must be unique for each user. If you hardcode the parameter value, all users will be considered as one. .build(); ``` ### ユーザーのログアウト \{#log-users-out\} ユーザーをログアウトさせるボタンがある場合は、`logout`メソッドを使用してください。 :::important ユーザーをログアウトすると、そのユーザー用に新しい匿名プロファイルが作成されます。 ::: ```kotlin showLineNumbers Adapty.logout { error -> if (error == null) { // successful logout } } ``` ```java showLineNumbers Adapty.logout(error -> { if (error == null) { // successful logout } }); ``` :::info ユーザーをアプリに再ログインさせるには、`identify`メソッドを使用してください。 ::: ### ログインなしでの購入を許可する \{#allow-purchases-without-login\} ユーザーがアプリへのログイン前後どちらでも購入できる場合、ログイン後もアクセスが維持されるようにする必要があります。 1. ログアウト状態のユーザーが購入を行うと、Adaptyはその購入を匿名プロファイルIDに紐付けます。 2. ユーザーがアカウントにログインすると、Adaptyは識別済みプロファイルへの切り替えを行います。 - 新しいカスタマーユーザーIDの場合(例:登録前に購入が行われた場合)、Adaptyは現在のプロファイルにカスタマーユーザーIDを割り当てるため、すべての購入履歴が維持されます。 - 既存のカスタマーユーザーIDの場合(そのカスタマーユーザーIDがすでにプロファイルにリンクされている場合)、プロファイル切り替え後に実際のアクセスレベルを取得する必要があります。識別後すぐに[`getProfile`](android-check-subscription-status)を呼び出すか、[プロファイルの更新をリッスン](android-check-subscription-status)してデータが自動的に同期されるようにすることができます。 ## 次のステップ \{#next-steps\} おめでとうございます!アプリにアプリ内課金のロジックを実装できました!アプリのマネタイズが順調に進むことを願っています! Adaptyをさらに活用するために、以下のトピックもご覧ください。 - [**テスト**](troubleshooting-test-purchases): すべてが期待通りに動作することを確認する - [**オンボーディング**](android-onboardings): オンボーディングでユーザーを引き付け、リテンションを高める - [**インテグレーション**](configuration): マーケティングアトリビューションや分析サービスとたった1行のコードで連携する - [**カスタムプロファイル属性の設定**](android-setting-user-attributes): ユーザープロファイルにカスタム属性を追加してセグメントを作成し、A/Bテストを実施したり、ユーザーごとに異なるペイウォールを表示したりする --- # File: adapty-sdk-integration-skill-android --- --- title: "SDKインテグレーションスキルを使ってAdaptyをAndroidアプリに統合する" description: "adapty-sdk-integrationスキルを使って、AIコーディングツールでAdapty SDKをAndroidアプリにエンドツーエンドで統合しましょう。" --- :::important このスキルはベータ版です。処理が止まったり予期しない動作をした場合は、代わりに[ステップバイステップの統合ガイド](adapty-cursor-android)をご利用ください。AIツールが各ステップを適切なドキュメントとともに進められるようになっています。 ::: --- no_index: true --- [adapty-sdk-integration スキル](https://github.com/adaptyteam/adapty-sdk-integration-skill)は、Adapty のインテグレーションをエンドツーエンドで自動化します。ダッシュボードのセットアップ、SDK のインストール、ペイウォール、各ステージの検証まで対応しています。プラットフォームを自動検出し、各ステージで関連する Adapty ドキュメントを取得します。 **対応ツール**: Claude Code、GitHub Copilot CLI、OpenAI Codex、Gemini CLI。 インストールするには、お使いのツール向けのフォームを選択してください。完全なリストは[スキルの README](https://github.com/adaptyteam/adapty-sdk-integration-skill) をご覧ください。 **Claude Code** ``` claude plugin marketplace add adaptyteam/adapty-sdk-integration-skill claude plugin install adapty-sdk-integration@adapty ``` **GitHub Copilot CLI** ``` gh skill install adaptyteam/adapty-sdk-integration-skill ``` **Gemini CLI** ``` gemini skills install https://github.com/adaptyteam/adapty-sdk-integration-skill ``` **OpenAI Codex またはその他のツール**: リポジトリをクローンし、`plugins/adapty-sdk-integration/skills/adapty-sdk-integration/` をツールのスキルディレクトリにコピーしてください。 インストール後、プロジェクト内でスキルを実行します: ``` /adapty-sdk-integration ``` スキルがいくつかのセットアップ質問を行い、その後ダッシュボードのセットアップ、SDK のインストール、ペイウォール、検証の手順を案内します。 --- # File: adapty-cursor-android --- --- title: "AIを使ってAndroidアプリにAdaptyを統合する" description: "Cursor、Context7、ChatGPT、Claude、その他のAIツールを使って、AndroidアプリにAdaptyをステップバイステップで統合するガイド。" --- このガイドでは、AIコーディングツールを使って、AdaptyをAndroidアプリへ段階的に統合していきます。適切なAdaptyドキュメントを正しい順番でAIに渡すのがポイントです。 For a fully automated integration, use the [adapty-sdk-integration skill](https://github.com/adaptyteam/adapty-sdk-integration-skill): it runs the whole integration from your AI coding tool in one command. ## 始める前に:ダッシュボードの設定 \{#before-you-start-dashboard-setup\} AdaptyはSDKコードを書く前に、ダッシュボードで一定の設定が必要です。インタラクティブなLLMスキルを使う方法と、ダッシュボードから手動で行う方法があります。 ### スキルを使う方法(推奨) \{#skill-approach-recommended\} Adapty CLIスキルを使えば、LLMがアプリ、プロダクト、アクセスレベル、ペイウォール、プレースメントを直接設定できます。各ステップでダッシュボードを開く必要がなく、[ストアの接続](integrate-payments)だけダッシュボードで行えば十分です。 ``` npx skills add adaptyteam/adapty-cli --skill adapty-cli ``` スキルを追加したら、エージェント内で `/adapty-cli` を実行してください。ストアに接続するためにダッシュボードを開くタイミングも含め、各ステップを案内してくれます。 ### ダッシュボードを使う方法 \{#dashboard-approach\} 手動ですべてを設定したい場合は、コードを書き始める前に以下の準備が必要です。ダッシュボードの値はLLMが調べることができないため、自分で用意する必要があります。 1. **アプリストアを接続する**: Adapty ダッシュボードで **App settings → General** へ移動します。購入機能を動かすには必須です。 [Google Playを接続する](integrate-payments) 2. **Public SDKキーをコピーする**: Adapty ダッシュボードで **App settings → General** へ移動し、**API keys** セクションを確認します。コード内では、Adaptyの設定ビルダーに渡す文字列として使用します。 3. **プロダクトを1つ以上作成する**: Adapty ダッシュボードの **Products** ページへ移動します。プロダクトはコード内で直接参照しません — Adatyはペイウォールを通じてプロダクトを届けます。 [プロダクトを追加する](quickstart-products) 4. **ペイウォールとプレースメントを作成する**: Adapty ダッシュボードで **Paywalls** ページにペイウォールを作成し、**Placements** ページでプレースメントに割り当てます。コード内では、`Adapty.getPaywall("YOUR_PLACEMENT_ID")` に渡す文字列がプレースメントIDです。 [ペイウォールを作成する](quickstart-paywalls) 5. **アクセスレベルを設定する**: Adapty ダッシュボードで **Products** ページのプロダクトごとに設定します。コード内では `profile.accessLevels["premium"]?.isActive` でチェックする文字列です。デフォルトの `premium` アクセスレベルはほとんどのアプリで機能します。プロダクトによって(例:`basic` プランと `pro` プランなど)ユーザーがアクセスできる機能が異なる場合は、コーディングを始める前に[アクセスレベルを追加作成](assigning-access-level-to-a-product)してください。 :::tip 以上の5つが揃ったら、コードを書く準備完了です。「Public SDKキーはX、プレースメントIDはY」とLLMに伝えると、正しい初期化コードとペイウォール取得コードを生成してもらえます。 ::: ### 準備ができたら設定するもの \{#set-up-when-ready\} コーディング開始に必須ではありませんが、統合が進んだ段階で必要になります。 - **A/Bテスト**: **Placements** ページで設定します。コードの変更は不要です。 [A/Bテスト](ab-tests) - **追加のペイウォールとプレースメント**: 異なるプレースメントIDで `getPaywall` 呼び出しを追加します。 - **アナリティクス連携**: **Integrations** ページで設定します。連携先によって手順が異なります。[アナリティクス連携](analytics-integration)・[アトリビューション連携](attribution-integration)を参照してください。 ## LLMにAdaptyドキュメントを渡す \{#feed-adapty-docs-to-your-llm\} ### Context7を使う(推奨) \{#use-context7-recommended\} [Context7](https://context7.com) は、LLMに最新のAdaptyドキュメントへの直接アクセスを提供するMCPサーバーです。質問内容に基づいて適切なドキュメントを自動的に取得するため、URLを手動で貼り付ける必要がありません。 Context7は **Cursor**、**Claude Code**、**Windsurf**、その他MCP対応ツールで動作します。セットアップするには以下を実行してください: ``` npx ctx7 setup ``` エディタを自動検出してContext7サーバーを設定します。手動セットアップの方法は [Context7 GitHubリポジトリ](https://github.com/upstash/context7)をご覧ください。 設定完了後、プロンプトでAdaptyライブラリを参照できます: ``` Use the adaptyteam/adapty-docs library to look up how to install the Android SDK ``` :::warning Context7を使えばドキュメントのリンクを手動で貼り付ける必要はなくなりますが、実装の順序は重要です。すべてが正しく動作するよう、以下の[実装ウォークスルー](#implementation-walkthrough)をステップごとに進めてください。 ::: ### プレーンテキストドキュメントを使う \{#use-plain-text-docs\} AdaptyのドキュメントはプレーンテキストのMarkdownとして取得できます。URLの末尾に `.md` を追加するか、記事タイトル下の **Copy for LLM** をクリックしてください。例:[adapty-cursor-android.md](https://adapty.io/docs/ja/adapty-cursor-android.md) 以下の[実装ウォークスルー](#implementation-walkthrough)の各ステップには、貼り付けるための `.md` リンクが入った「LLMへ送るプロンプト」ブロックがあります。 まとめて多くのドキュメントを取得する場合は、以下の[インデックスファイルとプラットフォーム別サブセット](#plain-text-doc-index-files)を参照してください。 ## 実装ウォークスルー \{#implementation-walkthrough\} ここからは、実装順にAdaptyの統合を進めます。各ステージには、LLMに送るドキュメント、完了時に確認すべき内容、よくある問題が含まれています。 ### 統合計画を立てる \{#plan-your-integration\} コードを書き始める前に、LLMにプロジェクトを分析させ、実装計画を作成してもらいましょう。AIツールに計画モード(CursorやClaude Codeのプランモードなど)がある場合は、LLMがコードを書く前にプロジェクト構造とAdaptyドキュメントの両方を読めるよう活用してください。 購入に使うアプローチをLLMに伝えてください — これにより、参照すべきガイドが変わります。 - [**Adaptyペイウォールビルダー**](adapty-paywall-builder): Adaptのノーコードビルダーでペイウォールを作成し、SDKが自動でレンダリングします。 - [**手動作成のペイウォール**](android-making-purchases): 自分でペイウォールUIをコードで構築しつつ、プロダクトの取得と購入処理はAdaptyを使います。 - [**オブザーバーモード**](observer-vs-full-mode): 既存の購入インフラを維持したまま、アナリティクスと連携にのみAdaptyを使います。 どれを選べばいいかわからない場合は、[クイックスタートの比較表](android-quickstart-paywalls)をご覧ください。 ### SDKのインストールと設定 \{#install-and-configure-the-sdk\} Android StudioでGradleを使ってAdapty SDKの依存関係を追加し、Public SDKキーで有効化します。これが基盤となるため、他の機能はすべてこのステップが完了しないと動きません。 **ガイド:** [Adapty SDKのインストールと設定](sdk-installation-android) LLMへ送るプロンプト: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/sdk-installation-android.md ``` :::tip[チェックポイント] - **期待される結果:** アプリがビルド・実行され、LogcatにAdaptyのアクティベーションログが表示される。 - **注意点:** 「Public API key is missing」エラーが出た場合 → プレースホルダーをApp settingsで確認した実際のキーに置き換えたか確認してください。 ::: ### ペイウォールの表示と購入処理 \{#show-paywalls-and-handle-purchases\} プレースメントIDでペイウォールを取得し、表示して、購入イベントを処理します。必要なガイドは購入処理の方法によって異なります。 進めながらサンドボックスで各購入をテストしてください。最後まで待たないようにしましょう。セットアップ方法は[サンドボックスでの購入テスト](test-purchases-in-sandbox)をご覧ください。 **ガイド:** - [ペイウォールを使って購入を有効にする(クイックスタート)](android-quickstart-paywalls) - [ペイウォールビルダーのペイウォールと設定の取得](android-get-pb-paywalls) - [ペイウォールの表示](android-present-paywalls) - [ペイウォールイベントの処理](android-handling-events) - [ボタンアクションへの対応](android-handle-paywall-actions) LLMへ送るプロンプト: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/android-quickstart-paywalls.md - https://adapty.io/docs/ja/android-get-pb-paywalls.md - https://adapty.io/docs/ja/android-present-paywalls.md - https://adapty.io/docs/ja/android-handling-events.md - https://adapty.io/docs/ja/android-handle-paywall-actions.md ``` :::tip[チェックポイント] - **期待される結果:** 設定したプロダクトとともにペイウォールが表示され、プロダクトをタップするとサンドボックスの購入ダイアログが起動する。 - **注意点:** ペイウォールが空、または `getPaywall` エラーが出る場合 → プレースメントIDがダッシュボードと完全に一致しているか、プレースメントにオーディエンスが割り当てられているかを確認してください。 ::: **ガイド:** - [カスタムペイウォールで購入を有効にする(クイックスタート)](android-quickstart-manual) - [ペイウォールとプロダクトの取得](fetch-paywalls-and-products-android) - [リモートコンフィグで設計したペイウォールのレンダリング](present-remote-config-paywalls-android) - [購入処理](android-making-purchases) - [購入の復元](android-restore-purchase) LLMへ送るプロンプト: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/android-quickstart-manual.md - https://adapty.io/docs/ja/fetch-paywalls-and-products-android.md - https://adapty.io/docs/ja/present-remote-config-paywalls-android.md - https://adapty.io/docs/ja/android-making-purchases.md - https://adapty.io/docs/ja/android-restore-purchase.md ``` :::tip[チェックポイント] - **期待される結果:** カスタムペイウォールにAdaptyから取得したプロダクトが表示され、プロダクトをタップするとサンドボックスの購入ダイアログが起動する。 - **注意点:** プロダクト配列が空の場合 → ダッシュボードでペイウォールにプロダクトが割り当てられているか、プレースメントにオーディエンスがあるかを確認してください。 ::: **ガイド:** - [オブザーバーモードの概要](observer-vs-full-mode) - [オブザーバーモードの実装](implement-observer-mode-android) - [オブザーバーモードでのトランザクション報告](report-transactions-observer-mode-android) LLMへ送るプロンプト: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/observer-vs-full-mode.md - https://adapty.io/docs/ja/implement-observer-mode-android.md - https://adapty.io/docs/ja/report-transactions-observer-mode-android.md ``` :::tip[チェックポイント] - **期待される結果:** 既存の購入フローでサンドボックス購入を行った後、Adapty ダッシュボードの **Event Feed** にトランザクションが表示される。 - **注意点:** イベントが表示されない場合 → Adaptyへのトランザクション報告が設定されているか、Google Play リアルタイム デベロッパー通知が設定されているかを確認してください。 ::: ### サブスクリプションのステータス確認 \{#check-subscription-status\} 購入後、ユーザープロファイルでアクティブなアクセスレベルを確認し、プレミアムコンテンツへのアクセスを制御します。 **ガイド:** [サブスクリプションのステータス確認](android-check-subscription-status) LLMへ送るプロンプト: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/android-check-subscription-status.md ``` :::tip[チェックポイント] - **期待される結果:** サンドボックスで購入後、`profile.accessLevels["premium"]?.isActive` が `true` を返す。 - **注意点:** 購入後に `accessLevels` が空の場合 → ダッシュボードでプロダクトにアクセスレベルが割り当てられているかを確認してください。 ::: ### ユーザーの識別 \{#identify-users\} アプリのユーザーアカウントとAdaptyプロファイルを紐付けることで、デバイスをまたいで購入情報が維持されます。 :::important アプリに認証機能がない場合はこのステップをスキップしてください。 ::: **ガイド:** [ユーザーの識別](android-quickstart-identify) LLMへ送るプロンプト: ``` Read these Adapty docs before writing code: - https://adapty.io/docs/ja/android-quickstart-identify.md ``` :::tip[チェックポイント] - **期待される結果:** `Adapty.identify("your-user-id")` を呼び出した後、ダッシュボードの **Profiles** セクションにカスタムユーザーIDが表示される。 - **注意点:** アクティベーション後・ペイウォール取得前に `identify` を呼び出すことで、匿名プロファイルへのアトリビューションを防げます。 ::: ### リリース準備 \{#prepare-for-release\} サンドボックスでの統合確認が完了したら、リリースチェックリストに沿ってプロダクション対応を確認しましょう。 **ガイド:** [リリースチェックリスト](release-checklist) LLMへ送るプロンプト: ``` Read these Adapty docs before releasing: - https://adapty.io/docs/ja/release-checklist.md ``` :::tip[チェックポイント] - **期待される結果:** チェックリストの全項目を確認済み:ストア接続、サーバー通知、購入フロー、アクセスレベルの確認、プライバシー要件。 - **注意点:** Google Play リアルタイム デベロッパー通知が未設定の場合 → **App settings → Android SDK** で設定してください。設定しないとダッシュボードにイベントが表示されません。 ::: ## プレーンテキストドキュメントのインデックスファイル \{#plain-text-doc-index-files\} 個別ページを超えた幅広いコンテキストをLLMに提供したい場合は、Adaptyドキュメント全体をまとめたインデックスファイルを用意しています: - [`llms.txt`](https://adapty.io/docs/ja/llms.txt): すべてのページを `.md` リンク付きで一覧表示。LLMがウェブサイトにアクセスしやすくするための[新興標準](https://llmstxt.org/)です。一部のAIエージェント(ChatGPTなど)では、`llms.txt` をダウンロードしてチャットにファイルとしてアップロードする必要があります。 - [`llms-full.txt`](https://adapty.io/docs/ja/llms-full.txt): Adaptyドキュメントサイト全体を1つのファイルにまとめたもの。非常に大きなファイルのため、全体像が必要なときのみ使用してください。 - Android専用の [`android-llms.txt`](https://adapty.io/docs/ja/android-llms.txt) と [`android-llms-full.txt`](https://adapty.io/docs/ja/android-llms-full.txt): サイト全体と比べてトークン数を節約できるプラットフォーム別サブセットです。 --- # File: android-get-pb-paywalls --- --- title: "Android SDKでペイウォールビルダーのペイウォールとその設定を取得する" description: "Android アプリのサブスクリプション管理を改善するために、Adapty で PB ペイウォールを取得する方法をご紹介します。" --- Adapty ダッシュボードの新しいペイウォールビルダーで[ペイウォールのビジュアル部分をデザイン](adapty-paywall-builder)したら、モバイルアプリにそれを表示できます。まず最初に、プレースメントに紐づくペイウォールとそのビュー設定を以下の手順で取得します。 :::warning 新しいペイウォールビルダーは Android SDK バージョン 3.0 以上で動作します。 ::: このトピックはペイウォールビルダーでカスタマイズしたペイウォールに関するものです。ペイウォールを手動で実装する場合は、[モバイルアプリでリモートコンフィグペイウォールのペイウォールとプロダクトを取得する](fetch-paywalls-and-products-android)をご参照ください。 :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 :::
モバイルアプリでペイウォールを表示する前に(クリックして展開) 1. Adapty ダッシュボードで[プロダクトを作成](create-product)する。 2. Adapty ダッシュボードで[ペイウォールを作成し、プロダクトを組み込む](create-paywall)。 3. Adapty ダッシュボードで[プレースメントを作成し、ペイウォールを組み込む](create-placement)。 4. モバイルアプリに [Adapty SDK](sdk-installation-android) をインストールする。
## ペイウォールビルダーでデザインしたペイウォールを取得する \{#fetch-paywall-designed-with-paywall-builder\} [ペイウォールビルダーでペイウォールをデザイン](adapty-paywall-builder)した場合、モバイルアプリのコードでそれをレンダリングしてユーザーに表示する必要はありません。このようなペイウォールには、表示する内容と表示方法の両方が含まれています。ただし、プレースメントを通じてそのIDを取得し、ビュー設定を取得した上でモバイルアプリに表示する必要があります。 最適なパフォーマンスを確保するには、ペイウォールとその[ビュー設定](android-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder)をできるだけ早く取得し、ユーザーに表示する前に画像のダウンロードが完了するよう十分な時間を確保することが重要です。 ペイウォールを取得するには、`getPaywall` メソッドを使用します。 ```kotlin showLineNumbers ... Adapty.getPaywall("YOUR_PLACEMENT_ID", locale = "en", loadTimeout = 10.seconds) { result -> when (result) { is AdaptyResult.Success -> { val paywall = result.value // the requested paywall } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` ```java showLineNumbers ... Adapty.getPaywall("YOUR_PLACEMENT_ID", "en", TimeInterval.seconds(10), result -> { if (result instanceof AdaptyResult.Success) { AdaptyPaywall paywall = ((AdaptyResult.Success) result).getValue(); // the requested paywall } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` パラメータ: | パラメータ | 必須/任意 | 説明 | |---------|--------|-----------| | **placementId** | 必須 | 取得したい[プレースメント](placements)の識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。 | | **locale** |

任意

デフォルト: `en`

|

[ペイウォールのローカライズ](add-paywall-locale-in-adapty-paywall-builder)の識別子。このパラメータは、マイナス(**-**)で区切られた 1 つまたは 2 つのサブタグで構成される言語コードです。最初のサブタグは言語、2 番目はリージョンを表します。

例:`en` は英語、`pt-br` はブラジルポルトガル語を表します。

ロケールコードとその推奨される使用方法については、[ローカライズとロケールコード](localizations-and-locale-codes)をご参照ください。

| | **fetchPolicy** | デフォルト: `.reloadRevalidatingCacheData` |

デフォルトでは、SDK はサーバーからデータの読み込みを試み、失敗した場合はキャッシュされたデータを返します。ユーザーが常に最新のデータを取得できるため、この設定を推奨します。

ただし、インターネット接続が不安定なユーザーが多い場合は、`.returnCacheDataElseLoad` を使用してキャッシュが存在する場合はそれを返すことを検討してください。この場合、ユーザーは最新のデータを取得できない可能性がありますが、接続状況に関わらず読み込みが速くなります。キャッシュは定期的に更新されるため、セッション中にネットワークリクエストを避けるために使用しても問題ありません。

キャッシュはアプリの再起動後も保持され、アプリを再インストールするか手動でクリアした場合のみ削除されます。

Adapty SDK はペイウォールを 2 層でローカルに保存します。上記の定期更新キャッシュと[フォールバックペイウォール](fallback-paywalls)です。また、CDN を使用してペイウォールを高速に取得し、CDN に到達できない場合はスタンドアロンのフォールバックサーバーも使用します。このシステムは、インターネット接続が不安定な場合でも、常に最新バージョンのペイウォールを確実に取得できるよう設計されています。

| | **loadTimeout** | デフォルト: 5 秒 |

このメソッドのタイムアウト制限を設定する値。タイムアウトに達した場合、キャッシュされたデータまたはローカルフォールバックが返されます。

内部で複数のリクエストが実行される場合があるため、まれに `loadTimeout` で指定した時間よりもわずかに遅れてタイムアウトになることがあります。

Android の場合:拡張関数(`import com.adapty.utils.seconds` の `.seconds` など)を使って `TimeInterval` を作成するか、`TimeInterval.seconds(5)` を使用します。制限なしに設定するには `TimeInterval.INFINITE` を使用します。

| レスポンスパラメータ: | パラメータ | 説明 | | :-------- |:----------------------------------------------------------------------------------------------------------------------------------------------------------------| | Paywall | プロダクト ID のリスト、ペイウォール識別子、リモートコンフィグ、その他いくつかのプロパティを含む [`AdaptyPaywall`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/) オブジェクト。 | ## ペイウォールビルダーでデザインしたペイウォールのビュー設定を取得する \{#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder\} :::important ペイウォールビルダーで **Show on device** トグルが有効になっていることを確認してください。このオプションが有効でない場合、ビュー設定は取得できません。 ::: ペイウォールを取得したら、`ViewConfiguration` が含まれているか確認します。これはペイウォールビルダーで作成されたことを示します。`ViewConfiguration` がある場合はペイウォールビルダーのペイウォールとして扱い、ない場合は[リモートコンフィグペイウォールとして処理](present-remote-config-paywalls)してください。 ビュー設定を読み込むには `getViewConfiguration` メソッドを使用します。 ```kotlin showLineNumbers if (!paywall.hasViewConfiguration) { // use your custom logic return } AdaptyUI.getViewConfiguration(paywall, loadTimeout = 10.seconds) { result -> when(result) { is AdaptyResult.Success -> { val viewConfiguration = result.value // use loaded configuration } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` | パラメータ | 必須/任意 | 説明 | | :-------------- | :------------- | :----------------------------------------------------------- | | **paywall** | 必須 | 目的のペイウォールのコントローラーを取得するための `AdaptyPaywall` オブジェクト。 | | **loadTimeout** | デフォルト: 5 秒 | このメソッドのタイムアウト制限を設定する値。タイムアウトに達した場合、キャッシュされたデータまたはローカルフォールバックが返されます。内部で複数のリクエストが実行される場合があるため、まれに `loadTimeout` で指定した時間よりもわずかに遅れてタイムアウトになることがあります。 | ビュー設定を読み込むには `getViewConfiguration` メソッドを使用します。 ```java showLineNumbers if (!paywall.hasViewConfiguration()) { // use your custom logic return; } AdaptyUI.getViewConfiguration(paywall, TimeInterval.seconds(10), result -> { if (result instanceof AdaptyResult.Success) { AdaptyUI.LocalizedViewConfiguration viewConfiguration = ((AdaptyResult.Success) result).getValue(); // use loaded configuration } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` | パラメータ | 必須/任意 | 説明 | | :----------------------- | :------------- | :----------------------------------------------------------- | | **paywall** | 必須 | 目的のペイウォールのコントローラーを取得するための `AdaptyPaywall` オブジェクト。 | | **loadTimeout** | デフォルト: 5 秒 | このメソッドのタイムアウト制限を設定する値。タイムアウトに達した場合、キャッシュされたデータまたはローカルフォールバックが返されます。内部で複数のリクエストが実行される場合があるため、まれに `loadTimeout` で指定した時間よりもわずかに遅れてタイムアウトになることがあります。 | :::note 複数の言語を使用している場合は、[ペイウォールビルダーのローカライズ](add-paywall-locale-in-adapty-paywall-builder)の追加方法と、ロケールコードの正しい使い方を[こちら](android-localizations-and-locale-codes)でご確認ください。 ::: 読み込みが完了したら、[ペイウォールを表示](android-present-paywalls)します。 ## デフォルトオーディエンス向けのペイウォールを高速取得する \{#get-a-paywall-for-a-default-audience-to-fetch-it-faster\} 通常、ペイウォールはほぼ即座に取得できるため、速度を気にする必要はありません。ただし、オーディエンスやペイウォールが多数あり、ユーザーのインターネット接続が弱い場合は、取得に時間がかかることがあります。そのような場合、ペイウォールをまったく表示しないよりも、デフォルトのペイウォールを表示してスムーズなユーザー体験を確保したいことがあるかもしれません。 この問題に対応するため、`getPaywallForDefaultAudience` メソッドを使用できます。このメソッドは、**All Users** オーディエンス向けに指定したプレースメントのペイウォールを取得します。ただし、推奨されるアプローチは上記の[ペイウォール情報の取得](#fetch-paywall-designed-with-paywall-builder)セクションで説明した `getPaywall` メソッドによる取得です。 :::warning `getPaywall` を推奨する理由 `getPaywallForDefaultAudience` メソッドにはいくつかの重要な欠点があります。 - **後方互換性の問題が生じる可能性**:現在および将来のアプリバージョンで異なるペイウォールを表示する必要がある場合、課題が生じることがあります。現在(レガシー)バージョンをサポートするペイウォールを設計するか、現在(レガシー)バージョンのユーザーがレンダリングされないペイウォールに遭遇するリスクを受け入れるかのいずれかになります。 - **ターゲティングの喪失**:すべてのユーザーが **All Users** オーディエンス向けに設計された同じペイウォールを見ることになり、国別、マーケティングアトリビューション、またはカスタム属性に基づくパーソナライズドターゲティングが失われます。 これらの欠点を受け入れてでもペイウォールの高速取得のメリットを得たい場合は、以下のように `getPaywallForDefaultAudience` メソッドを使用してください。そうでない場合は、[上記](#fetch-paywall-designed-with-paywall-builder)で説明した `getPaywall` を使い続けてください。 ::: ```kotlin showLineNumbers Adapty.getPaywallForDefaultAudience("YOUR_PLACEMENT_ID", locale = "en") { result -> when (result) { is AdaptyResult.Success -> { val paywall = result.value // the requested paywall } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` ```java showLineNumbers Adapty.getPaywallForDefaultAudience("YOUR_PLACEMENT_ID", "en", result -> { if (result instanceof AdaptyResult.Success) { AdaptyPaywall paywall = ((AdaptyResult.Success) result).getValue(); // the requested paywall } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` :::note `getPaywallForDefaultAudience` メソッドは Android SDK 2.11.3 以降で利用可能です。 ::: | パラメータ | 必須/任意 | 説明 | |---------|--------|-----------| | **placementId** | 必須 | [プレースメント](placements)の識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。 | | **locale** |

任意

デフォルト: `en`

|

[ペイウォールのローカライズ](add-remote-config-locale)の識別子。このパラメータは、マイナス(**-**)で区切られた 1 つ以上のサブタグで構成される言語コードです。最初のサブタグは言語、2 番目はリージョンを表します。

例:`en` は英語、`pt-br` はブラジルポルトガル語を表します。

ロケールコードとその推奨される使用方法については、[ローカライズとロケールコード](localizations-and-locale-codes)をご参照ください。

| | **fetchPolicy** | デフォルト: `.reloadRevalidatingCacheData` |

デフォルトでは、SDK はサーバーからデータの読み込みを試み、失敗した場合はキャッシュされたデータを返します。ユーザーが常に最新のデータを取得できるため、この設定を推奨します。

ただし、インターネット接続が不安定なユーザーが多い場合は、`.returnCacheDataElseLoad` を使用してキャッシュが存在する場合はそれを返すことを検討してください。この場合、ユーザーは最新のデータを取得できない可能性がありますが、接続状況に関わらず読み込みが速くなります。キャッシュは定期的に更新されるため、セッション中にネットワークリクエストを避けるために使用しても問題ありません。

キャッシュはアプリの再起動後も保持され、アプリを再インストールするか手動でクリアした場合のみ削除されます。

| ## アセットのカスタマイズ \{#customize-assets\} ペイウォール内の画像や動画をカスタマイズするには、カスタムアセットを実装します。 ヒーロー画像と動画には定義済みの ID(`hero_image` と `hero_video`)があります。カスタムアセットバンドルでは、これらの ID でそれぞれの要素を指定し、動作をカスタマイズします。 その他の画像や動画については、Adapty ダッシュボードで[カスタム ID を設定](custom-media)する必要があります。 たとえば、以下のようなことができます。 - 一部のユーザーに別の画像や動画を表示する。 - リモートのメイン画像を読み込んでいる間、ローカルのプレビュー画像を表示する。 - 動画を再生する前にプレビュー画像を表示する。 :::important この機能を使用するには、Adapty Android SDK をバージョン 3.7.0 以上にアップデートしてください。 ::: カスタムアセットをシンプルな辞書形式で提供する例を次に示します。 ```kotlin showLineNumbers val customAssets = AdaptyCustomAssets.of( "hero_image" to AdaptyCustomImageAsset.remote( url = "https://example.com/image.jpg", preview = AdaptyCustomImageAsset.file( FileLocation.fromAsset("images/hero_image_preview.png"), ) ), "hero_video" to AdaptyCustomVideoAsset.file( FileLocation.fromResId(requireContext(), R.raw.custom_video), preview = AdaptyCustomImageAsset.file( FileLocation.fromResId(requireContext(), R.drawable.video_preview), ), ), ) val paywallView = AdaptyUI.getPaywallView( activity, viewConfiguration, products, eventListener, insets, customAssets, ) ``` :::note アセットが見つからない場合、ペイウォールはデフォルトの表示にフォールバックします。 ::: --- # File: android-present-paywalls --- --- title: "Android - 新しいペイウォールビルダーのペイウォールを表示する" description: "Androidで効果的なマネタイズのためのペイウォール表示方法を学びましょう。" --- ペイウォールビルダーを使ってペイウォールをカスタマイズした場合、ユーザーに表示するためのレンダリングコードをモバイルアプリに書く必要はありません。このようなペイウォールには、表示内容と表示方法の両方が含まれています。 :::warning このガイドは、SDK v3.0 が必要な**新しいペイウォールビルダーのペイウォール**専用です。ペイウォールの表示方法は、異なるバージョンのペイウォールビルダーで設計されたペイウォール、リモートコンフィグペイウォール、[Observer モード](observer-vs-full-mode)によって異なります。 - **リモートコンフィグペイウォール**の表示については、[リモートコンフィグで設計されたペイウォールのレンダリング](present-remote-config-paywalls)をご覧ください。 - **Observer モードペイウォール**の表示については、[Android - Observer モードでペイウォールビルダーのペイウォールを表示する](android-present-paywall-builder-paywalls-in-observer-mode)をご覧ください。 ::: 以下で使用する `viewConfiguration` オブジェクトの取得方法については、[ペイウォールビルダーのペイウォールと設定を取得する](android-get-pb-paywalls)をご覧ください。 デバイス画面にビジュアルペイウォールを表示するには、まず設定が必要です。`AdaptyUI.getPaywallView()` メソッドを呼び出すか、`AdaptyPaywallView` を直接作成してください: ```kotlin showLineNumbers val paywallView = AdaptyUI.getPaywallView( activity, viewConfiguration, products, eventListener, insets, personalizedOfferResolver, tagResolver, timerResolver, ) ``` ```kotlin showLineNumbers val paywallView = AdaptyPaywallView(activity) // or retrieve it from xml ... with(paywallView) { showPaywall( viewConfiguration, products, eventListener, insets, personalizedOfferResolver, tagResolver, timerResolver, ) } ``` ```java showLineNumbers AdaptyPaywallView paywallView = AdaptyUI.getPaywallView( activity, viewConfiguration, products, eventListener, insets, personalizedOfferResolver, tagResolver, timerResolver ); ``` ```java showLineNumbers AdaptyPaywallView paywallView = new AdaptyPaywallView(activity); //add to the view hierarchy if needed, or you receive it from xml ... paywallView.showPaywall(viewConfiguration, products, eventListener, insets, personalizedOfferResolver, tagResolver, timerResolver); ``` ```xml showLineNumbers ``` ビューが正常に作成されたら、ビュー階層に追加してデバイス画面に表示できます。 `AdaptyUI.getPaywallView()` を呼び出さずに `AdaptyPaywallView` を取得した場合は、`.showPaywall()` メソッドも呼び出す必要があります。 デバイス画面にビジュアルペイウォールを表示するには、まず設定が必要です。次のコンポーザブル関数を使用してください: ```kotlin showLineNumbers AdaptyPaywallScreen( viewConfiguration, products, eventListener, insets, personalizedOfferResolver, tagResolver, timerResolver, ) ``` リクエストパラメータ: | パラメータ | 必須/任意 | 説明 | | :---------------------------- | :------- |:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **viewConfiguration** | 必須 | ペイウォールのビジュアル詳細を含む `AdaptyUI.LocalizedViewConfiguration` オブジェクトを指定します。`Adapty.getViewConfiguration(paywall)` メソッドで読み込んでください。詳細は[ペイウォールのビジュアル設定を取得する](android-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder)をご覧ください。 | | **products** | 任意 | 画面上のプロダクト表示タイミングを最適化するために `AdaptyPaywallProduct` の配列を指定します。`null` を渡すと、AdaptyUI が必要なプロダクトを自動的に取得します。 | | **eventListener** | 任意 | ペイウォールイベントを監視するために `AdaptyUiEventListener` を指定します。使いやすさのために `AdaptyUiDefaultEventListener` の拡張を推奨します。詳細は[ペイウォールイベントの処理](android-handling-events)をご覧ください。 | | **insets** | 任意 |

インセットは、システムバーの後ろにタップ可能な要素が隠れないようにするためのペイウォール周囲のスペースです。

デフォルト: `UNSPECIFIED`(Adapty がインセットを自動調整します。エッジ・ツー・エッジのペイウォールに適しています)

ペイウォールがエッジ・ツー・エッジでない場合は、カスタムインセットを設定することをお勧めします。設定方法は下記の[ペイウォールインセットの変更](#change-paywall-insets)セクションをご覧ください。

| | **personalizedOfferResolver** | 任意 | パーソナライズされた価格設定([詳細はこちら](https://developer.android.com/google/play/billing/integrate#personalized-price))を指定するには、`AdaptyUiPersonalizedOfferResolver` を実装し、`AdaptyPaywallProduct` が個人化された価格かどうかを true/false で返す独自のロジックを渡してください。 | | **tagResolver** | 任意 | ペイウォールテキスト内のカスタムタグを解決するために `AdaptyUiTagResolver` を使用します。このリゾルバーはタグパラメータを受け取り、対応する文字列に解決します。詳細はペイウォールビルダーのカスタムタグのトピックをご覧ください。 | | **timerResolver** | 任意 | カスタムタイマー機能を使用する場合は、ここにリゾルバーを渡してください。 | :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 ::: ## ペイウォールインセットの変更 \{#change-paywall-insets\} インセットは、システムバーの後ろにタップ可能な要素が隠れないようにするためのペイウォール周囲のスペースです。デフォルトでは、Adapty がインセットを自動調整します。これはエッジ・ツー・エッジのペイウォールに適しています。 ペイウォールがエッジ・ツー・エッジでない場合は、カスタムインセットの設定をお勧めします: - ステータスバーとナビゲーションバーのどちらも `AdaptyPaywallView` と重なっていない場合は `AdaptyPaywallInsets.NONE` を使用してください。 - ペイウォールが上部のステータスバーとは重なっているが下部とは重なっていない場合など、より詳細な設定が必要な場合は、以下の例のように `bottomInset` のみを `0` に設定できます: ```kotlin showLineNumbers //create extension function fun View.onReceiveSystemBarsInsets(action: (insets: Insets) -> Unit) { ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets -> val systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()) ViewCompat.setOnApplyWindowInsetsListener(this, null) action(systemBarInsets) insets } } //and then use it with the view paywallView.onReceiveSystemBarsInsets { insets -> val paywallInsets = AdaptyPaywallInsets.vertical(insets.top, 0) paywallView.showPaywall( viewConfiguration, products, eventListener, paywallInsets, personalizedOfferResolver, tagResolver, timerResolver, ) } ``` ```java showLineNumbers ... ViewCompat.setOnApplyWindowInsetsListener(paywallView, (view, insets) -> { Insets systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()); ViewCompat.setOnApplyWindowInsetsListener(paywallView, null); AdaptyPaywallInsets paywallInsets = AdaptyPaywallInsets.of(systemBarInsets.top, 0); paywallView.showPaywall(paywall, products, viewConfiguration, paywallInsets, productTitleResolver); return insets; }); ``` ## 開発者定義タイマーの使用 \{#use-developer-defined-timer\} モバイルアプリで開発者定義タイマーを使用するには、カスタムタイマーとペイウォールのレンダリング時に置き換えられる文字列値をペアにしたディクショナリまたはマップである `timerResolver` オブジェクトを作成します。以下に例を示します: ```kotlin showLineNumbers ... val customTimers = mapOf( "CUSTOM_TIMER_NY" to Calendar.getInstance(TimeZone.getDefault()).apply { set(2025, 0, 1) }.time, // New Year 2025 ) val timerResolver = AdaptyUiTimerResolver { timerId -> customTimers.getOrElse(timerId, { Date(System.currentTimeMillis() + 3600 * 1000L) /* in 1 hour */ } ) } ``` ```java showLineNumbers ... Map customTimers = new HashMap<>(); customTimers.put( "CUSTOM_TIMER_NY", new Calendar.Builder().setTimeZone(TimeZone.getDefault()).setDate(2025, 0, 1).build().getTime() ); AdaptyUiTimerResolver timerResolver = new AdaptyUiTimerResolver() { @NonNull @Override public Date timerEndAtDate(@NonNull String timerId) { Date date = customTimers.get(timerId); return date != null ? date : new Date(System.currentTimeMillis() + 3600 * 1000L); /* in 1 hour */ } }; ``` この例では、`CUSTOM_TIMER_NY` は Adapty ダッシュボードで設定した開発者定義タイマーの **Timer ID** です。`timerResolver` により、アプリはタイマーの終了時刻(元日など)から現在時刻を引いて計算した `13d 09h 03m 34s` のような正確な値でタイマーを動的に更新します。 ## カスタムタグの使用 \{#use-custom-tags\} モバイルアプリでカスタムタグを使用するには、カスタムタグとペイウォールのレンダリング時に置き換えられる文字列値をペアにしたディクショナリまたはマップである `tagResolver` オブジェクトを作成します。以下に例を示します: ```kotlin showLineNumbers val customTags = mapOf("USERNAME" to "John") val tagResolver = AdaptyUiTagResolver { tag -> customTags[tag] } ``` ```java showLineNumbers Map customTags = new HashMap<>(); customTags.put("USERNAME", "John"); AdaptyUiTagResolver tagResolver = customTags::get; ``` この例では、`USERNAME` は Adapty ダッシュボードで `` として入力したカスタムタグです。`tagResolver` により、アプリはこのカスタムタグを `John` のような指定された値に動的に置き換えます。 `tagResolver` はペイウォールを表示する直前に作成・設定することをお勧めします。準備ができたら、ペイウォール表示に使用する AdaptyUI メソッドに渡してください。 ## ペイウォールのローディングインジケーターの色を変更する \{#change-paywall-loading-indicator-color\} ローディングインジケーターのデフォルトカラーは、次の方法でオーバーライドできます: ```xml showLineNumbers title = "XML" ``` --- # File: android-handle-paywall-actions --- --- title: "Android SDKでボタンアクションに対応する" description: "AdaptyのAndroidでペイウォールのボタンアクションを処理し、アプリの収益化を改善する方法。" --- Adaptyのペイウォールビルダーを使ってペイウォールを構築する場合、ボタンを適切に設定することが重要です。 1. [ペイウォールビルダーにボタンを追加](paywall-buttons)し、既存のアクションを割り当てるか、カスタムアクションIDを作成します。 2. 割り当てた各アクションを処理するコードをアプリに記述します。 このガイドでは、コード内でカスタムアクションおよび既存アクションを処理する方法を説明します。 :::warning **購入、復元、ペイウォールのクローズ、URLの開封のみが自動的に処理されます。** それ以外のボタンアクションはすべて、アプリコード内で適切なレスポンスの実装が必要です。 ::: ## ペイウォールを閉じる \{#close-paywalls\} ペイウォールを閉じるボタンを追加するには: 1. ペイウォールビルダーでボタンを追加し、**Close** アクションを割り当てます。 2. アプリコードで、ペイウォールを閉じる `close` アクションのハンドラーを実装します。 :::info Android SDKでは、`close` アクションはデフォルトでペイウォールを閉じる動作をします。ただし、必要に応じてコードでこの動作を上書きすることもできます。たとえば、1つのペイウォールを閉じると別のペイウォールが開くようにする場合などです。 ::: ```kotlin override fun onActionPerformed(action: AdaptyUI.Action, context: Context) { when (action) { AdaptyUI.Action.Close -> (context as? Activity)?.onBackPressed() // default behavior } } ``` ## ペイウォールからURLを開く \{#open-urls-from-paywalls\} :::tip リンクのグループ(利用規約や購入の復元など)を追加したい場合は、ペイウォールビルダーで **Link** 要素を追加し、**Open URL** アクションが割り当てられたボタンと同じ方法で処理します。 ::: ペイウォールからリンクを開くボタンを追加するには(**Terms of use** や **Privacy policy** など): 1. ペイウォールビルダーでボタンを追加し、**Open URL** アクションを割り当て、開きたいURLを入力します。 2. アプリコードで、受け取ったURLをブラウザで開く `openUrl` アクションのハンドラーを実装します。 :::info Android SDKでは、`openUrl` アクションはデフォルトでURLを開く動作をします。ただし、必要に応じてコードでこの動作を上書きすることもできます。 ::: ```kotlin override fun onActionPerformed(action: AdaptyUI.Action, context: Context) { when (action) { is AdaptyUI.Action.OpenUrl -> { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(action.url)) // default behavior context.startActivity(intent) } } } ``` ## アプリへのログイン \{#log-into-the-app\} ユーザーをアプリにログインさせるボタンを追加するには: 1. ペイウォールビルダーでボタンを追加し、**Login** アクションを割り当てます。 2. アプリコードで、ユーザーを識別する `login` アクションのハンドラーを実装します。 ```kotlin override fun onActionPerformed(action: AdaptyUI.Action, context: Context) { when (action) { AdaptyUI.Action.Login -> { val intent = Intent(context, LoginActivity::class.java) context.startActivity(intent) } } } ``` ## カスタムアクションの処理 \{#handle-custom-actions\} その他のアクションを処理するボタンを追加するには: 1. ペイウォールビルダーでボタンを追加し、**Custom** アクションを割り当て、IDを設定します。 2. アプリコードで、作成したアクションIDのハンドラーを実装します。 たとえば、別のサブスクリプションオファーや買い切り購入のセットがある場合、別のペイウォールを表示するボタンを追加できます。 ```kotlin override fun onActionPerformed(action: AdaptyUI.Action, context: Context) { when (action) { is AdaptyUI.Action.Custom -> { if (action.customId == "openNewPaywall") { // Display another paywall } } } } ``` --- # File: android-handling-events --- --- title: "Android - ペイウォールイベントの処理" description: "AdaptyのイベントトラッキングツールでAndroidのサブスクリプションイベントを効率的に処理しましょう。" --- :::important このガイドでは、購入・復元・プロダクト選択・ペイウォールレンダリングに関するイベント処理について説明します。ボタン操作(ペイウォールのクローズ、リンクを開くなど)も別途実装が必要です。詳しくは[ボタンアクションの処理ガイド](android-handle-paywall-actions)を参照してください。 ::: [ペイウォールビルダー](adapty-paywall-builder)で設定したペイウォールは、購入や復元のために追加のコードは不要です。ただし、アプリが対応できるいくつかのイベントが発生します。これらのイベントには、ボタン操作(閉じるボタン、URL、プロダクト選択など)や、ペイウォール上の購入関連アクションの通知が含まれます。以下でこれらのイベントへの対応方法を確認してください。 :::warning このガイドは、Adapty SDK v3.0以降が必要な**新しいペイウォールビルダーのペイウォール**専用です。 ::: :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 ::: 購入画面で発生する処理を制御・監視したい場合は、`AdaptyUiEventListener` のメソッドを実装してください。 一部のケースでデフォルトの動作を維持したい場合は、`AdaptyUiDefaultEventListener` を継承して、変更したいメソッドだけをオーバーライドできます。 以下は `AdaptyUiDefaultEventListener` のデフォルト実装です。 ### ユーザー起因のイベント \{#user-generated-events\} #### プロダクト選択 \{#product-selection\} プロダクトが購入のために選択された場合(ユーザーまたはシステムによる)、このメソッドが呼び出されます: ```kotlin showLineNumbers title="Kotlin" public override fun onProductSelected( product: AdaptyPaywallProduct, context: Context, ) {} ```
イベント例(クリックして展開) ```javascript { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } ```
#### 購入開始 \{#started-purchase\} ユーザーが購入プロセスを開始すると、このメソッドが呼び出されます: ```kotlin showLineNumbers title="Kotlin" public override fun onPurchaseStarted( product: AdaptyPaywallProduct, context: Context, ) {} ```
イベント例(クリックして展開) ```javascript { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } ```
このメソッドはObserverモードでは呼び出されません。詳しくは[Android - ObserverモードでのペイウォールビルダーペイウォールのPresent](android-present-paywall-builder-paywalls-in-observer-mode)を参照してください。 #### 購入成功・キャンセル・保留 \{#successful-canceled-or-pending-purchase\} 購入が成功すると、このメソッドが呼び出されます: ```kotlin showLineNumbers title="Kotlin" public override fun onPurchaseFinished( purchaseResult: AdaptyPurchaseResult, product: AdaptyPaywallProduct, context: Context, ) { if (purchaseResult !is AdaptyPurchaseResult.UserCanceled) context.getActivityOrNull()?.onBackPressed() } ```
イベント例(クリックして展開) ```javascript // Successful purchase { "purchaseResult": { "type": "Success", "profile": { "accessLevels": { "premium": { "id": "premium", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } } } }, "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } // Cancelled purchase { "purchaseResult": { "type": "UserCanceled" }, "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } // Pending purchase { "purchaseResult": { "type": "Pending" }, "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } ```
この場合は画面を閉じることをお勧めします。 このメソッドはObserverモードでは呼び出されません。詳しくは[Android - ObserverモードでのペイウォールビルダーペイウォールのPresent](android-present-paywall-builder-paywalls-in-observer-mode)を参照してください。 #### 購入失敗 \{#failed-purchase\} エラーにより購入が失敗した場合、このメソッドが呼び出されます。対象はGoogle Play Billing のエラー(支払い制限、無効なプロダクト、ネットワーク障害)、トランザクション検証失敗、システムエラーです。なお、ユーザーによるキャンセルはこのメソッドではなく `onPurchaseFinished` がキャンセル結果付きで呼び出され、保留中の支払いもこのメソッドは呼び出されません。 ```kotlin showLineNumbers title="Kotlin" public override fun onPurchaseFailure( error: AdaptyError, product: AdaptyPaywallProduct, context: Context, ) {} ```
イベント例(クリックして展開) ```javascript { "error": { "code": "purchase_failed", "message": "Purchase failed due to insufficient funds", "details": { "underlyingError": "Insufficient funds in account" } }, "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" } } ```
このメソッドはObserverモードでは呼び出されません。詳しくは[Android - ObserverモードでのペイウォールビルダーペイウォールのPresent](android-present-paywall-builder-paywalls-in-observer-mode)を参照してください。 #### Webペイメントナビゲーション完了 \{#finished-web-payment-navigation\} 特定のプロダクトに対して[Webペイウォール](web-paywall)を開こうとした後にこのメソッドが呼び出されます。ナビゲーションの成功・失敗どちらの場合も対象です: ```kotlin showLineNumbers title="Kotlin" public override fun onFinishWebPaymentNavigation( product: AdaptyPaywallProduct?, error: AdaptyError?, context: Context, ) {} ``` **パラメーター:** | パラメーター | 説明 | |:------------|:-----| | **product** | Webペイウォールが開かれた `AdaptyPaywallProduct`。`null` の場合があります。 | | **error** | Webペイウォールのナビゲーションが失敗した場合の `AdaptyError` オブジェクト。成功した場合は `null`。 |
イベント例(クリックして展開) ```javascript // Successful navigation { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "error": null } // Failed navigation { "product": { "vendorProductId": "premium_monthly", "localizedTitle": "Premium Monthly", "localizedDescription": "Premium subscription for 1 month", "localizedPrice": "$9.99", "price": 9.99, "currencyCode": "USD" }, "error": { "code": "web_navigation_failed", "message": "Failed to open web paywall", "details": { "underlyingError": "Browser unavailable" } } } ```
#### 購入復元成功 \{#successful-restore\} 購入の復元が成功すると、このメソッドが呼び出されます: ```kotlin showLineNumbers title="Kotlin" public override fun onRestoreSuccess( profile: AdaptyProfile, context: Context, ) {} ```
イベント例(クリックして展開) ```javascript { "profile": { "accessLevels": { "premium": { "id": "premium", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } }, "subscriptions": [ { "vendorProductId": "premium_monthly", "isActive": true, "expiresAt": "2024-02-15T10:30:00Z" } ] } } ```
ユーザーが必要な `accessLevel` を持っている場合は、画面を閉じることをお勧めします。確認方法については[サブスクリプションのステータス](android-listen-subscription-changes)を参照してください。 #### 購入復元失敗 \{#failed-restore\} `Adapty.restorePurchases()` が失敗した場合、このメソッドが呼び出されます: ```kotlin showLineNumbers title="Kotlin" public override fun onRestoreFailure( error: AdaptyError, context: Context, ) {} ```
イベント例(クリックして展開) ```javascript { "error": { "code": "restore_failed", "message": "Purchase restoration failed", "details": { "underlyingError": "No previous purchases found" } } } ```
#### サブスクリプションのアップグレード \{#upgrade-subscription\} ユーザーが別のサブスクリプションがアクティブな状態で新しいサブスクリプションを購入しようとした場合、このメソッドをオーバーライドして新しい購入の処理方法を制御できます。2つの選択肢があります: 1. **現在のサブスクリプションを新しいものに置き換える**: ```kotlin showLineNumbers title="Kotlin" public override fun onAwaitingPurchaseParams( product: AdaptyPaywallProduct, context: Context, onPurchaseParamsReceived: AdaptyUiEventListener.PurchaseParamsCallback, ): AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked { onPurchaseParamsReceived( AdaptyPurchaseParameters.Builder() .withSubscriptionUpdateParams(AdaptySubscriptionUpdateParameters(...)) .build() ) return AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked } ``` 2. **両方のサブスクリプションを維持する**(新しいものを別途追加する): ```kotlin showLineNumbers title="Kotlin" public override fun onAwaitingPurchaseParams( product: AdaptyPaywallProduct, context: Context, onPurchaseParamsReceived: AdaptyUiEventListener.PurchaseParamsCallback, ): AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked { onPurchaseParamsReceived(AdaptyPurchaseParameters.Empty) return AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked } ``` :::note このメソッドをオーバーライドしない場合、デフォルトの動作は両方のサブスクリプションをアクティブに維持します(`AdaptyPurchaseParameters.Empty` を使用した場合と同等です)。 ::: 必要に応じて追加の購入パラメーターを設定することもできます: ```kotlin AdaptyPurchaseParameters.Builder() .withSubscriptionUpdateParams(AdaptySubscriptionUpdateParameters(...)) // 任意 - 現在のサブスクリプションを置き換える場合 .withOfferPersonalized(true) // 任意 - パーソナライズされた価格設定を使用する場合 .build() ``` 別のサブスクリプションがアクティブな状態で新しいサブスクリプションが購入された場合、このメソッドをオーバーライドして現在のサブスクリプションを新しいものに置き換えます。アクティブなサブスクリプションをそのままにして新しいものを別途追加する場合は、`onSubscriptionUpdateParamsReceived(null)` を呼び出してください: ```kotlin showLineNumbers title="Kotlin" public override fun onAwaitingSubscriptionUpdateParams( product: AdaptyPaywallProduct, context: Context, onSubscriptionUpdateParamsReceived: SubscriptionUpdateParamsCallback, ) { onSubscriptionUpdateParamsReceived(AdaptySubscriptionUpdateParameters(...)) } ```
イベント例(クリックして展開) ```javascript { "product": { "vendorProductId": "premium_yearly", "localizedTitle": "Premium Yearly", "localizedDescription": "Premium subscription for 1 year", "localizedPrice": "$99.99", "price": 99.99, "currencyCode": "USD" }, "subscriptionUpdateParams": { "replacementMode": "with_time_proration" } } ```
### データ取得とレンダリング \{#data-fetching-and-rendering\} #### プロダクト読み込みエラー \{#product-loading-errors\} 初期化時にプロダクトを渡さない場合、AdaptyUI はサーバーから必要なオブジェクトを自動的に取得します。この操作が失敗した場合、AdaptyUI はこのメソッドを呼び出してエラーを通知します: ```kotlin showLineNumbers title="Kotlin" public override fun onLoadingProductsFailure( error: AdaptyError, context: Context, ): Boolean = false ```
イベント例(クリックして展開) ```javascript { "error": { "code": "products_loading_failed", "message": "Failed to load products from the server", "details": { "underlyingError": "Network timeout" } } } ```
`true` を返すと、AdaptyUI は2秒後にリクエストを再試行します。 #### レンダリングエラー \{#rendering-errors\} インターフェースのレンダリング中にエラーが発生した場合、このメソッドを呼び出して報告されます: ```kotlin showLineNumbers title="Kotlin" public override fun onRenderingError( error: AdaptyError, context: Context, ) {} ```
イベント例(クリックして展開) ```javascript { "error": { "code": "rendering_failed", "message": "Failed to render paywall interface", "details": { "underlyingError": "Invalid paywall configuration" } } } ```
通常の状況ではこのようなエラーは発生しないため、遭遇した場合はお知らせください。 --- # File: android-use-fallback-paywalls --- --- title: "Android - フォールバックペイウォールを使用する" description: "ユーザーがオフラインのとき、またはAdaptyサーバーが利用できないときのケースを処理します。" --- :::warning フォールバックペイウォールは Android SDK v2.11 以降でサポートされています。 ::: スムーズなユーザー体験を維持するために、フロー、[ペイウォール](paywalls)、[オンボーディング](onboardings)に[フォールバック](/fallback-paywalls)を設定することが重要です。この対策により、インターネット接続が部分的または完全に失われた場合でも、アプリケーションの機能を維持できます。 * **アプリケーションが Adapty サーバーにアクセスできない場合:** フォールバックのフローまたはペイウォールを表示し、ローカルのオンボーディング設定にアクセスできます。 * **アプリケーションがインターネットにアクセスできない場合:** フォールバックのフローまたはペイウォールを表示できます。オンボーディングはリモートコンテンツを含むため、動作にはインターネット接続が必要です。 :::important このガイドの手順を進める前に、Adapty からフォールバック設定ファイルを[ダウンロード](/local-fallback-paywalls)してください。 ::: ## 設定 \{#configuration\} 1. フォールバック設定ファイルをAndroidプロジェクトの `assets` または `res/raw` ディレクトリに移動します。 2. 対象のペイウォールまたはオンボーディングを取得する**前に** `.setFallback` メソッドを呼び出します。 ```kotlin showLineNumbers //if you put the 'android_fallback.json' file to the 'assets' directory val location = FileLocation.fromAsset("android_fallback.json") //or `FileLocation.fromAsset("/android_fallback.json")` if you placed it in a child folder of 'assets') //if you put the 'android_fallback.json' file to the 'res/raw' directory val location = FileLocation.fromResId(context, R.raw.android_fallback) //you can also pass a file URI val fileUri: Uri = //get Uri for the file with fallback paywalls val location = FileLocation.fromFileUri(fileUri) //pass the file location Adapty.setFallback(location, callback) ``` ```java showLineNumbers //if you put the 'android_fallback.json' file to the 'assets' directory FileLocation location = FileLocation.fromAsset("android_fallback.json"); //or `FileLocation.fromAsset("/android_fallback.json");` if you placed it in a child folder of 'assets') //if you put the 'android_fallback.json' file to the 'res/raw' directory FileLocation location = FileLocation.fromResId(context, R.raw.android_fallback); //you can also pass a file URI Uri fileUri = //get Uri for the file with fallback paywalls FileLocation location = FileLocation.fromFileUri(fileUri); //pass the file location Adapty.setFallback(location, callback); ``` パラメーター: | パラメーター | 説明 | | :----------- | :----------------------------------------------------------- | | **location** | フォールバック設定ファイルの [FileLocation](https://android.adapty.io/adapty/com.adapty.utils/-file-location/-companion/) オブジェクト | --- # File: android-localizations-and-locale-codes --- --- title: "Android SDKでローカライゼーションとロケールコードを使用する" description: "アプリのローカライゼーションとロケールコードを管理して、グローバルなユーザーにリーチしましょう(Android)。" --- ## なぜこれが重要なのか \{#why-this-is-important\} ロケールコードが関係するシナリオはいくつかあります。たとえば、アプリの現在のローカライゼーションに対応する正しいペイウォールを取得しようとする場合などです。 ロケールコードは複雑で、プラットフォームによって異なる場合があるため、Adapty ではサポートするすべてのプラットフォームに対して内部標準を採用しています。ただし、これらのコードが複雑であることから、サーバーに送信している内容と、その後の処理を正確に把握しておくことが非常に重要です。そうすることで、常に期待通りの結果を受け取れます。 ## Adapty のロケールコード標準 \{#locale-code-standard-at-adapty\} ロケールコードには、Adapty は若干修正した [BCP 47 標準](https://en.wikipedia.org/wiki/IETF_language_tag) を使用しています。各コードは小文字のサブタグで構成され、ハイフンで区切られます。例:`en`(英語)、`pt-br`(ポルトガル語(ブラジル))、`zh`(簡体字中国語)、`zh-hant`(繁体字中国語)。 ## ロケールコードのマッチング \{#locale-code-matching\} Adapty がクライアント側の SDK からロケールコードを含む呼び出しを受け取り、対応するペイウォールのローカライゼーションを探す際、以下の処理が行われます: 1. 受け取ったロケール文字列が小文字に変換され、アンダースコア(`_`)がすべてハイフン(`-`)に置き換えられます 2. 完全に一致するロケールコードを持つローカライゼーションを検索します 3. 一致するものが見つからない場合、最初のハイフンより前の部分文字列(`pt-br` の場合は `pt`)を取り出し、一致するローカライゼーションを検索します 4. それでも一致するものが見つからない場合、デフォルトの `en` ローカライゼーションを返します これにより、`'pt_BR'` を送信した iOS デバイス、`pt-BR` を送信した Android デバイス、`pt-br` を送信した別のデバイスはすべて同じ結果を受け取ります。 ## ローカライゼーションの実装:推奨方法 \{#implementing-localizations-recommended-way\} ローカライゼーションについて検討している場合、すでにプロジェクト内でローカライズされた文字列ファイルを扱っている可能性が高いです。その場合、各ローカライゼーションに対応するファイルに、意図した Adapty のロケールコードをキーと値のペアで設定しておくことをお勧めします。そして、SDK を呼び出す際にそのキーの値を取得します: ```kotlin showLineNumbers // 1. Modify your strings.xml files /* strings.xml - Spanish */ es /* strings.xml - Portuguese (Brazil) */ pt-br // 2. Extract and use the locale code val localeCode = context.getString(R.string.adapty_paywalls_locale) // pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall method ``` この方法により、アプリのすべてのユーザーに対してどのローカライゼーションが取得されるかを完全にコントロールできます。 ## ローカライゼーションの実装:別の方法 \{#implementing-localizations-the-other-way\} すべてのローカライゼーションに対してロケールコードを明示的に定義しなくても、似た結果(ただし完全に同一ではありません)を得ることができます。それは、プラットフォームが提供する他のオブジェクトからロケールコードを抽出する方法です: ```kotlin showLineNumbers val locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) context.resources.configuration.locales[0] else context.resources.configuration.locale val localeCode = locale.toLanguageTag() // pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall method ``` この方法は、Adapty のサーバーが受け取る内容を正確に予測することが難しいため、推奨していません。 それでもこの方法を使用する場合は、関連するすべてのユースケースに対応していることを確認してください。 --- # File: android-web-paywall --- --- title: "Android SDKでウェブペイウォールを実装する" description: "ウェブペイウォールを設定して、Playストアの手数料や審査なしで収益を得ましょう。" --- :::important 始める前に、[ダッシュボードでウェブペイウォールを設定](web-paywall)し、Adapty SDK バージョン 3.15 以降をインストールしていることを確認してください。 ::: ## ウェブペイウォールを開く \{#open-web-paywalls\} 自分で開発したペイウォールを使用している場合は、SDKメソッドを使ってウェブペイウォールを処理する必要があります。`.openWebPaywall` メソッドは以下を行います: 1. 固有のURLを生成し、特定のユーザーに表示されたペイウォールと、そのユーザーがリダイレクトされるウェブページをAdaptyが紐付けられるようにします。 2. ユーザーがアプリに戻るタイミングを追跡し、プロファイルのアクセス権が更新されたかどうかを確認するために、短い間隔で`.getProfile`をリクエストします。 これにより、支払いが成功してアクセス権が更新された場合、サブスクリプションはほぼ即座にアプリ内で有効になります。 :::note ユーザーがアプリに戻った後、プロファイルの更新を反映するためにUIを更新してください。AdaptyはプロファイルのUpdateイベントを受信して処理します。 ::: ```kotlin showLineNumbers Adapty.openWebPaywall( activity = activity, product = product, ) { error -> if (error == null) { // the web paywall was opened successfully } else { // handle the error } } ``` :::note `openWebPaywall` メソッドには2つのバージョンがあります: 1. `openWebPaywall(product)` — ペイウォールに基づいてURLを生成し、プロダクトデータもURLに追加します。 2. `openWebPaywall(paywall)` — ペイウォールに基づいてURLを生成しますが、プロダクトデータはURLに追加しません。Adaptyペイウォール内のプロダクトとウェブペイウォールのプロダクトが異なる場合に使用してください。 ::: ## アプリ内ブラウザでウェブペイウォールを開く \{#open-web-paywalls-in-an-in-app-browser\} デフォルトでは、ウェブペイウォールは外部ブラウザで開きます。 シームレスなユーザー体験を提供するために、アプリ内ブラウザでウェブペイウォールを開くことができます。これにより、アプリを切り替えることなく、アプリケーション内でウェブ購入ページを表示してトランザクションを完了できます。 これを有効にするには、`presentation` パラメータを `AdaptyWebPresentation.InAppBrowser` に設定します: ```kotlin showLineNumbers Adapty.openWebPaywall( activity = activity, product = product, presentation = AdaptyWebPresentation.InAppBrowser, ) { error -> if (error == null) { // the web paywall was opened successfully } else { // handle the error val adaptyError = error } } ``` --- # File: android-troubleshoot-paywall-builder --- --- title: "Android SDKでのペイウォールビルダーのトラブルシューティング" description: "Android SDKでのペイウォールビルダーのトラブルシューティング" --- このガイドでは、Android SDKでAdapty ペイウォールビルダーを使用して作成したペイウォールに関する一般的な問題の解決方法を説明します。 ## ペイウォール設定の取得に失敗する \{#getting-a-paywall-configuration-fails\} **問題**: `getViewConfiguration` メソッドがペイウォール設定の取得に失敗する。 **原因**: ペイウォールビルダーで、デバイスへの表示が有効になっていない。 **解決策**: ペイウォールビルダーの **Show on device** トグルを有効にしてください。 ## ペイウォールのビュー数が多すぎる \{#the-paywall-view-number-is-too-big\} **問題**: ペイウォールのビュー数が想定の2倍になっている。 **原因**: コード内で `logShowPaywall` を呼び出している可能性があります。ペイウォールビルダーを使用している場合、このメソッドを呼び出すとビュー数が重複して記録されます。ペイウォールビルダーで作成したペイウォールでは、アナリティクスが自動的に計測されるため、このメソッドを使用する必要はありません。 **解決策**: ペイウォールビルダーを使用している場合は、コード内で `logShowPaywall` を呼び出していないことを確認してください。 ## その他の問題 \{#other-issues\} **問題**: 上記以外のペイウォールビルダーに関連する問題が発生している。 **解決策**: 必要に応じて、[移行ガイド](android-sdk-migration-guides)を使用してSDKを最新バージョンに移行してください。多くの問題は新しいSDKバージョンで解決されています。 --- # File: android-quickstart-manual --- --- title: "Android SDKのカスタムペイウォールで購入機能を有効にする" description: "Adapty SDKをAndroidのカスタムペイウォールに統合してアプリ内課金を有効にします。" --- このガイドでは、Adaptyをカスタムペイウォールに統合する方法を説明します。ペイウォールの実装を完全にコントロールしながら、Adapty SDKがプロダクトの取得、新規購入の処理、過去の購入の復元を担当します。 :::important **このガイドはカスタムペイウォールを実装する開発者向けです。** 購入機能を最も簡単に有効にしたい場合は、[Adapty ペイウォールビルダー](android-quickstart-paywalls)をご利用ください。ペイウォールビルダーを使えば、ノーコードのビジュアルエディタでペイウォールを作成でき、すべての購入ロジックはAdaptyが自動的に処理します。アプリを再公開することなくデザインのテストも可能です。 ::: ## 始める前に \{#before-you-start\} ### プロダクトのセットアップ \{#set-up-products\} アプリ内課金を有効にするには、3つの重要な概念を理解する必要があります。 - [**プロダクト**](product) – ユーザーが購入できるもの(サブスクリプション、消耗型アイテム、永続アクセス) - [**ペイウォール**](paywalls) – どのプロダクトを提供するかを定義する設定。Adaptyでは、ペイウォールがプロダクトを取得する唯一の手段ですが、この設計によりアプリのコードを変更することなくプロダクト・価格・オファーを変更できます。 - [**プレースメント**](placements) – アプリのどこでどのタイミングでペイウォールを表示するか(`main`、`onboarding`、`settings`など)。ダッシュボードでプレースメントにペイウォールを設定し、コード内ではプレースメントIDで取得します。これにより、A/Bテストの実施や、ユーザーごとに異なるペイウォールの表示が簡単に行えます。 カスタムペイウォールを使用する場合でも、これらの概念を理解しておいてください。基本的には、アプリで販売するプロダクトを管理するための仕組みです。 カスタムペイウォールを実装するには、**ペイウォール**を作成して**プレースメント**に追加する必要があります。この設定によってプロダクトを取得できるようになります。ダッシュボードで必要な作業を理解するために、[こちら](quickstart)のクイックスタートガイドをご参照ください。 ### ユーザーの管理 \{#manage-users\} バックエンド認証の有無にかかわらず利用できます。 ただし、Adapty SDKは匿名ユーザーと識別済みユーザーを異なる方法で処理します。詳細を理解し、ユーザーを適切に扱うために、[識別クイックスタートガイド](android-quickstart-identify)をお読みください。 ## ステップ1. プロダクトを取得する \{#step-1-get-products\} カスタムペイウォール用のプロダクトを取得するには、次の手順が必要です。 1. `getPaywall`メソッドに[プレースメント](placements)IDを渡して`paywall`オブジェクトを取得する。 2. `getPaywallProducts`メソッドを使用して、このペイウォールのプロダクト配列を取得する。 ```kotlin showLineNumbers fun loadPaywall() { Adapty.getPaywall("YOUR_PLACEMENT_ID") { result -> when (result) { is AdaptyResult.Success -> { val paywall = result.value Adapty.getPaywallProducts(paywall) { productResult -> when (productResult) { is AdaptyResult.Success -> { val products = productResult.value // Use products to build your custom paywall UI } is AdaptyResult.Error -> { val error = productResult.error // Handle the error } } } } is AdaptyResult.Error -> { val error = result.error // Handle the error } } } } ``` ```java showLineNumbers public void loadPaywall() { Adapty.getPaywall("YOUR_PLACEMENT_ID", result -> { if (result instanceof AdaptyResult.Success) { AdaptyPaywall paywall = ((AdaptyResult.Success) result).getValue(); Adapty.getPaywallProducts(paywall, productResult -> { if (productResult instanceof AdaptyResult.Success) { List products = ((AdaptyResult.Success>) productResult).getValue(); // Use products to build your custom paywall UI } else if (productResult instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) productResult).getError(); // Handle the error } }); } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // Handle the error } }); } ``` ## ステップ2. 購入を受け付ける \{#step-2-accept-purchases\} カスタムペイウォールでユーザーがプロダクトをタップしたら、選択されたプロダクトを引数として`makePurchase`メソッドを呼び出します。これにより購入フローが処理され、更新されたプロファイルが返されます。 ```kotlin showLineNumbers fun purchaseProduct(activity: Activity, product: AdaptyPaywallProduct) { Adapty.makePurchase(activity, product) { result -> when (result) { is AdaptyResult.Success -> { when (val purchaseResult = result.value) { is AdaptyPurchaseResult.Success -> { val profile = purchaseResult.profile // Purchase successful, profile updated } is AdaptyPurchaseResult.UserCanceled -> { // User canceled the purchase } is AdaptyPurchaseResult.Pending -> { // Purchase is pending (e.g., user will pay offline with cash) } } } is AdaptyResult.Error -> { val error = result.error // Handle the error } } } } ``` ```java showLineNumbers public void purchaseProduct(Activity activity, AdaptyPaywallProduct product) { Adapty.makePurchase(activity, product, null, result -> { if (result instanceof AdaptyResult.Success) { AdaptyPurchaseResult purchaseResult = ((AdaptyResult.Success) result).getValue(); if (purchaseResult instanceof AdaptyPurchaseResult.Success) { AdaptyProfile profile = ((AdaptyPurchaseResult.Success) purchaseResult).getProfile(); // Purchase successful, profile updated } else if (purchaseResult instanceof AdaptyPurchaseResult.UserCanceled) { // User canceled the purchase } else if (purchaseResult instanceof AdaptyPurchaseResult.Pending) { // Purchase is pending (e.g., user will pay offline with cash) } } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // Handle the error } }); } ``` ## ステップ3. 購入を復元する \{#step-3-restore-purchases\} Google Playをはじめとするアプリストアでは、サブスクリプションを提供するすべてのアプリに対して、ユーザーが購入を復元できる手段を提供することを義務付けています。 ユーザーが復元ボタンをタップしたら`restorePurchases`メソッドを呼び出してください。これにより購入履歴がAdaptyと同期され、更新されたプロファイルが返されます。 ```kotlin showLineNumbers fun restorePurchases() { Adapty.restorePurchases { result -> when (result) { is AdaptyResult.Success -> { val profile = result.value // Restore successful, profile updated } is AdaptyResult.Error -> { val error = result.error // Handle the error } } } } ``` ```java showLineNumbers public void restorePurchases() { Adapty.restorePurchases(result -> { if (result instanceof AdaptyResult.Success) { AdaptyProfile profile = ((AdaptyResult.Success) result).getValue(); // Restore successful, profile updated } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // Handle the error } }); } ``` ## 次のステップ \{#next-steps\} --- no_index: true --- import Callout from '../../../components/Callout.astro'; ご質問やお困りのことがあれば、[サポートフォーラム](https://adapty.featurebase.app/)をご覧ください。よくある質問への回答を見つけたり、ご自身の質問を投稿することができます。チームとコミュニティがサポートいたします! ペイウォールをアプリに表示する準備が整いました。[Google Play Storeでの購入テスト](testing-on-android)を行い、ペイウォールからテスト購入が完了できることを確認してください。本番対応の実装例については、サンプルアプリの[ProductListFragment.kt](https://github.com/adaptyteam/AdaptySDK-Android/blob/master/app/src/main/java/com/adapty/example/ProductListFragment.kt)をご覧ください。適切なエラーハンドリング、UIフィードバック、サブスクリプション管理を含む購入処理のデモが確認できます。 次に、[ユーザーが購入を完了したかどうかを確認](android-check-subscription-status)し、ペイウォールを表示するか有料機能へのアクセスを許可するかを判断してください。 --- # File: fetch-paywalls-and-products-android --- --- title: "Android SDKでリモートコンフィグペイウォールのペイウォールとプロダクトを取得する" description: "Adapty Android SDKでペイウォールとプロダクトを取得して、ユーザーの収益化を強化します。" --- リモートコンフィグおよびカスタムペイウォールを表示する前に、それらに関する情報を取得する必要があります。このトピックはリモートコンフィグおよびカスタムペイウォールに関するものです。ペイウォールビルダーでカスタマイズされたペイウォールの取得方法については、[ペイウォールビルダーのペイウォールと設定の取得](android-get-pb-paywalls)を参照してください。 :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 :::
モバイルアプリでペイウォールとプロダクトの取得を始める前に(クリックして展開) 1. Adapty ダッシュボードで[プロダクトを作成](create-product)します。 2. Adapty ダッシュボードで[ペイウォールを作成し、プロダクトをペイウォールに組み込み](create-paywall)ます。 3. Adapty ダッシュボードで[プレースメントを作成し、ペイウォールをプレースメントに組み込み](create-placement)ます。 4. モバイルアプリに[Adapty SDKをインストール](sdk-installation-android)します。
## ペイウォール情報の取得 \{#fetch-paywall-information\} Adaptyでは、[プロダクト](product)はApp StoreとGoogle Play両方のプロダクトを組み合わせたものです。これらのクロスプラットフォームプロダクトはペイウォールに統合され、特定のモバイルアプリのプレースメント内で表示できます。 プロダクトを表示するには、`getPaywall`メソッドを使用して、いずれかの[プレースメント](placements)から[ペイウォール](paywalls)を取得する必要があります。 :::important **プロダクトIDをハードコーディングしないでください。** ハードコーディングすべき唯一のIDはプレースメントIDです。ペイウォールはリモートで設定されるため、プロダクトの数や利用可能なオファーはいつでも変更される可能性があります。アプリはこれらの変更を動的に処理する必要があります。今日ペイウォールが2つのプロダクトを返し、明日3つ返した場合、コードを変更せずにすべてを表示できるようにしてください。 ::: ```kotlin showLineNumbers Adapty.getPaywall("YOUR_PLACEMENT_ID", locale = "en") { result -> when (result) { is AdaptyResult.Success -> { val paywall = result.value // the requested paywall } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` ```java showLineNumbers Adapty.getPaywall("YOUR_PLACEMENT_ID", "en", result -> { if (result instanceof AdaptyResult.Success) { AdaptyPaywall paywall = ((AdaptyResult.Success) result).getValue(); // the requested paywall } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` | パラメータ | 必須/任意 | 説明 | |---------|--------|-----------| | **placementId** | 必須 | [プレースメント](placements)の識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。 | | **locale** |

任意

デフォルト: `en`

|

[ペイウォールのローカライゼーション](add-remote-config-locale)の識別子。このパラメータはマイナス(**-**)文字で区切られた1つ以上のサブタグで構成される言語コードであることが期待されます。最初のサブタグは言語、2番目は地域を表します。

例:`en`は英語、`pt-br`はブラジルポルトガル語を表します。

ロケールコードおよび推奨される使用方法については、[ローカライゼーションとロケールコード](android-localizations-and-locale-codes)を参照してください。

| | **fetchPolicy** | デフォルト: `.reloadRevalidatingCacheData` |

デフォルトでは、SDKはサーバーからデータを読み込もうとし、失敗した場合はキャッシュされたデータを返します。ユーザーが常に最新のデータを取得できるため、この方法を推奨します。

ただし、ユーザーが不安定なインターネット環境にある場合は、`.returnCacheDataElseLoad`を使用してキャッシュデータが存在する場合に返すことを検討してください。この場合、ユーザーは最新のデータを取得できない可能性がありますが、インターネット接続が不安定でも高速な読み込みを体験できます。キャッシュは定期的に更新されるため、ネットワークリクエストを避けるためにセッション中に使用しても安全です。

キャッシュはアプリの再起動後も保持され、アプリの再インストールまたは手動クリーンアップ時にのみクリアされます。

Adapty SDKはペイウォールを2つのレイヤーに保存します:上記の定期的に更新されるキャッシュと[フォールバックペイウォール](android-use-fallback-paywalls)です。また、CDNを使用してペイウォールをより速く取得し、CDNに到達できない場合のスタンドアロンフォールバックサーバーも使用します。このシステムは、インターネット接続が不安定な場合でも常にペイウォールの最新バージョンを取得できるよう設計されています。

| | **loadTimeout** | デフォルト: 5秒 |

この値はこのメソッドのタイムアウトを制限します。タイムアウトに達した場合、キャッシュされたデータまたはローカルフォールバックが返されます。

まれに、処理が内部で複数のリクエストで構成される場合があるため、このメソッドは`loadTimeout`で指定した時間よりわずかに遅くタイムアウトする場合があります。

| プロダクトIDをハードコーディングしないでください!ペイウォールはリモートで設定されるため、利用可能なプロダクト、プロダクト数、特別オファー(無料トライアルなど)は時間とともに変更される可能性があります。これらのシナリオをコードで処理してください。 例えば、最初に2つのプロダクトを取得した場合、アプリはその2つを表示する必要があります。その後3つのプロダクトを取得した場合、コードを変更せずに3つすべてを表示する必要があります。ハードコーディングが必要なのはプレースメントIDだけです。 レスポンスパラメータ: | パラメータ | 説明 | | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | | Paywall | プロダクトIDのリスト、ペイウォール識別子、リモートコンフィグ、その他いくつかのプロパティを含む[`AdaptyPaywall`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/)オブジェクト。 | ## プロダクトの取得 \{#fetch-products\} ペイウォールを取得したら、それに対応するプロダクト配列を照会できます: ```kotlin showLineNumbers Adapty.getPaywallProducts(paywall) { result -> when (result) { is AdaptyResult.Success -> { val products = result.value // the requested products } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` ```java showLineNumbers Adapty.getPaywallProducts(paywall, result -> { if (result instanceof AdaptyResult.Success) { List products = ((AdaptyResult.Success>) result).getValue(); // the requested products } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` レスポンスパラメータ: | パラメータ | 説明 | | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Products | プロダクト識別子、プロダクト名、価格、通貨、サブスクリプション期間、その他いくつかのプロパティを含む[`AdaptyPaywallProduct`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall-product/)オブジェクトのリスト。 | 独自のペイウォールデザインを実装する場合、[`AdaptyPaywallProduct`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall-product/)オブジェクトのこれらのプロパティにアクセスする必要があるでしょう。以下によく使用されるプロパティを示しますが、利用可能なすべてのプロパティの詳細については、リンクされたドキュメントを参照してください。 | プロパティ | 説明 | |-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Title** | プロダクトのタイトルを表示するには、`product.localizedTitle`を使用します。ローカライゼーションはデバイス自体のロケールではなく、ユーザーが選択したストアの国に基づいています。 | | **Price** | ローカライズされた価格を表示するには、`product.price.localizedString`を使用します。このローカライゼーションはデバイスのロケール情報に基づいています。`product.price.amount`を使用して数値として価格にアクセスすることもできます。値はローカル通貨で提供されます。関連する通貨記号を取得するには、`product.price.currencySymbol`を使用します。 | | **Subscription Period** | 期間(週、月、年など)を表示するには、`product.subscriptionDetails?.localizedSubscriptionPeriod`を使用します。このローカライゼーションはデバイスのロケールに基づいています。プログラムでサブスクリプション期間を取得するには、`product.subscriptionDetails?.subscriptionPeriod`を使用します。そこから`unit`列挙型にアクセスして期間の長さ(DAY、WEEK、MONTH、YEAR、またはUNKNOWN)を取得できます。`numberOfUnits`の値で期間単位の数を取得できます。例えば、四半期ごとのサブスクリプションの場合、unitプロパティに`MONTH`、numberOfUnitsプロパティに`3`が表示されます。 | | **Introductory Offer** | サブスクリプションに初回オファーが含まれているかどうかを示すバッジやインジケーターを表示するには、`product.subscriptionDetails?.introductoryOfferPhases`プロパティを確認してください。これは最大2つの割引フェーズ(無料トライアルフェーズと初回価格フェーズ)を含めることができるリストです。各フェーズオブジェクト内には以下の役立つプロパティがあります:
• `paymentMode`:`FREE_TRIAL`、`PAY_AS_YOU_GO`、`PAY_UPFRONT`、`UNKNOWN`の値を持つ列挙型。無料トライアルは`FREE_TRIAL`タイプになります。
• `price`:数値としての割引価格。無料トライアルの場合は`0`を探してください。
• `localizedNumberOfPeriods`:オファーの期間を説明するデバイスのロケールを使用してローカライズされた文字列。例えば、3日間のトライアルオファーはこのフィールドに`3 days`と表示されます。
• `subscriptionPeriod`:または、このプロパティでオファー期間の個別の詳細を取得できます。オファーに対しては前のセクションで説明したのと同じ方法で機能します。
• `localizedSubscriptionPeriod`:ユーザーのロケールに対してフォーマットされた割引のサブスクリプション期間。 | ## デフォルトオーディエンスのペイウォールでペイウォール取得を高速化する \{#speed-up-paywall-fetching-with-default-audience-paywall\} 通常、ペイウォールはほぼ即座に取得されるため、このプロセスの高速化を心配する必要はありません。ただし、オーディエンスとペイウォールが多数あり、ユーザーのインターネット接続が弱い場合、ペイウォールの取得に予想以上に時間がかかることがあります。そのような状況では、ペイウォールをまったく表示しないよりもスムーズなユーザー体験を確保するために、デフォルトのペイウォールを表示したい場合があります。 これに対処するため、`getPaywallForDefaultAudience`メソッドを使用できます。このメソッドは、**All Users**オーディエンス向けに指定されたプレースメントのペイウォールを取得します。ただし、上記の[ペイウォール情報の取得](fetch-paywalls-and-products-android#fetch-paywall-information)セクションで詳述されているように、推奨されるアプローチは`getPaywall`メソッドでペイウォールを取得することであることを理解することが重要です。 :::warning `getPaywall`を推奨する理由 `getPaywallForDefaultAudience`メソッドにはいくつかの重大な欠点があります: - **後方互換性の問題の可能性**:現在および将来のアプリバージョンで異なるペイウォールを表示する必要がある場合、課題に直面する可能性があります。現在の(レガシー)バージョンをサポートするペイウォールを設計するか、現在の(レガシー)バージョンのユーザーがレンダリングされないペイウォールに問題が発生する可能性を受け入れる必要があります。 - **ターゲティングの喪失**:すべてのユーザーが**All Users**オーディエンス向けに設計された同じペイウォールを表示するため、パーソナライズされたターゲティング(国、マーケティングアトリビューション、独自のカスタム属性に基づくものを含む)が失われます。 これらの欠点を受け入れてペイウォール取得の高速化の恩恵を受けたい場合は、以下のように`getPaywallForDefaultAudience`メソッドを使用してください。そうでない場合は、[上記](#fetch-paywall-information)で説明した`getPaywall`を使用してください。 ::: ```kotlin showLineNumbers Adapty.getPaywallForDefaultAudience("YOUR_PLACEMENT_ID", locale = "en") { result -> when (result) { is AdaptyResult.Success -> { val paywall = result.value // the requested paywall } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` ```java showLineNumbers Adapty.getPaywallForDefaultAudience("YOUR_PLACEMENT_ID", "en", result -> { if (result instanceof AdaptyResult.Success) { AdaptyPaywall paywall = ((AdaptyResult.Success) result).getValue(); // the requested paywall } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` :::note `getPaywallForDefaultAudience`メソッドはAndroid SDKバージョン2.11.3以降から利用可能です。 ::: | パラメータ | 必須/任意 | 説明 | |---------|--------|-----------| | **placementId** | 必須 | [プレースメント](placements)の識別子。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。 | | **locale** |

任意

デフォルト: `en`

|

[ペイウォールのローカライゼーション](add-remote-config-locale)の識別子。このパラメータはマイナス(**-**)文字で区切られた1つ以上のサブタグで構成される言語コードであることが期待されます。最初のサブタグは言語、2番目は地域を表します。

例:`en`は英語、`pt-br`はブラジルポルトガル語を表します。

ロケールコードおよび推奨される使用方法については、[ローカライゼーションとロケールコード](android-localizations-and-locale-codes)を参照してください。

| | **fetchPolicy** | デフォルト: `.reloadRevalidatingCacheData` |

デフォルトでは、SDKはサーバーからデータを読み込もうとし、失敗した場合はキャッシュされたデータを返します。ユーザーが常に最新のデータを取得できるため、この方法を推奨します。

ただし、ユーザーが不安定なインターネット環境にある場合は、`.returnCacheDataElseLoad`を使用してキャッシュデータが存在する場合に返すことを検討してください。この場合、ユーザーは最新のデータを取得できない可能性がありますが、インターネット接続が不安定でも高速な読み込みを体験できます。キャッシュは定期的に更新されるため、ネットワークリクエストを避けるためにセッション中に使用しても安全です。

キャッシュはアプリの再起動後も保持され、アプリの再インストールまたは手動クリーンアップ時にのみクリアされます。

| --- # File: present-remote-config-paywalls-android --- --- title: "Android SDKでリモートコンフィグで設計されたペイウォールを表示する" description: "Adapty Android SDKでリモートコンフィグペイウォールを表示してユーザー体験をパーソナライズする方法を解説します。" --- リモートコンフィグを使用してペイウォールをカスタマイズした場合、ユーザーに表示するためにモバイルアプリのコードでレンダリングを実装する必要があります。リモートコンフィグは柔軟にカスタマイズできるため、何を含めるか、またペイウォールのビューをどのように表示するかはすべて自分で制御できます。リモートコンフィグ経由で設定したカスタムペイウォールを表示するために、リモート設定を取得するメソッドを提供しています。 ## ペイウォールのリモートコンフィグを取得して表示する \{#get-paywall-remote-config-and-present-it\} ペイウォールのリモートコンフィグを取得するには、`remoteConfig` プロパティにアクセスして必要な値を取り出します。 ```kotlin showLineNumbers Adapty.getPaywall("YOUR_PLACEMENT_ID") { result -> when (result) { is AdaptyResult.Success -> { val paywall = result.value val headerText = paywall.remoteConfig?.dataMap?.get("header_text") as? String } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` ```java showLineNumbers Adapty.getPaywall("YOUR_PLACEMENT_ID", result -> { if (result instanceof AdaptyResult.Success) { AdaptyPaywall paywall = ((AdaptyResult.Success) result).getValue(); AdaptyPaywall.RemoteConfig remoteConfig = paywall.getRemoteConfig(); if (remoteConfig != null) { if (remoteConfig.getDataMap().get("header_text") instanceof String) { String headerText = (String) remoteConfig.getDataMap().get("header_text"); } } } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` 必要な値をすべて取得したら、それらをレンダリングして視覚的に魅力的なページに組み立てます。さまざまなスマートフォンの画面サイズや向きに対応したデザインにし、あらゆるデバイスでシームレスで使いやすい体験を提供してください。 :::warning [ペイウォール表示イベントの記録](present-remote-config-paywalls-android#track-paywall-view-events)を以下の手順に従って必ず行ってください。これにより、Adapty アナリティクスがファネルおよび A/B テストの情報を収集できるようになります。 ::: ペイウォールの表示が完了したら、購入フローの設定に進みます。ユーザーが購入する際は、ペイウォールのプロダクトを使用して `.makePurchase()` を呼び出すだけです。`.makePurchase()` メソッドの詳細については、[購入の実行](android-making-purchases)をご覧ください。 インターネット接続がない場合やキャッシュが利用できない場合でもスムーズな体験を保証するために、[フォールバックペイウォールと呼ばれるバックアップペイウォールの作成](android-use-fallback-paywalls)をお勧めします。 ## ペイウォール表示イベントを記録する \{#track-paywall-view-events\} Adapty はペイウォールのパフォーマンス測定をサポートしています。購入データは自動的に収集されますが、ペイウォールの表示ログはお客様自身が記録する必要があります。ユーザーがペイウォールを見るタイミングを把握しているのはお客様だけだからです。 ペイウォール表示イベントを記録するには、`.logShowPaywall(paywall)` を呼び出すだけです。これにより、ファネルや A/B テストのペイウォール指標に反映されます。 :::important [ペイウォールビルダー](adapty-paywall-builder)で作成したペイウォールを表示している場合は、`.logShowPaywall(paywall)` を呼び出す必要はありません。 ::: ```kotlin showLineNumbers Adapty.logShowPaywall(paywall) ``` リクエストパラメーター: | パラメーター | 必須 | 説明 | | :---------- | :------- |:------------------------------------------------------------------------------------------------------------| | **paywall** | 必須 | [`AdaptyPaywall`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/) オブジェクト。 | --- # File: android-making-purchases --- --- title: "Android SDKでモバイルアプリのアプリ内課金を行う" description: "Adaptyを使ってアプリ内課金とサブスクリプションを処理するガイド。" --- モバイルアプリにペイウォールを表示することは、ユーザーにプレミアムコンテンツやサービスへのアクセスを提供するうえで欠かせないステップです。ただし、[ペイウォールビルダー](adapty-paywall-builder)を使ってペイウォールをカスタマイズしている場合に限り、ペイウォールを表示するだけで購入処理を完結できます。 ペイウォールビルダーを使用しない場合は、`.makePurchase()` という別のメソッドを使って購入を完了し、目的のコンテンツを解放する必要があります。このメソッドは、ユーザーがペイウォールを通じて希望のトランザクションを進めるための入口となります。 ペイウォールに、ユーザーが購入しようとしているプロダクトに対して有効なプロモーションオファーが設定されている場合、Adapty は購入時に自動的にそのオファーを適用します。 :::warning 初回オファーは、ペイウォールビルダーで設定したペイウォールを使用している場合にのみ自動的に適用されることに注意してください。 それ以外の場合は、[iOSで初回オファーの適用資格を確認する](fetch-paywalls-and-products#check-intro-offer-eligibility-on-ios)必要があります。このステップを省略すると、リリース時にアプリが審査でリジェクトされる可能性があります。さらに、初回オファーの対象ユーザーに通常価格が請求されてしまう恐れもあります。 ::: [初期設定](quickstart)を一つも省かずに完了させていることを確認してください。設定が完了していないと、購入の検証ができません。 ## 購入を行う \{#make-purchase\} :::note **[ペイウォールビルダー](adapty-paywall-builder)をお使いですか?** 購入は自動的に処理されるため、このステップはスキップできます。 **ステップバイステップのガイドをお探しですか?** 全体のコンテキストを含む実装手順については、[クイックスタートガイド](android-implement-paywalls-manually)をご確認ください。 ::: ```kotlin showLineNumbers Adapty.makePurchase(activity, product, null) { result -> when (result) { is AdaptyResult.Success -> { when (val purchaseResult = result.value) { is AdaptyPurchaseResult.Success -> { val profile = purchaseResult.profile if (profile.accessLevels["YOUR_ACCESS_LEVEL"]?.isActive == true) { // Grant access to the paid features } } is AdaptyPurchaseResult.UserCanceled -> { // Handle the case where the user canceled the purchase } is AdaptyPurchaseResult.Pending -> { // Handle deferred purchases (e.g., the user will pay offline with cash) } } } is AdaptyResult.Error -> { val error = result.error // Handle the error } } } ``` ```java showLineNumbers Adapty.makePurchase(activity, product, null, result -> { if (result instanceof AdaptyResult.Success) { AdaptyPurchaseResult purchaseResult = ((AdaptyResult.Success) result).getValue(); if (purchaseResult instanceof AdaptyPurchaseResult.Success) { AdaptyProfile profile = ((AdaptyPurchaseResult.Success) purchaseResult).getProfile(); AdaptyProfile.AccessLevel premium = profile.getAccessLevels().get("YOUR_ACCESS_LEVEL"); if (premium != null && premium.isActive()) { // Grant access to the paid features } } else if (purchaseResult instanceof AdaptyPurchaseResult.UserCanceled) { // Handle the case where the user canceled the purchase } else if (purchaseResult instanceof AdaptyPurchaseResult.Pending) { // Handle deferred purchases (e.g., the user will pay offline with cash) } } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // Handle the error } }); ``` リクエストパラメータ: | パラメータ | 必須 | 説明 | | :---------- | :------- | :-------------------------------------------------------------------------------------------------- | | **Product** | 必須 | ペイウォールから取得した [`AdaptyPaywallProduct`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall-product/) オブジェクト。 | レスポンスパラメータ: | パラメータ | 説明 | |---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Profile** |

リクエストが成功した場合、レスポンスにはこのオブジェクトが含まれます。[AdaptyProfile](https://android.adapty.io/adapty/com.adapty.models/-adapty-profile/) オブジェクトは、アプリ内のユーザーのアクセスレベル、サブスクリプション、および買い切り購入に関する包括的な情報を提供します。

アクセスレベルのステータスを確認して、ユーザーがアプリへの必要なアクセス権を持っているかどうかを確認してください。

| :::warning **注意:** Apple の StoreKit バージョンが v2.0 未満で、Adapty SDK バージョンが v2.9.0 未満の場合は、代わりに [Apple App Store 共有シークレット](app-store-connection-configuration#step-5-enter-app-store-shared-secret)を提供する必要があります。この方法は現在 Apple によって非推奨とされています。 ::: ## 購入時にサブスクリプションを変更する \{#change-subscription-when-making-a-purchase\} ユーザーが現在のサブスクリプションを更新する代わりに新しいサブスクリプションを選択した場合、その動作はアプリストアによって異なります。Google Play では、サブスクリプションは自動的に更新されません。以下に説明するように、モバイルアプリのコードで切り替えを管理する必要があります。 Android でサブスクリプションを別のものに変更するには、追加パラメータを指定して `.makePurchase()` メソッドを呼び出します: ```kotlin showLineNumbers Adapty.makePurchase( activity, product, AdaptyPurchaseParameters.Builder() .withSubscriptionUpdateParams(subscriptionUpdateParams) .build() ) { result -> when (result) { is AdaptyResult.Success -> { when (val purchaseResult = result.value) { is AdaptyPurchaseResult.Success -> { val profile = purchaseResult.profile // successful cross-grade } is AdaptyPurchaseResult.UserCanceled -> { // user canceled the purchase flow } is AdaptyPurchaseResult.Pending -> { // the purchase has not been finished yet, e.g. user will pay offline by cash } } } is AdaptyResult.Error -> { val error = result.error // Handle the error } } } ``` 追加リクエストパラメータ: | パラメータ | 必須 | 説明 | | :--------------------------- | :------- | :----------------------------------------------------------- | | **subscriptionUpdateParams** | 必須 | [`AdaptySubscriptionUpdateParameters`](https://android.adapty.io/adapty/com.adapty.models/-adapty-subscription-update-parameters/) オブジェクト。 | ```java showLineNumbers Adapty.makePurchase( activity, product, new AdaptyPurchaseParameters.Builder() .withSubscriptionUpdateParams(subscriptionUpdateParams) .build(), result -> { if (result instanceof AdaptyResult.Success) { AdaptyPurchaseResult purchaseResult = ((AdaptyResult.Success) result).getValue(); if (purchaseResult instanceof AdaptyPurchaseResult.Success) { AdaptyProfile profile = ((AdaptyPurchaseResult.Success) purchaseResult).getProfile(); // successful cross-grade } else if (purchaseResult instanceof AdaptyPurchaseResult.UserCanceled) { // user canceled the purchase flow } else if (purchaseResult instanceof AdaptyPurchaseResult.Pending) { // the purchase has not been finished yet, e.g. user will pay offline by cash } } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // Handle the error } }); ``` 追加リクエストパラメータ: | パラメータ | 必須 | 説明 | | :--------------------------- | :------- | :----------------------------------------------------------- | | **subscriptionUpdateParams** | 必須 | [`AdaptySubscriptionUpdateParameters`](https://android.adapty.io/adapty/com.adapty.models/-adapty-subscription-update-parameters/) オブジェクト。 | サブスクリプションと置き換えモードの詳細については、Google Developer のドキュメントをご覧ください: - [置き換えモードについて](https://developer.android.com/google/play/billing/subscriptions#replacement-modes) - [置き換えモードに関する Google の推奨事項](https://developer.android.com/google/play/billing/subscriptions#replacement-recommendations) - 置き換えモード [`CHARGE_PRORATED_PRICE`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode#CHARGE_PRORATED_PRICE())。注意:このメソッドはサブスクリプションのアップグレードにのみ利用可能です。ダウングレードはサポートされていません。 - 置き換えモード [`DEFERRED`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode#DEFERRED())。注意:実際のサブスクリプション変更は、現在のサブスクリプションの請求期間が終了した時点でのみ発生します。 ### プリペイドプランを管理する \{#manage-prepaid-plans\} アプリユーザーが[プリペイドプラン](https://developer.android.com/google/play/billing/subscriptions#prepaid-plans)(例:数ヶ月分の非自動更新サブスクリプションを購入)を利用できる場合、プリペイドプランの[保留中のトランザクション](https://developer.android.com/google/play/billing/subscriptions#pending)を有効にできます。 ```kotlin showLineNumbers AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withEnablePendingPrepaidPlans(true) .build() ``` ```java showLineNumbers new AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withEnablePendingPrepaidPlans(true) .build(); ``` --- # File: android-restore-purchase --- --- title: "Android SDKで購入を復元する" description: "Adaptyで購入を復元し、シームレスなユーザー体験を実現する方法を学びましょう。" --- 購入の復元は、サブスクリプションやアプリ内課金などの購入済みコンテンツに、再度課金されることなくアクセスを取り戻せる機能です。アプリをアンインストールして再インストールしたユーザーや、新しいデバイスに乗り換えたユーザーが、以前の購入コンテンツに再び支払いなしでアクセスしたい場合に特に役立ちます。 :::note [ペイウォールビルダー](adapty-paywall-builder)で作成したペイウォールでは、追加のコードなしで購入が自動的に復元されます。その場合は、このステップをスキップできます。 ::: [ペイウォールビルダー](adapty-paywall-builder)を使ってペイウォールをカスタマイズしていない場合に購入を復元するには、`.restorePurchases()` メソッドを呼び出してください。 ```kotlin showLineNumbers Adapty.restorePurchases { result -> when (result) { is AdaptyResult.Success -> { val profile = result.value if (profile.accessLevels["YOUR_ACCESS_LEVEL"]?.isActive == true) { // successful access restore } } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` ```java showLineNumbers Adapty.restorePurchases(result -> { if (result instanceof AdaptyResult.Success) { AdaptyProfile profile = ((AdaptyResult.Success) result).getValue(); if (profile != null) { AdaptyProfile.AccessLevel premium = profile.getAccessLevels().get("YOUR_ACCESS_LEVEL"); if (premium != null && premium.isActive()) { // successful access restore } } } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` レスポンスパラメータ: | パラメータ | 説明 | |---------|-----------| | **Profile** |

[`AdaptyProfile`](https://android.adapty.io/adapty/com.adapty.models/-adapty-profile/) オブジェクト。このモデルにはアクセスレベル、サブスクリプション、買い切り購入に関する情報が含まれています。

ユーザーがアプリへのアクセス権を持っているかどうかを判断するには、**アクセスレベルのステータス**を確認してください。

| :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 ::: --- # File: implement-observer-mode-android --- --- title: "Android SDKにオブザーバーモードを実装する" description: "Android SDKでAdaptyのオブザーバーモードを実装し、ユーザーのサブスクリプションイベントを追跡します。" --- すでに独自の購入インフラがあり、Adaptyへの完全な移行を検討していない場合は、[オブザーバーモード](observer-vs-full-mode)を検討してみてください。基本的な機能として、オブザーバーモードは高度なアナリティクスと、アトリビューションおよびアナリティクスシステムとのシームレスな連携を提供します。 これで十分な場合、必要な作業は以下の2つだけです: 1. `observerMode` パラメータを `true` に設定して、Adapty SDKの設定時にオブザーバーモードを有効化する。[Android](sdk-installation-android#activate-adapty-module-of-adapty-sdk)のセットアップ手順を参照してください。 2. 既存の購入インフラから[トランザクションをAdaptyに報告する](report-transactions-observer-mode-android)。 ## オブザーバーモードのセットアップ \{#observer-mode-setup\} 購入とサブスクリプションのステータスを自分で管理し、サブスクリプションイベントとアナリティクスの送信にAdaptyを使用する場合は、オブザーバーモードを有効にしてください。 :::important オブザーバーモードで動作している場合、Adapty SDKはトランザクションをクローズしません。そのため、ご自身でトランザクションを処理するようにしてください。 ::: ```kotlin showLineNumbers class MyApplication : Application() { override fun onCreate() { super.onCreate() Adapty.activate( applicationContext, AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withObserverMode(true) //default false .build() ) } ``` ```java showLineNumbers public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); Adapty.activate( applicationContext, new AdaptyConfig.Builder("PUBLIC_SDK_KEY") .withObserverMode(true) //default false .build() ); } ``` パラメータ: | パラメータ | 説明 | | --------------------------- | ------------------------------------------------------------ | | observerMode | [オブザーバーモード](observer-vs-full-mode)を制御するboolean値。デフォルト値は `false` です。 | ## オブザーバーモードでAdaptyのペイウォールを使用する \{#using-adapty-paywalls-in-observer-mode\} Adaptyのペイウォールとそれを利用したA/Bテスト機能も使用したい場合は可能ですが、オブザーバーモードでは追加の設定が必要です。上記の手順に加えて、以下の作業が必要です: 1. [リモートコンフィグペイウォール](present-remote-config-paywalls-android)の場合は通常通りペイウォールを表示する。ペイウォールビルダーのペイウォールについては、[Android](android-present-paywall-builder-paywalls-in-observer-mode)の専用セットアップガイドを参照してください。 3. 購入トランザクションに[ペイウォールを関連付ける](report-transactions-observer-mode-android)。 --- # File: report-transactions-observer-mode-android --- --- title: "Android SDKのオブザーバーモードでトランザクションを報告する" description: "Android SDKのAdaptyオブザーバーモードで購入トランザクションを報告し、ユーザーインサイトと収益トラッキングを行います。" --- オブザーバーモードでは、Adapty SDKは既存の購入システムを通じて行われた購入を自動的に追跡できません。アプリストアからのトランザクションを自分で報告する必要があります。アナリティクスのエラーを防ぐため、アプリをリリースする**前に**この設定を完了しておくことが重要です。 各トランザクションをAdaptyに明示的に報告するには、`reportTransaction`を使用してください。 :::warning **トランザクションの報告をスキップしないでください!** `reportTransaction`を呼び出さない場合、Adaptyはそのトランザクションを認識できず、アナリティクスに表示されず、インテグレーションにも送信されません。 ::: Adaptyのペイウォールを使用している場合は、トランザクションを報告する際に`variationId`を含めてください。これにより、購入がトリガーとなったペイウォールに紐付けられ、正確なペイウォールアナリティクスが確保されます。 ```kotlin showLineNumbers val transactionInfo = TransactionInfo.fromPurchase(purchase) Adapty.reportTransaction(transactionInfo, variationId) { result -> if (result is AdaptyResult.Success) { // success } } ``` パラメーター: | パラメーター | 必須/任意 | 説明 | | --------------- | --------- | ------------------------------------------------------------ | | transactionInfo | 必須 | 購入からのTransactionInfoです。purchaseはBillingライブラリの[Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase)クラスのインスタンスです。 | | variationId | 任意 | バリアントの文字列識別子です。[AdaptyPaywall](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/)オブジェクトの`variationId`プロパティを使用して取得できます。 | ```java showLineNumbers TransactionInfo transactionInfo = TransactionInfo.fromPurchase(purchase); Adapty.reportTransaction(transactionInfo, variationId, result -> { if (result instanceof AdaptyResult.Success) { // success } }); ``` パラメーター: | パラメーター | 必須/任意 | 説明 | | --------------- | --------- | ------------------------------------------------------------ | | transactionInfo | 必須 | 購入からのTransactionInfoです。purchaseはBillingライブラリの[Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase)クラスのインスタンスです。 | | variationId | 任意 | バリアントの文字列識別子です。[AdaptyPaywall](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/)オブジェクトの`variationId`プロパティを使用して取得できます。 | オブザーバーモードでは、Adapty SDKは既存の購入システムを通じて行われた購入を自動的に追跡できません。アプリストアからのトランザクションを報告するか、復元する必要があります。アナリティクスのエラーを防ぐため、アプリをリリースする**前に**この設定を完了しておくことが重要です。 トランザクションをAdaptyに報告するには、`restorePurchases`を使用してください。 :::warning **購入の復元をスキップしないでください!** `restorePurchases`を呼び出さない場合、Adaptyはそのトランザクションを認識できず、アナリティクスに表示されず、インテグレーションにも送信されません。 ::: Adaptyのペイウォールを使用している場合は、`setVariationId`メソッドを使用して、トランザクションを購入のきっかけとなったペイウォールに紐付けてください。これにより、正確なアナリティクスのために購入がトリガーとなったペイウォールに正しく関連付けられます。この手順は、Adaptyのペイウォールを使用している場合にのみ必要です。 ```kotlin showLineNumbers Adapty.restorePurchases { result -> if (result is AdaptyResult.Success) { // success } } Adapty.setVariationId(transactionId, variationId) { error -> if (error == null) { // success } } ``` パラメーター: | パラメーター | 必須/任意 | 説明 | | ------------- | --------- | ------------------------------------------------------------ | | transactionId | 必須 | 購入の文字列識別子(`purchase.getOrderId`)です。purchaseはBillingライブラリの[Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase)クラスのインスタンスです。 | | variationId | 必須 | バリアントの文字列識別子です。[AdaptyPaywall](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/)オブジェクトの`variationId`プロパティを使用して取得できます。 | ```java showLineNumbers Adapty.restorePurchases(result -> { if (result instanceof AdaptyResult.Success) { // success } }); Adapty.setVariationId(transactionId, variationId, error -> { if (error == null) { // success } }); ``` パラメーター: | パラメーター | 必須/任意 | 説明 | | ------------- | --------- | ------------------------------------------------------------ | | transactionId | 必須 | 購入の文字列識別子(`purchase.getOrderId`)です。purchaseはBillingライブラリの[Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase)クラスのインスタンスです。 | | variationId | 必須 | バリアントの文字列識別子です。[AdaptyPaywall](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/)オブジェクトの`variationId`プロパティを使用して取得できます。 | **トランザクションの報告** オブザーバーモードでAdaptyにトランザクションを報告するには、[モバイルコードでの購入の復元](android-restore-purchase)ページで説明されているように`restorePurchases`を使用してください。 :::warning **トランザクションの報告をスキップしないでください!** `restorePurchases`を呼び出さない場合、Adaptyはそのトランザクションを認識できず、アナリティクスに表示されず、インテグレーションにも送信されません。 ::: **ペイウォールとトランザクションの関連付け** Adapty SDKは購入の発生元を判断できません。購入の処理はあなた自身が行うためです。そのため、オブザーバーモードでペイウォールやA/B テストを使用する場合は、アプリストアからのトランザクションをモバイルアプリのコード内で対応するペイウォールに関連付ける必要があります。アプリのリリース前にこれを正しく設定しておくことが重要です。設定しないと、アナリティクスにエラーが発生します。 ```kotlin Adapty.setVariationId(transactionId, variationId) { error -> if (error == null) { // success } } ``` リクエストパラメーター: | パラメーター | 必須/任意 | 説明 | | ------------- | --------- | ------------------------------------------------------------ | | transactionId | 必須 | 購入の文字列識別子(purchase.getOrderId)です。purchaseはBillingライブラリの[Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase)クラスのインスタンスです。 | | variationId | 必須 | バリアントの文字列識別子です。[AdaptyPaywall](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/)オブジェクトの`variationId`プロパティを使用して取得できます。 | ```java Adapty.setVariationId(transactionId, variationId, error -> { if (error == null) { // success } }); ``` | パラメーター | 必須/任意 | 説明 | | ------------- | --------- | ------------------------------------------------------------ | | transactionId | 必須 | 購入の文字列識別子(purchase.getOrderId)です。purchaseはBillingライブラリの[Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase)クラスのインスタンスです。 | | variationId | 必須 | バリアントの文字列識別子です。[AdaptyPaywall](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/)オブジェクトの`variationId`プロパティを使用して取得できます。 | --- # File: android-present-paywall-builder-paywalls-in-observer-mode --- --- title: "Android SDKのObserverモードでペイウォールビルダーのペイウォールを表示する" description: "Adaptyのペイウォールビルダーを使用してObserverモードでペイウォールを表示する方法について説明します。" --- ペイウォールビルダーを使ってペイウォールをカスタマイズした場合、モバイルアプリのコードでユーザーに表示するための描画処理を別途実装する必要はありません。このようなペイウォールには、表示内容と表示方法の両方が含まれています。 :::warning このセクションは[Observerモード](observer-vs-full-mode)専用です。Observerモードを使用していない場合は、[Android - ペイウォールビルダーのペイウォールを表示する](android-present-paywalls)を参照してください。 :::
ペイウォールの表示を始める前に(クリックして展開) 1. Adaptyの初期連携を[Google Play](initial-android)および[App Store](initial_ios)と行います。 2. Adapty SDKをインストールして設定します。`observerMode`パラメータを`true`に設定してください。フレームワーク別の手順は[Android向け](sdk-installation-android)を参照してください。 3. Adapty ダッシュボードで[プロダクトを作成](create-product)します。 4. Adapty ダッシュボードで[ペイウォールを設定してプロダクトを割り当て](create-paywall)、ペイウォールビルダーを使ってカスタマイズします。 5. Adapty ダッシュボードで[プレースメントを作成してペイウォールを割り当て](create-placement)ます。 6. モバイルアプリのコードで[ペイウォールビルダーのペイウォールとその設定を取得](android-get-pb-paywalls)します。

1. `AdaptyUiObserverModeHandler`を実装します。 `onPurchaseInitiated`イベントは、ユーザーが購入を開始したことを通知します。このコールバックに応じてカスタムの購入フローをトリガーできます: ```kotlin showLineNumbers val observerModeHandler = AdaptyUiObserverModeHandler { product, paywall, paywallView, onStartPurchase, onFinishPurchase -> onStartPurchase() yourBillingClient.makePurchase( product, onSuccess = { purchase -> onFinishPurchase() //handle success }, onError = { onFinishPurchase() //handle error }, onCancel = { onFinishPurchase() //handle cancel } ) } ``` ```java showLineNumbers AdaptyUiObserverModeHandler observerModeHandler = (product, paywall, paywallView, onStartPurchase, onFinishPurchase) -> { onStartPurchase.invoke(); yourBillingClient.makePurchase( product, purchase -> { onFinishPurchase.invoke(); //handle success }, error -> { onFinishPurchase.invoke(); //handle error }, () -> { //cancellation onFinishPurchase.invoke(); //handle cancel } ); }; ``` Observerモードでの復元を処理するには、`getRestoreHandler()`をオーバーライドします。デフォルトでは`null`が返され、Adaptyの組み込み`Adapty.restorePurchases()`フローが使用されます。独自の復元実装を提供するには: ```kotlin showLineNumbers val observerModeHandler = object : AdaptyUiObserverModeHandler { // onPurchaseInitiated implementation (see above) override fun getRestoreHandler() = AdaptyUiObserverModeHandler.RestoreHandler { onStartRestore, onFinishRestore -> onStartRestore() yourBillingClient.restorePurchases( onSuccess = { restoredPurchases -> onFinishRestore() //handle successful restore }, onError = { onFinishRestore() //handle error } ) } } ``` ```java showLineNumbers AdaptyUiObserverModeHandler observerModeHandler = new AdaptyUiObserverModeHandler() { // onPurchaseInitiated implementation (see above) @Override public RestoreHandler getRestoreHandler() { return (onStartRestore, onFinishRestore) -> { onStartRestore.invoke(); yourBillingClient.restorePurchases( restoredPurchases -> { onFinishRestore.invoke(); //handle successful restore }, error -> { onFinishRestore.invoke(); //handle error } ); }; } }; ``` 購入または復元プロセスをAdaptyUIに通知するために、以下のコールバックを呼び出すことを忘れないでください。これはローダーの表示など、ペイウォールの正常な動作に必要です: | コールバック | 説明 | | :----------------- |:---------------------------------------------------------------------------------------| | onStartPurchase() | 購入が開始されたことをAdaptyUIに通知するために呼び出します。 | | onFinishPurchase() | 購入が完了したことをAdaptyUIに通知するために呼び出します。 | | onStartRestore() | 任意。復元が開始されたことをAdaptyUIに通知するために呼び出せます。 | | onFinishRestore() | 任意。復元が完了したことをAdaptyUIに通知するために呼び出せます。 | 2. デバイス画面にビジュアルペイウォールを表示するには、まず設定が必要です。 これを行うには、`AdaptyUI.getPaywallView()`メソッドを呼び出すか、`AdaptyPaywallView`を直接作成します: ```kotlin showLineNumbers val paywallView = AdaptyUI.getPaywallView( activity, viewConfiguration, products, eventListener, personalizedOfferResolver, tagResolver, timerResolver, observerModeHandler, ) ``` ```kotlin showLineNumbers val paywallView = AdaptyPaywallView(activity) // or retrieve it from xml ... with(paywallView) { showPaywall( viewConfiguration, products, eventListener, personalizedOfferResolver, tagResolver, timerResolver, observerModeHandler, ) } ``` ```java showLineNumbers AdaptyPaywallView paywallView = AdaptyUI.getPaywallView( activity, viewConfiguration, products, eventListener, personalizedOfferResolver, tagResolver, timerResolver, observerModeHandler ); ``` ```java showLineNumbers AdaptyPaywallView paywallView = new AdaptyPaywallView(activity); //add to the view hierarchy if needed, or you receive it from xml ... paywallView.showPaywall(viewConfiguration, products, eventListener, personalizedOfferResolver, tagResolver, timerResolver, observerModeHandler); ``` ```xml showLineNumbers ``` ビューが正常に作成されたら、ビュー階層に追加して表示できます。 このコンポーザブル関数を使用します: ```kotlin showLineNumbers AdaptyPaywallScreen( viewConfiguration, products, eventListener, personalizedOfferResolver, tagResolver, timerResolver, ) ``` リクエストパラメータ: | パラメータ | 必須 | 説明 | |---------|--------|-----------| | **Products** | 任意 | `AdaptyPaywallProduct`の配列を指定すると、画面上のプロダクト表示タイミングを最適化できます。`null`を渡した場合、AdaptyUIが必要なプロダクトを自動的に取得します。 | | **ViewConfiguration** | 必須 | ペイウォールのビジュアル詳細を含む`AdaptyViewConfiguration`オブジェクトを指定します。`Adapty.getViewConfiguration(paywall)`メソッドを使って読み込みます。詳細は[ペイウォールのビジュアル設定を取得する](#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder)を参照してください。 | | **EventListener** | 任意 | `AdaptyUiEventListener`を指定してペイウォールのイベントを監視します。使いやすさのためAdaptyUiDefaultEventListenerの継承が推奨されます。詳細は[ペイウォールイベントの処理](android-handling-events)を参照してください。 | | **PersonalizedOfferResolver** | 任意 | パーソナライズ価格([詳細](https://developer.android.com/google/play/billing/integrate#personalized-price))を示すには、`AdaptyUiPersonalizedOfferResolver`を実装し、`AdaptyPaywallProduct`の価格がパーソナライズされている場合はtrue、そうでない場合はfalseを返す独自のロジックを渡します。 | | **TagResolver** | 任意 | `AdaptyUiTagResolver`を使用してペイウォールテキスト内のカスタムタグを解決します。このリゾルバーはタグパラメータを受け取り、対応する文字列に解決します。詳細はペイウォールビルダーのカスタムタグのトピックを参照してください。 | | **ObserverModeHandler** | Observerモードでは必須 | 前のステップで実装した`AdaptyUiObserverModeHandler`。 | | **variationId** | 必須 | バリアントの文字列識別子。[`AdaptyPaywall`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/)オブジェクトの`variationId`プロパティを使って取得できます。 | | **transaction** | 必須 |

iOS、StoreKit1の場合:[`SKPaymentTransaction`](https://developer.apple.com/documentation/storekit/skpaymenttransaction)オブジェクト。

iOS、StoreKit 2の場合:[Transaction](https://developer.apple.com/documentation/storekit/transaction)オブジェクト。

Androidの場合:購入のString識別子(`purchase.getOrderId()`)。ここで購入はBillingライブラリの[Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase)クラスのインスタンスです。

|
ペイウォールの表示を始める前に(クリックして展開) 1. Adaptyの初期連携を[Google Play](initial-android)および[App Store](initial_ios)と行います。 2. Adapty SDKをインストールして設定します。`observerMode`パラメータを`true`に設定してください。フレームワーク別の手順は[Android](sdk-installation-android)、[React Native](sdk-installation-reactnative)、[Flutter](sdk-installation-flutter#activate-adapty-module-of-adapty-sdk)、[Unity](sdk-installation-unity#activate-adapty-module-of-adapty-sdk)を参照してください。 3. Adapty ダッシュボードで[プロダクトを作成](create-product)します。 4. Adapty ダッシュボードで[ペイウォールを設定してプロダクトを割り当て](create-paywall)、ペイウォールビルダーを使ってカスタマイズします。 5. Adapty ダッシュボードで[プレースメントを作成してペイウォールを割り当て](create-placement)ます。 6. モバイルアプリのコードで[ペイウォールビルダーのペイウォールとその設定を取得](android-get-pb-paywalls)します。
1. `AdaptyUiObserverModeHandler`を実装します。`AdaptyUiObserverModeHandler`のコールバック(`onPurchaseInitiated`)は、ユーザーが購入を開始したタイミングを通知します。このコールバックに応じてカスタムの購入フローを次のようにトリガーできます: ```kotlin showLineNumbers val observerModeHandler = AdaptyUiObserverModeHandler { product, paywall, paywallView, onStartPurchase, onFinishPurchase -> onStartPurchase() yourBillingClient.makePurchase( product, onSuccess = { purchase -> onFinishPurchase() //handle success }, onError = { onFinishPurchase() //handle error }, onCancel = { onFinishPurchase() //handle cancel } ) } ``` ```java showLineNumbers AdaptyUiObserverModeHandler observerModeHandler = (product, paywall, paywallView, onStartPurchase, onFinishPurchase) -> { onStartPurchase.invoke(); yourBillingClient.makePurchase( product, purchase -> { onFinishPurchase.invoke(); //handle success }, error -> { onFinishPurchase.invoke(); //handle error }, () -> { //cancellation onFinishPurchase.invoke(); //handle cancel } ); }; ``` また、AdaptyUIへのコールバックを忘れずに呼び出してください。これはローダーの表示など、ペイウォールの正常な動作に必要です: | Kotlinでのコールバック | Javaでのコールバック | 説明 | | :----------------- | :------------------------ | :-------------------------------------------------------------------------------------------------------------------------------- | | onStartPurchase() | onStartPurchase.invoke() | 購入が開始されたことをAdaptyUIに通知するために呼び出します。 | | onFinishPurchase() | onFinishPurchase.invoke() | 購入が正常に完了したか、失敗したか、またはキャンセルされたことをAdaptyUIに通知するために呼び出します。 | 2. ビジュアルペイウォールを表示するには、まず初期化が必要です。`AdaptyUI.getPaywallView()`メソッドを呼び出すか、`AdaptyPaywallView`を直接作成します: ```kotlin showLineNumbers val paywallView = AdaptyUI.getPaywallView( activity, viewConfiguration, products, AdaptyPaywallInsets.of(topInset, bottomInset), eventListener, personalizedOfferResolver, tagResolver, observerModeHandler, ) //======= OR ======= val paywallView = AdaptyPaywallView(activity) // or retrieve it from xml ... with(paywallView) { setEventListener(eventListener) setObserverModeHandler(observerModeHandler) showPaywall( viewConfiguration, products, AdaptyPaywallInsets.of(topInset, bottomInset), personalizedOfferResolver, tagResolver, ) } ``` ```java showLineNumbers AdaptyPaywallView paywallView = AdaptyUI.getPaywallView( activity, viewConfiguration, products, AdaptyPaywallInsets.of(topInset, bottomInset), eventListener, personalizedOfferResolver, tagResolver, observerModeHandler ); //======= OR ======= AdaptyPaywallView paywallView = new AdaptyPaywallView(activity); //add to the view hierarchy if needed, or you receive it from xml ... paywallView.setEventListener(eventListener); paywallView.setObserverModeHandler(observerModeHandler); paywallView.showPaywall(viewConfiguration, products, AdaptyPaywallInsets.of(topInset, bottomInset), personalizedOfferResolver); ``` ```xml showLineNumbers ``` ビューが正常に作成されたら、ビュー階層に追加して表示できます。 リクエストパラメータ: | パラメータ | 必須 | 説明 | |---------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Products** | 任意 | `AdaptyPaywallProduct`の配列を指定すると、画面上のプロダクト表示タイミングを最適化できます。`null`を渡した場合、AdaptyUIが必要なプロダクトを自動的に取得します。 | | **ViewConfiguration** | 必須 | ペイウォールのビジュアル詳細を含む`AdaptyViewConfiguration`オブジェクトを指定します。`Adapty.getViewConfiguration(paywall)`メソッドを使って読み込みます。詳細は[ペイウォールのビジュアル設定を取得する](android-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder)を参照してください。 | | **Insets** | 必須 | システムバーで覆われる領域の情報を含む`AdaptyPaywallInsets`オブジェクトを定義し、コンテンツの上下マージンを設定します。ステータスバーもナビゲーションバーも`AdaptyPaywallView`と重ならない場合は`AdaptyPaywallInsets.NONE`を渡します。システムバーがUIの一部と重なるフルスクリーンモードの場合は、表の下に示す方法でインセットを取得します。 | | **EventListener** | 任意 | `AdaptyUiEventListener`を指定してペイウォールのイベントを監視します。使いやすさのためAdaptyUiDefaultEventListenerの継承が推奨されます。詳細は[ペイウォールイベントの処理](android-handling-events)を参照してください。 | | **PersonalizedOfferResolver** | 任意 | パーソナライズ価格([詳細](https://developer.android.com/google/play/billing/integrate#personalized-price))を示すには、`AdaptyUiPersonalizedOfferResolver`を実装し、`AdaptyPaywallProduct`の価格がパーソナライズされている場合はtrue、そうでない場合はfalseを返す独自のロジックを渡します。 | | **TagResolver** | 任意 | `AdaptyUiTagResolver`を使用してペイウォールテキスト内のカスタムタグを解決します。このリゾルバーはタグパラメータを受け取り、対応する文字列に解決します。詳細はペイウォールビルダーのカスタムタグのトピックを参照してください。 | | **ObserverModeHandler** | Observerモードでは必須 | 前のステップで実装した`AdaptyUiObserverModeHandler`。 | | **variationId** | 必須 | バリアントの文字列識別子。[`AdaptyPaywall`](https://android.adapty.io/adapty/com.adapty.models/-adapty-paywall/)オブジェクトの`variationId`プロパティを使って取得できます。 | | **transaction** | 必須 |

iOS、StoreKit1の場合:[`SKPaymentTransaction`](https://developer.apple.com/documentation/storekit/skpaymenttransaction)オブジェクト。

iOS、StoreKit 2の場合:[Transaction](https://developer.apple.com/documentation/storekit/transaction)オブジェクト。

Androidの場合:購入のString識別子(`purchase.getOrderId()`)。ここで購入はBillingライブラリの[Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase)クラスのインスタンスです。

| システムバーがUIの一部と重なるフルスクリーンモードでは、次のようにインセットを取得します: ```kotlin showLineNumbers import androidx.core.graphics.Insets import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat //create extension function fun View.onReceiveSystemBarsInsets(action: (insets: Insets) -> Unit) { ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets -> val systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()) ViewCompat.setOnApplyWindowInsetsListener(this, null) action(systemBarInsets) insets } } //and then use it with the view paywallView.onReceiveSystemBarsInsets { insets -> val paywallInsets = AdaptyPaywallInsets.of(insets.top, insets.bottom) paywallView.setEventListener(eventListener) paywallView.setObserverModeHandler(observerModeHandler) paywallView.showPaywall(viewConfig, products, paywallInsets, personalizedOfferResolver, tagResolver) } ``` ```java showLineNumbers import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; ... ViewCompat.setOnApplyWindowInsetsListener(paywallView, (view, insets) -> { Insets systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()); ViewCompat.setOnApplyWindowInsetsListener(paywallView, null); AdaptyPaywallInsets paywallInsets = AdaptyPaywallInsets.of(systemBarInsets.top, systemBarInsets.bottom); paywallView.setEventListener(eventListener); paywallView.setObserverModeHandler(observerModeHandler); paywallView.showPaywall(viewConfiguration, products, paywallInsets, personalizedOfferResolver, tagResolver); return insets; }); ``` 戻り値: | オブジェクト | 説明 | | :------------------ | :------------------------------------------------- | | `AdaptyPaywallView` | リクエストされたペイウォール画面を表すオブジェクト。 | :::warning [購入トランザクションにペイウォールを関連付ける](report-transactions-observer-mode-android)のを忘れないでください。設定しないと、Adaptyは購入元のペイウォールを特定できません。 :::
--- # File: android-troubleshoot-purchases --- --- title: "Android SDKでの購入に関するトラブルシューティング" description: "Android SDKでの購入に関するトラブルシューティング" --- このガイドでは、Android SDKで手動購入を実装する際によく発生する問題の解決方法を説明します。 ## makePurchaseが正常に完了してもプロファイルが更新されない \{#makepurchase-is-called-successfully-but-the-profile-is-not-being-updated\} **問題**: `makePurchase` メソッドが正常に完了するにもかかわらず、ユーザーのプロファイルとサブスクリプション状態がAdaptyで更新されない。 **原因**: 通常、Google Play Storeのセットアップが不完全であるか、設定に問題があることを示しています。 **解決策**: [Google Play のセットアップ手順](initial-android)がすべて完了しているか確認してください。 ## makePurchaseが2回呼び出される \{#makepurchase-is-invoked-twice\} **問題**: 同じ購入に対して `makePurchase` メソッドが複数回呼び出されている。 **原因**: UIの状態管理の問題や、ユーザーの素早い操作によって購入フローが複数回トリガーされる場合に発生します。 **解決策**: [Google Play のセットアップ手順](initial-android)がすべて完了しているか確認してください。 ## オブザーバーモードでのAdaptyError.cantMakePayments \{#adaptyerrorcantmakepayments-in-observer-mode\} **問題**: オブザーバーモードで `makePurchase` を使用すると `AdaptyError.cantMakePayments` が発生する。 **原因**: オブザーバーモードでは、Adaptyの `makePurchase` メソッドを使用せず、購入処理はご自身で行う必要があります。 **解決策**: 購入に `makePurchase` を使用している場合は、オブザーバーモードをオフにしてください。`makePurchase` を使用するか、オブザーバーモードで自前の購入処理を行うか、どちらか一方を選択してください。詳細は[オブザーバーモードの実装](implement-observer-mode-android)を参照してください。 ## Adaptyエラー: (code: 103, message: Play Market request failed on purchases updated: responseCode=3, debugMessage=Billing Unavailable, detail: null) \{#adapty-error-code-103-message-play-market-request-failed-on-purchases-updated-responsecode3-debugmessagebilling-unavailable-detail-null\} **問題**: Google Play Storeから課金不可エラーが返ってくる。 **原因**: このエラーはAdaptyとは無関係です。デバイスで課金が利用できないことを示すGoogle Play Billing Libraryのエラーです。 **解決策**: このエラーはAdaptyとは無関係です。Play Storeのドキュメントで詳細を確認できます: [Handle BillingResult response codes](https://developer.android.com/google/play/billing/errors#billing_unavailable_error_code_3) | Play Billing | Android Developers。 ## makePurchasesCompletionHandlersが見つからない \{#not-found-makepurchasescompletionhandlers\} **問題**: `makePurchasesCompletionHandlers` が見つからないというエラーが発生する。 **原因**: 通常、サンドボックステストに関連する問題です。 **解決策**: 新しいサンドボックスユーザーを作成して再試行してください。これによりサンドボックス関連の購入完了ハンドラーの問題が解決されることがほとんどです。 ## その他の問題 \{#other-issues\} **問題**: 上記に該当しない購入関連の問題が発生している。 **解決策**: 必要に応じて[移行ガイド](android-sdk-migration-guides)を参照し、SDKを最新バージョンに移行してください。多くの問題は新しいSDKバージョンで解決されています。 --- # File: android-identifying-users --- --- title: "Android SDKでユーザーを識別する" description: "Adaptyでユーザーを識別して、パーソナライズされたサブスクリプション体験を向上させます(Android)。" --- Adaptyはすべてのユーザーに対して内部プロファイルIDを作成します。ただし、独自の認証システムがある場合は、独自のCustomer User IDを設定する必要があります。[Profiles](profiles-crm)セクションでCustomer User IDによってユーザーを検索したり、すべてのインテグレーションに送信される[サーバーサイドAPI](getting-started-with-server-side-api)で使用したりできます。 ### 設定時にCustomer User IDを設定する \{#setting-customer-user-id-on-configuration\} 設定時にユーザーIDが存在する場合は、`.activate()`メソッドの`customerUserId`パラメータとして渡すだけです: ```kotlin showLineNumbers Adapty.activate(applicationContext, "PUBLIC_SDK_KEY", customerUserId = "YOUR_USER_ID") ``` :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 ::: ### 設定後にCustomer User IDを設定する \{#setting-customer-user-id-after-configuration\} SDK設定時にユーザーIDがない場合は、`.identify()`メソッドを使っていつでも後から設定できます。このメソッドを使う最も一般的なケースは、ユーザーが匿名ユーザーから認証済みユーザーに切り替わる登録後や認証後です。 ```kotlin showLineNumbers Adapty.identify("YOUR_USER_ID") { error -> if (error == null) { // successful identify } } ``` ```java showLineNumbers Adapty.identify("YOUR_USER_ID", error -> { if (error == null) { // successful identify } }); ``` リクエストパラメータ: - **Customer User ID**(必須):文字列のユーザー識別子。 :::warning 重要なユーザーデータの再送信 ユーザーが再度アカウントにログインする場合など、Adaptyのサーバーにそのユーザーの情報がすでに存在するケースがあります。このような場合、Adapty SDKは自動的に新しいユーザーとして切り替えて動作します。カスタム属性やサードパーティネットワークからのアトリビューションなど、匿名ユーザーに渡したデータがある場合は、識別済みユーザーに対してそのデータを再送信する必要があります。 また、新しいユーザーのデータが異なる場合があるため、ユーザーを識別した後はすべてのペイウォールとプロダクトを再取得する必要がある点にも注意してください。 ::: ### ログアウトとログイン \{#logging-out-and-logging-in\} `.logout()`メソッドを呼び出すことで、いつでもユーザーをログアウトできます: ```kotlin showLineNumbers Adapty.logout { error -> if (error == null) { // successful logout } } ``` ```java showLineNumbers Adapty.logout(error -> { if (error == null) { // successful logout } }); ``` その後、`.identify()`メソッドを使ってユーザーをログインできます。 ### デバイスをまたいでユーザーを検出する \{#detect-users-across-devices\} --- no_index: true --- SDKが有効化されると、StoreKit(iOS)またはGoogle Play Billing(Android)からユーザーの既存のエンタイトルメントを自動的に読み取り、Adaptyバックエンドと同期します。有効なサブスクリプションは、アプリが`restorePurchases`を呼び出すことなく、Adaptyプロファイルに表示されます。 **自動では行われない**のは、新しいデバイスのプロファイルが元のデバイスと同じユーザーのものであることの認識です。AdaptyはCustomer User IDでプロファイルを照合するため、同一性の継続性はCUIDとして何を使用するかによって異なります。 **デバイス間でAdaptyが検出できること** | あなたの設定 | Adaptyが検出すること | 必要な対応 | | --- | --- | --- | | Customer User ID = `device_id`(アプリのログインなし) | 新しいデバイスは異なるCUIDを取得するため、異なるプロファイルが作成されます。サブスクリプションは**Access level updated**イベントを通じて新しいプロファイルに同期されますが、`subscription_started`は発火しません。新しいプロファイルは元の購入の継承者として扱われます。`subscription_started`に基づくアナリティクスは、リターニングユーザーをカウント不足します。 | リターニングユーザーが既存のプロファイルをデバイス間で照合できるよう、安定したアカウントIDをCustomer User IDとして使用してください。 | | Customer User ID = 安定したアカウントID(すべてのデバイスでログイン) | SDKは`activate()`でサブスクリプションを自動同期し、`identify()`がCUIDで既存のプロファイルを照合します。 | 追加の設定は不要です。IDとサブスクリプションの両方が自動的に解決されます。 | | Apple Family Sharing の継承者 | ファミリーメンバーは**Access level updated**イベントのみを通じてサブスクリプションを受け取ります。`subscription_started`は発火しません。 | **Access level updated**をリッスンしてください。完全なイベントマトリクスは[Apple Family Sharing](apple-family-sharing)を参照してください。 | | 同じApple/Googleアカウント、異なるアプリ内ユーザー | 最初に購入を記録したプロファイルが親になります。その後のプロファイルは継承者チェーンを通じてサブスクリプションを確認し、**Access level updated**イベントが1回発生します。 | ログインを必須にし、あなたのモデルに合った[共有モード](sharing-paid-access-between-user-accounts)を選択してください。 | **新しいデバイスでの購入の復元** ペイウォールにユーザーが操作できる「購入を復元」ボタンを設置してください。Apple App Review(ガイドライン3.1.1)で必須とされており、自動同期がエッジケースを見逃した場合のフォールバックとして機能します。このボタンはSDKの`restorePurchases`を呼び出す必要があります。 初回起動時にプログラムで`restorePurchases`を呼び出すことは、通常の使用では必要ありません。SDKはすでに`activate()`で同等の処理を実行しています。プログラムによる呼び出しは、`activate()`完了後にアクセスが欠落している場合のデバッグなど、強制的に新しいレシートチェックを行う場合にのみ使用してください。 --- # File: android-setting-user-attributes --- --- title: "Android SDKでユーザー属性を設定する" description: "Adaptyでユーザー属性を設定してオーディエンスのセグメンテーションを改善する方法を学びます。" --- メールアドレスや電話番号などのオプション属性をアプリのユーザーに設定できます。設定した属性を使って、ユーザーの[セグメント](segments)を作成したり、CRMで確認したりすることができます。 ### ユーザー属性の設定 \{#setting-user-attributes\} ユーザー属性を設定するには、`.updateProfile()` メソッドを呼び出します。 ```kotlin showLineNumbers val builder = AdaptyProfileParameters.Builder() .withEmail("email@email.com") .withPhoneNumber("+18888888888") .withFirstName("John") .withLastName("Appleseed") .withGender(AdaptyProfile.Gender.OTHER) .withBirthday(AdaptyProfile.Date(1970, 1, 3)) Adapty.updateProfile(builder.build()) { error -> if (error != null) { // handle the error } } ``` ```java showLineNumbers AdaptyProfileParameters.Builder builder = new AdaptyProfileParameters.Builder() .withEmail("email@email.com") .withPhoneNumber("+18888888888") .withFirstName("John") .withLastName("Appleseed") .withGender(AdaptyProfile.Gender.OTHER) .withBirthday(new AdaptyProfile.Date(1970, 1, 3)); Adapty.updateProfile(builder.build(), error -> { if (error != null) { // handle the error } }); ``` `updateProfile` メソッドで以前に設定した属性はリセットされませんのでご注意ください。 :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 ::: ### 使用可能なキーの一覧 \{#the-allowed-keys-list\} `AdaptyProfileParameters.Builder` で使用できるキー `` と値 `` の一覧は以下のとおりです。 | キー | 値 | |---|-----| |

email

phoneNumber

firstName

lastName

| String | | gender | Enum。使用可能な値: `female`、`male`、`other` | | birthday | Date | ### カスタムユーザー属性 \{#custom-user-attributes\} 独自のカスタム属性を設定することもできます。カスタム属性は通常、アプリの使用状況に関連するものです。たとえば、フィットネスアプリなら週あたりの運動回数、語学学習アプリならユーザーの習熟度レベルなどが挙げられます。セグメントで活用してターゲットを絞ったペイウォールやオファーを作成したり、アナリティクスでどのプロダクト指標が収益に最も影響するかを把握したりすることができます。 ```kotlin showLineNumbers builder.withCustomAttribute("key1", "value1") ``` ```java showLineNumbers builder.withCustomAttribute("key1", "value1"); ``` 既存のキーを削除するには、`.withRemoved(customAttributeForKey:)` メソッドを使用します。 ```kotlin showLineNumbers builder.withRemovedCustomAttribute("key2") ``` ```java showLineNumbers builder.withRemovedCustomAttribute("key2"); ``` これまでに設定されたカスタム属性を確認したい場合は、`AdaptyProfile` オブジェクトの `customAttributes` フィールドを使用してください。 :::warning ユーザー属性は異なるデバイスからいつでも送信される可能性があるため、`customAttributes` の値は最新の状態ではない場合があります。最後の同期後にサーバー上の属性が更新されている可能性があります。 ::: ### 制限事項 \{#limits\} - ユーザーごとに最大30件のカスタム属性を設定可能 - キー名は最大30文字。キー名には英数字と以下の記号が使用可能: `_` `-` `.` - 値は文字列またはfloatで、最大50文字まで。 --- # File: android-listen-subscription-changes --- --- title: "Android SDKでサブスクリプションステータスを確認する" description: "Adaptyを使用してAndroidアプリのユーザーサブスクリプションステータスを追跡・管理し、顧客維持率を向上させましょう。" --- Adaptyを使えば、サブスクリプションのステータス管理が簡単になります。プロダクトIDをコードに直接記述する必要はありません。アクティブな[アクセスレベル](access-level)を確認するだけで、ユーザーのサブスクリプションステータスを手軽に把握できます。 サブスクリプションステータスの確認を始める前に、[リアルタイム デベロッパー通知(RTDN)](enable-real-time-developer-notifications-rtdn)を設定してください。 ## アクセスレベルとAdaptyProfileオブジェクト \{#access-level-and-the-adaptyprofile-object\} アクセスレベルは[AdaptyProfile](https://android.adapty.io/adapty/com.adapty.models/-adapty-profile/)オブジェクトのプロパティです。アプリ起動時(例:[ユーザーを識別する](android-identifying-users#setting-customer-user-id-on-configuration)タイミングなど)にプロファイルを取得し、変更があるたびに更新することをおすすめします。こうすることで、毎回リクエストを送らずともプロファイルオブジェクトを活用できます。 プロファイルの更新通知を受け取るには、以下の[プロファイル更新(アクセスレベルを含む)をリッスンする](android-listen-subscription-changes)セクションで説明している方法でプロファイルの変更を監視してください。 :::tip Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演している[サンプルアプリ](sample-apps)をご覧ください。 ::: ## サーバーからアクセスレベルを取得する \{#retrieving-the-access-level-from-the-server\} サーバーからアクセスレベルを取得するには、`.getProfile()`メソッドを使用します: ```kotlin showLineNumbers Adapty.getProfile { result -> when (result) { is AdaptyResult.Success -> { val profile = result.value // check the access } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` ```java showLineNumbers Adapty.getProfile(result -> { if (result instanceof AdaptyResult.Success) { AdaptyProfile profile = ((AdaptyResult.Success) result).getValue(); // check the access } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` レスポンスパラメーター: | パラメーター | 説明 | | --------- | ------------------------------------------------------------ | | Profile |

[AdaptyProfile](https://android.adapty.io/adapty/com.adapty.models/-adapty-profile/)オブジェクト。通常、ユーザーがプレミアムアクセスを持っているかどうかを判断するには、プロファイルのアクセスレベルのステータスを確認するだけで十分です。

`.getProfile`メソッドは常にAPIへのクエリを試みるため、最新の結果を返します。何らかの理由(例:インターネット接続なし)でAdapty SDKがサーバーから情報を取得できない場合、キャッシュのデータが返されます。なお、Adapty SDKは`AdaptyProfile`のキャッシュを定期的に更新し、情報をできる限り最新の状態に保ちます。

| `.getProfile()`メソッドはユーザープロファイルを返し、そこからアクセスレベルのステータスを取得できます。アプリごとに複数のアクセスレベルを設定することが可能です。たとえばニュースアプリで異なるトピックへのサブスクリプションを個別に販売する場合、「sports」や「science」といったアクセスレベルを作成できます。ただし、ほとんどの場合は1つのアクセスレベルで十分であり、その場合はデフォルトの「premium」アクセスレベルを使用するだけで問題ありません。 デフォルトの「premium」アクセスレベルを確認する例: ```kotlin showLineNumbers Adapty.getProfile { result -> when (result) { is AdaptyResult.Success -> { val profile = result.value if (profile.accessLevels["premium"]?.isActive == true) { // grant access to premium features } } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` ```java showLineNumbers Adapty.getProfile(result -> { if (result instanceof AdaptyResult.Success) { AdaptyProfile profile = ((AdaptyResult.Success) result).getValue(); AdaptyProfile.AccessLevel premium = profile.getAccessLevels().get("premium"); if (premium != null && premium.isActive()) { // grant access to premium features } } else if (result instanceof AdaptyResult.Error) { AdaptyError error = ((AdaptyResult.Error) result).getError(); // handle the error } }); ``` ### サブスクリプションステータスの更新をリッスンする \{#listening-for-subscription-status-updates\} ユーザーのサブスクリプションが変更されるたびに、Adaptyはイベントを発火します。 Adaptyからメッセージを受け取るには、追加の設定が必要です: ```kotlin showLineNumbers Adapty.setOnProfileUpdatedListener { profile -> // handle any changes to subscription state } ``` ```java showLineNumbers t Adapty.setOnProfileUpdatedListener(profile -> { // handle any changes to subscription state }); ``` Adaptyはアプリケーション起動時にもイベントを発火します。この場合、キャッシュされたサブスクリプションステータスが渡されます。 ### サブスクリプションステータスのキャッシュ \{#subscription-status-cache\} Adapty SDKに実装されているキャッシュは、プロファイルのサブスクリプションステータスを保存します。そのため、サーバーが利用できない状況でも、キャッシュされたデータからプロファイルのサブスクリプションステータスを取得できます。 ただし、キャッシュから直接データをリクエストすることはできません。SDKは1分ごとにサーバーへクエリを送り、プロファイルに関する更新や変更を確認します。新しいトランザクションやその他の更新があった場合、それらはサーバーとの同期を保つためにキャッシュデータへ反映されます。 --- # File: kids-mode-android --- --- title: "Android SDKのキッズモード" description: "キッズモードを簡単に有効化してGoogleのポリシーに準拠。Android SDKではGAIDや広告データは収集されません。" --- Androidアプリが子ども向けの場合、[Google](https://support.google.com/googleplay/android-developer/answer/9893335)のポリシーに従う必要があります。Adapty SDKを使用している場合、いくつかの簡単な手順でこれらのポリシーに準拠し、アプリストアの審査を通過できるよう設定できます。 ## 必要な対応 \{#whats-required\} Adapty SDKで以下の収集を無効化する必要があります: - [Android広告ID(AAID/GAID)](https://support.google.com/googleplay/android-developer/answer/6048248) - [IPアドレス](https://www.ftc.gov/system/files/ftc_gov/pdf/p235402_coppa_application.pdf) また、カスタマーユーザーIDの扱いにも注意が必要です。``形式のユーザーIDは、メールアドレスと同様に個人情報の収集とみなされる可能性があります。キッズモードでは、ランダム化または匿名化された識別子(ハッシュIDやデバイス生成のUUIDなど)を使用することがベストプラクティスです。 ## キッズモードの有効化 \{#enabling-kids-mode\} ### Adapty ダッシュボードでの設定 \{#updates-in-the-adapty-dashboard\} Adapty ダッシュボードでは、IPアドレスの収集を無効化する必要があります。[App settings](https://app.adapty.io/settings/general)に移動し、**Collect users' IP address**の下にある**Disable IP address collection**をクリックしてください。 ### モバイルアプリのコードでの設定 \{#updates-in-your-mobile-app-code\} ポリシーに準拠するため、Adapty SDKの初期化時にAndroid広告ID(AAID/GAID)とIPアドレスの収集を無効化する必要があります: **Kotlin:** ```kotlin showLineNumbers override fun onCreate() { super.onCreate() Adapty.activate( applicationContext, AdaptyConfig.Builder("PUBLIC_SDK_KEY") // highlight-start .withAdIdCollectionDisabled(true) // set to `true` .withIpAddressCollectionDisabled(true) // set to `true` // highlight-end .build() ) } ``` **Java:** ```java showLineNumbers @Override public void onCreate() { super.onCreate(); Adapty.activate( applicationContext, new AdaptyConfig.Builder("PUBLIC_SDK_KEY") // highlight-start .withAdIdCollectionDisabled(true) // set to `true` .withIpAddressCollectionDisabled(true) // set to `true` // highlight-end .build() ); } ``` ### Androidマニフェストでの設定 \{#updates-in-your-android-manifest\} :::note アプリが子ども**専用**であり、Android 13(API 33)以上をターゲットとしてコンパイルしている場合、Google Playでは`AD_ID`パーミッションをリクエストしないことが求められます。分析、アトリビューション、または広告向けの別のSDKがマニフェストのマージを通じてこのパーミッションを追加している場合があります。`withAdIdCollectionDisabled(true)`を設定するとAdaptyによるIDの収集は停止しますが、他のSDKが宣言したパーミッションは削除されません。 ::: パーミッションを削除するには、`app/src/main/AndroidManifest.xml`の``要素内に以下を追加してください。``要素では`xmlns:tools="http://schemas.android.com/tools"`を宣言する必要があります。 ```xml showLineNumbers title="AndroidManifest.xml" ``` --- # File: android-get-onboardings --- --- title: "Android SDKでオンボーディングを取得する" description: "AdaptyのAndroid向けオンボーディング取得方法について説明します。" --- Adapty ダッシュボードのビルダーで[オンボーディングのビジュアル部分をデザイン](design-onboarding)したら、Androidアプリに表示できます。まず最初に、プレースメントに紐付いたオンボーディングとそのビュー設定を取得する必要があります。詳しくは以下をご覧ください。 始める前に、以下を確認してください: 1. [Adapty Android SDK](sdk-installation-android) バージョン 3.8.0 以上がインストールされていること。 2. [オンボーディングを作成済み](create-onboarding)であること。 3. オンボーディングを[プレースメント](placements)に追加済みであること。 ## オンボーディングの取得 \{#fetch-onboarding\} ノーコードビルダーで[オンボーディング](onboardings)を作成すると、アプリが取得・表示する必要のある設定を含むコンテナとして保存されます。このコンテナは、表示するコンテンツ・見せ方・ユーザーの操作(クイズの回答やフォーム入力など)の処理まで、すべてのエクスペリエンスを管理します。また、コンテナはアナリティクスイベントを自動的に追跡するため、別途ビュートラッキングを実装する必要はありません。 パフォーマンスを最大限に発揮させるため、ユーザーに表示する前に画像のダウンロードが完了するよう、早めにオンボーディングの設定を取得してください。 オンボーディングを取得するには、`getOnboarding` メソッドを使用します: ```kotlin showLineNumbers Adapty.getOnboarding("YOUR_PLACEMENT_ID") { result -> when (result) { is AdaptyResult.Success -> { val onboarding = result.value // the requested onboarding } is AdaptyResult.Error -> { val error = result.error // handle the error } } } ``` パラメーター: | パラメーター | 必須/任意 | 説明 | |---------|--------|------| | **placementId** | 必須 | 対象の[プレースメント](placements)の識別子です。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。 | | **locale** |

任意

デフォルト:`en`

|

オンボーディングのローカライズ識別子です。マイナス(**-**)文字で区切られた1つまたは2つのサブタグで構成される言語コードを指定してください。最初のサブタグは言語、2番目のサブタグは地域を示します。

例:`en` は英語、`pt-br` はブラジルポルトガル語を表します。

ロケールコードの詳細と推奨される使い方については、[ローカライズとロケールコード](localizations-and-locale-codes)をご覧ください。

| | **fetchPolicy** | デフォルト:`.reloadRevalidatingCacheData` |

デフォルトでは、SDKはサーバーからデータを読み込もうとし、失敗した場合はキャッシュデータを返します。ユーザーに常に最新のデータを提供できるため、このオプションを推奨します。

ただし、ユーザーのインターネット接続が不安定だと思われる場合は、`.returnCacheDataElseLoad` を使用してキャッシュデータが存在すればそれを返すことを検討してください。この場合、最新のデータが取得できないことがありますが、接続状態に関わらず読み込みが速くなります。キャッシュは定期的に更新されるため、セッション中にネットワークリクエストを避けて使用しても安全です。

キャッシュはアプリを再起動しても消えず、アプリを再インストールするか手動でクリアした場合のみ削除されます。

Adapty SDK はオンボーディングをローカルに2つの層で保存しています。上記で説明した定期更新キャッシュとフォールバックオンボーディングです。また、オンボーディングの取得を高速化するためにCDNを使用し、CDNに接続できない場合に備えた独立したフォールバックサーバーも用意しています。このシステムは、インターネット接続が不安定な場合でも、常に最新のオンボーディングを確実に取得できるよう設計されています。

| | **loadTimeout** | デフォルト:5秒 |

このメソッドのタイムアウト上限です。タイムアウトに達した場合、キャッシュデータまたはローカルフォールバックが返されます。

なお、このメソッドは内部で複数のリクエストが発生する場合があるため、`loadTimeout` で指定した時間よりわずかに遅れてタイムアウトすることがあります。

Android の場合:拡張関数(例:`5.seconds`、`.seconds` は `import com.adapty.utils.seconds` から)を使って `TimeInterval` を作成するか、`TimeInterval.seconds(5)` を使用できます。制限を設けない場合は `TimeInterval.INFINITE` を指定してください。

| レスポンスパラメーター: | パラメーター | 説明 | |:----------|:-----| | Onboarding | オンボーディングの識別子と設定、リモートコンフィグ、その他いくつかのプロパティを含む [`AdaptyOnboarding`](https://android.adapty.io/adapty/com.adapty.models/-adapty-onboarding/) オブジェクトです。 | ## デフォルトオーディエンスのオンボーディングで取得を高速化する \{#speed-up-onboarding-fetching-with-default-audience-onboarding\} 通常、オンボーディングはほぼ即座に取得されるため、この処理の高速化を気にする必要はありません。ただし、オーディエンスやオンボーディングが多数あり、ユーザーのインターネット接続が遅い場合、オンボーディングの取得に予想より時間がかかることがあります。そのような状況では、オンボーディングをまったく表示しないよりも、デフォルトのオンボーディングを表示してスムーズなユーザー体験を提供したい場合があります。 この問題に対応するため、`getOnboardingForDefaultAudience` メソッドを使用できます。このメソッドは、指定されたプレースメントの **All Users** オーディエンス向けオンボーディングを取得します。ただし、推奨される方法は上記の[オンボーディングの取得](#fetch-onboarding)セクションで説明した `getOnboarding` メソッドを使用することです。 :::warning `getOnboardingForDefaultAudience` の代わりに `getOnboarding` の使用を検討してください。前者には以下の重要な制限があります: - **互換性の問題**:複数のアプリバージョンをサポートする際に問題が生じる可能性があり、後方互換性のあるデザインが必要になるか、古いバージョンで正しく表示されないことを受け入れる必要があります。 - **パーソナライズなし**:"All Users" オーディエンス向けのコンテンツのみ表示され、国・アトリビューション・カスタム属性によるターゲティングが機能しません。 高速な取得がこれらのデメリットを上回る場合は、以下に示すように `getOnboardingForDefaultAudience` を使用してください。それ以外の場合は、[上記](#fetch-onboarding)で説明した `getOnboarding` を使用してください。 ::: ```kotlin Adapty.getOnboardingForDefaultAudience("YOUR_PLACEMENT_ID") { result -> when (result) { is AdaptyResult.Success -> { val onboarding = result.value // Handle successful onboarding retrieval } is AdaptyResult.Error -> { val error = result.error // Handle error case } } } ``` パラメーター: | パラメーター | 必須/任意 | 説明 | |---------|--------|------| | **placementId** | 必須 | 対象の[プレースメント](placements)の識別子です。Adapty ダッシュボードでプレースメントを作成する際に指定した値です。 | | **locale** |

任意

デフォルト:`en`

|

オンボーディングのローカライズ識別子です。マイナス(**-**)文字で区切られた1つまたは2つのサブタグで構成される言語コードを指定してください。最初のサブタグは言語、2番目のサブタグは地域を示します。

例:`en` は英語、`pt-br` はブラジルポルトガル語を表します。

ロケールコードの詳細と推奨される使い方については、[ローカライズとロケールコード](localizations-and-locale-codes)をご覧ください。

| | **fetchPolicy** | デフォルト:`.reloadRevalidatingCacheData` |

デフォルトでは、SDKはサーバーからデータを読み込もうとし、失敗した場合はキャッシュデータを返します。ユーザーに常に最新のデータを提供できるため、このオプションを推奨します。

ただし、ユーザーのインターネット接続が不安定だと思われる場合は、`.returnCacheDataElseLoad` を使用してキャッシュデータが存在すればそれを返すことを検討してください。この場合、最新のデータが取得できないことがありますが、接続状態に関わらず読み込みが速くなります。キャッシュは定期的に更新されるため、セッション中にネットワークリクエストを避けて使用しても安全です。

キャッシュはアプリを再起動しても消えず、アプリを再インストールするか手動でクリアした場合のみ削除されます。

Adapty SDK はオンボーディングをローカルに2つの層で保存しています。上記で説明した定期更新キャッシュとフォールバックオンボーディングです。また、オンボーディングの取得を高速化するためにCDNを使用し、CDNに接続できない場合に備えた独立したフォールバックサーバーも用意しています。このシステムは、インターネット接続が不安定な場合でも、常に最新のオンボーディングを確実に取得できるよう設計されています。

| --- # File: android-present-onboardings --- --- title: "Android SDKでオンボーディングを表示する" description: "Androidでオンボーディングを表示して、効果的なユーザーエンゲージメントを実現する方法を学びましょう。" --- 始める前に、以下を確認してください: 1. [Adapty Android SDK](sdk-installation-android) 3.8.0 以降をインストール済みであること。 2. [オンボーディングを作成済み](create-onboarding)であること。 3. オンボーディングを[プレースメント](placements)に追加済みであること。 オンボーディングビルダーを使ってオンボーディングをカスタマイズした場合、モバイルアプリのコードでレンダリングについて心配する必要はありません。そのようなオンボーディングには、表示内容と表示方法の両方が含まれています。 デバイス画面にビジュアルオンボーディングを表示するには、まず設定が必要です。`AdaptyUI.getOnboardingView()` メソッドを呼び出すか、`OnboardingView` を直接作成してください: ```kotlin val onboardingView = AdaptyUI.getOnboardingView( activity = this, viewConfig = onboardingConfig, eventListener = eventListener ) ``` ```kotlin val onboardingView = AdaptyOnboardingView(activity) onboardingView.show( viewConfig = onboardingConfig, delegate = eventListener ) ``` ```java AdaptyOnboardingView onboardingView = AdaptyUI.getOnboardingView( activity, onboardingConfig, eventListener ); ``` ```java AdaptyOnboardingView onboardingView = new AdaptyOnboardingView(activity); onboardingView.show(onboardingConfig, eventListener); ``` ```xml ``` ビューが正常に作成されたら、ビュー階層に追加してデバイス画面に表示できます。 リクエストパラメータ: | パラメータ | 必須 | 説明 | | :-------- | :------- |:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **viewConfig** | 必須 | `AdaptyUI.getOnboardingConfiguration()` から取得したオンボーディング設定 | | **eventListener** | 必須 | オンボーディングイベントを処理する `AdaptyOnboardingEventListener` の実装。詳細は[オンボーディングイベントの処理](android-handle-onboarding-events)を参照してください。 | ## ローディングインジケーターの色を変更する \{#change-loading-indicator-color\} 以下の方法でローディングインジケーターのデフォルトカラーをオーバーライドできます: ```xml ``` ## スプラッシュ画面とオンボーディング間のスムーズなトランジションを追加する \{#add-smooth-transitions-between-the-splash-screen-and-onboarding\} デフォルトでは、スプラッシュ画面とオンボーディングの間に、オンボーディングが完全に読み込まれるまでローディング画面が表示されます。ただし、トランジションをよりスムーズにしたい場合は、スプラッシュ画面を延長するか別のものを表示するようにカスタマイズできます。 これを行うには、`res/layout` に `adapty_onboarding_placeholder_view.xml` を作成し、そこでプレースホルダー(オンボーディングの読み込み中に表示する内容)を定義してください。 プレースホルダーを定義すると、オンボーディングはバックグラウンドで読み込まれ、準備が整い次第自動的に表示されます。 ## セーフエリアのパディングを無効にする \{#disable-safe-area-paddings\} デフォルトでは、オンボーディングビューはステータスバーやナビゲーションバーなどのシステムUI要素を避けるために、セーフエリアのパディングを自動的に適用します。ただし、この動作を無効にしてレイアウトを完全に制御したい場合は、`safeAreaPaddings` パラメータを `false` に設定することで対応できます。 ```kotlin val onboardingView = AdaptyUI.getOnboardingView( activity = this, viewConfig = onboardingConfig, eventListener = eventListener, safeAreaPaddings = false ) ``` ```kotlin val onboardingView = AdaptyOnboardingView(activity) onboardingView.show( viewConfig = onboardingConfig, delegate = eventListener, safeAreaPaddings = false ) ``` ```java AdaptyOnboardingView onboardingView = AdaptyUI.getOnboardingView( activity, onboardingConfig, eventListener, false ); ``` ```java AdaptyOnboardingView onboardingView = new AdaptyOnboardingView(activity); onboardingView.show(onboardingConfig, eventListener, false); ``` あるいは、アプリにブールリソースを追加することで、この動作をグローバルに制御することもできます: ```xml false ``` `safeAreaPaddings` を `false` に設定すると、オンボーディングは自動的なパディング調整なしにフルスクリーンに拡張され、レイアウトを完全に制御できるようになり、オンボーディングコンテンツが画面全体のスペースを使用できるようになります。 ## オンボーディングでのリンクの開き方をカスタマイズする \{#customize-how-links-open-in-onboardings\} :::important オンボーディングでのリンクの開き方のカスタマイズは、Adapty SDK v3.15.1 以降でサポートされています。 ::: デフォルトでは、オンボーディング内のリンクはアプリ内ブラウザで開きます。これにより、アプリを切り替えることなくアプリ内でウェブページを表示できるため、シームレスなユーザー体験が提供されます。 代わりに外部ブラウザでリンクを開きたい場合は、`externalUrlsPresentation` パラメータを `AdaptyWebPresentation.ExternalBrowser` に設定することでこの動作をカスタマイズできます: ```kotlin val onboardingConfig = AdaptyUI.getOnboardingConfiguration( onboarding = onboarding, externalUrlsPresentation = AdaptyWebPresentation.ExternalBrowser // default – InAppBrowser ) ``` ```java AdaptyOnboardingConfiguration onboardingConfig = AdaptyUI.getOnboardingConfiguration( onboarding, AdaptyWebPresentation.ExternalBrowser // default – InAppBrowser ); ``` --- # File: android-handle-onboarding-events --- --- title: "Android SDKでオンボーディングイベントを処理する" description: "Adaptyを使用してAndroidでオンボーディング関連のイベントを処理します。" --- 始める前に、以下を確認してください: 1. [Adapty Android SDK](sdk-installation-android) 3.8.0 以降をインストール済みであること。 2. [オンボーディングを作成](create-onboarding)済みであること。 3. オンボーディングを[プレースメント](placements)に追加済みであること。 ビルダーで設定されたオンボーディングは、アプリが応答できるイベントを生成します。それらのイベントへの対応方法を以下で説明します。 Android アプリ内のオンボーディング画面で発生するプロセスを制御・監視するには、`AdaptyOnboardingEventListener` インターフェースを実装してください。 ## カスタムアクション \{#custom-actions\} ビルダーでは、ボタンに**カスタム**アクションを追加してIDを割り当てることができます。このIDをコード内で使用して、カスタムアクションとして処理できます。 たとえば、ユーザーが**ログイン**や**通知を許可**などのカスタムボタンをタップすると、デリゲートメソッド `onCustomAction` がビルダーのアクションIDとともに呼び出されます。"allowNotifications" のような独自のIDを作成できます。 ```kotlin showLineNumbers class YourActivity : AppCompatActivity() { private val eventListener = object : AdaptyOnboardingEventListener { override fun onCustomAction(action: AdaptyOnboardingCustomAction, context: Context) { when (action.actionId) { "allowNotifications" -> { // Request notification permissions } } } override fun onError(error: AdaptyOnboardingError, context: Context) { // Handle errors } // ... other required delegate methods } } ```
イベント例(クリックして展開) ```json { "actionId": "allowNotifications", "meta": { "onboardingId": "onboarding_123", "screenClientId": "profile_screen", "screenIndex": 0, "screensTotal": 3 } } ```
## オンボーディングを閉じる \{#closing-onboarding\} オンボーディングは、ユーザーが**閉じる**アクションが割り当てられたボタンをタップすると、閉じられたとみなされます。ユーザーがオンボーディングを閉じたときの動作を管理する必要があります。例: :::important ユーザーがオンボーディングを閉じたときの動作を管理する必要があります。たとえば、オンボーディング自体の表示を停止する処理が必要です。 ::: 例: ```kotlin override fun onCloseAction(action: AdaptyOnboardingCloseAction, context: Context) { // Dismiss the onboarding screen (context as? Activity)?.onBackPressed() } ```
イベント例(クリックして展開) ```json { "action_id": "close_button", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "final_screen", "screen_index": 3, "total_screens": 4 } } ```
## ペイウォールを開く \{#opening-a-paywall\} :::tip オンボーディング内でペイウォールを開きたい場合は、このイベントを処理してください。オンボーディングが閉じた後にペイウォールを開きたい場合は、[`AdaptyOnboardingCloseAction`](#closing-onboarding) を処理して、イベントデータに依存せずにペイウォールを開く方がシンプルです。 ::: オンボーディング内でペイウォールをシームレスに扱う最善の方法は、アクションIDをペイウォールのプレースメントIDと同じにすることです。こうすることで、`AdaptyOnboardingOpenPaywallAction` の後にプレースメントIDを使ってすぐにペイウォールを取得・表示できます: ```kotlin override fun onOpenPaywallAction(action: AdaptyOnboardingOpenPaywallAction, context: Context) { // Get the paywall using the placement ID from the action Adapty.getPaywall(placementId = action.actionId) { result -> when (result) { is AdaptyResult.Success -> { val paywall = result.value // Get the paywall configuration AdaptyUI.getViewConfiguration(paywall) { result -> when(result) { is AdaptyResult.Success -> { val paywallConfig = result.value // Create and present the paywall val paywallView = AdaptyUI.getPaywallView( activity = this, viewConfig = paywallConfig, products, eventListener = paywallEventListener ) // Add the paywall view to your layout binding.container.addView(paywallView) } is AdaptyResult.Error -> { val error = result.error // handle the error } } } is AdaptyResult.Error -> { val error = result.error // handle the error } } } } ```
イベント例(クリックして展開) ```json { "action_id": "premium_offer_1", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "pricing_screen", "screen_index": 2, "total_screens": 4 } } ```
## オンボーディングの読み込み完了 \{#finishing-loading-onboarding\} オンボーディングの読み込みが完了すると、このメソッドが呼び出されます: ```kotlin override fun onFinishLoading(action: AdaptyOnboardingLoadedAction, context: Context) { // Handle loading completion } ```
イベント例(クリックして展開) ```json { "meta": { "onboarding_id": "onboarding_123", "screen_cid": "welcome_screen", "screen_index": 0, "total_screens": 4 } } ```
## ナビゲーションイベント \{#navigation-events\} `onAnalyticsEvent` メソッドは、オンボーディングフロー中にさまざまなアナリティクスイベントが発生したときに呼び出されます。 `event` オブジェクトは以下のいずれかの型になります: | 型 | 説明 | |------------|-------------| | `OnboardingStarted` | オンボーディングが読み込まれたとき | | `ScreenPresented` | 任意の画面が表示されたとき | | `ScreenCompleted` | 画面が完了したとき。オプションの `elementId`(完了した要素の識別子)とオプションの `reply`(ユーザーからの返答)を含みます。ユーザーが画面を離れる操作を行ったときに発火します。 | | `SecondScreenPresented` | 2番目の画面が表示されたとき | | `UserEmailCollected` | 入力フィールドでユーザーのメールアドレスが収集されたとき | | `OnboardingCompleted` | ユーザーが `final` IDを持つ画面に到達したときに発火します。このイベントが必要な場合は、最後の画面に `final` IDを割り当ててください。 | | `Unknown` | 認識できないイベントタイプの場合。`name`(不明なイベントの名前)と `meta`(追加のメタデータ)を含みます。 | 各イベントには以下の `meta` 情報が含まれます: | フィールド | 説明 | |------------|-------------| | `onboardingId` | オンボーディングフローの一意の識別子 | | `screenClientId` | 現在の画面の識別子 | | `screenIndex` | フロー内での現在の画面の位置 | | `totalScreens` | フロー内の画面の総数 | アナリティクスイベントをトラッキングに使用する例: ```kotlin override fun onAnalyticsEvent(event: AdaptyOnboardingAnalyticsEvent, context: Context) { when (event) { is AdaptyOnboardingAnalyticsEvent.OnboardingStarted -> { // Track onboarding start trackEvent("onboarding_started", event.meta) } is AdaptyOnboardingAnalyticsEvent.ScreenPresented -> { // Track screen presentation trackEvent("screen_presented", event.meta) } is AdaptyOnboardingAnalyticsEvent.ScreenCompleted -> { // Track screen completion with user response trackEvent("screen_completed", event.meta, event.elementId, event.reply) } is AdaptyOnboardingAnalyticsEvent.OnboardingCompleted -> { // Track successful onboarding completion trackEvent("onboarding_completed", event.meta) } is AdaptyOnboardingAnalyticsEvent.Unknown -> { // Handle unknown events trackEvent(event.name, event.meta) } // Handle other cases as needed } } ```
イベント例(クリックして展開) ```javascript // OnboardingStarted { "name": "onboarding_started", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "welcome_screen", "screen_index": 0, "total_screens": 4 } } // ScreenPresented { "name": "screen_presented", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "interests_screen", "screen_index": 2, "total_screens": 4 } } // ScreenCompleted { "name": "screen_completed", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "profile_screen", "screen_index": 1, "total_screens": 4 }, "params": { "element_id": "profile_form", "reply": "success" } } // SecondScreenPresented { "name": "second_screen_presented", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "profile_screen", "screen_index": 1, "total_screens": 4 } } // UserEmailCollected { "name": "user_email_collected", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "profile_screen", "screen_index": 1, "total_screens": 4 } } // OnboardingCompleted { "name": "onboarding_completed", "meta": { "onboarding_id": "onboarding_123", "screen_cid": "final_screen", "screen_index": 3, "total_screens": 4 } } ```
--- # File: android-onboarding-input --- --- title: "Android SDKでオンボーディングのデータを処理する" description: "Adapty SDKを使ってAndroidアプリのオンボーディングデータを保存・活用する方法を説明します。" --- ユーザーがクイズの質問に回答したり、入力フィールドにデータを入力したりすると、`onStateUpdatedAction` メソッドが呼び出されます。コード内でフィールドの種類を保存したり処理したりできます。 例: ```kotlin override fun onStateUpdatedAction(action: AdaptyOnboardingStateUpdatedAction, context: Context) { // Store user preferences or responses when (val params = action.params) { is AdaptyOnboardingStateUpdatedParams.Select -> { // Handle single selection } is AdaptyOnboardingStateUpdatedParams.MultiSelect -> { // Handle multiple selections } is AdaptyOnboardingStateUpdatedParams.Input -> { // Handle text input } is AdaptyOnboardingStateUpdatedParams.DatePicker -> { // Handle date selection } } } ``` アクションのフォーマットは[こちら](https://android.adapty.io/adapty-ui/com.adapty.ui.onboardings.actions/-adapty-onboarding-state-updated-action/)でご確認ください。
保存されたデータの例(実装によってフォーマットが異なる場合があります) ```javascript // Example of a saved select action { "elementId": "preference_selector", "meta": { "onboardingId": "onboarding_123", "screenClientId": "preferences_screen", "screenIndex": 1, "screensTotal": 3 }, "params": { "type": "select", "value": { "id": "option_1", "value": "premium", "label": "Premium Plan" } } } // Example of a saved multi-select action { "elementId": "interests_selector", "meta": { "onboardingId": "onboarding_123", "screenClientId": "interests_screen", "screenIndex": 2, "screensTotal": 3 }, "params": { "type": "multiSelect", "value": [ { "id": "interest_1", "value": "sports", "label": "Sports" }, { "id": "interest_2", "value": "music", "label": "Music" } ] } } // Example of a saved input action { "elementId": "name_input", "meta": { "onboardingId": "onboarding_123", "screenClientId": "profile_screen", "screenIndex": 0, "screensTotal": 3 }, "params": { "type": "input", "value": { "type": "text", "value": "John Doe" } } } // Example of a saved date picker action { "elementId": "birthday_picker", "meta": { "onboardingId": "onboarding_123", "screenClientId": "profile_screen", "screenIndex": 0, "screensTotal": 3 }, "params": { "type": "datePicker", "value": { "day": 15, "month": 6, "year": 1990 } } } ```
## ユースケース \{#use-cases\} ### ユーザープロファイルをデータで充実させる \{#enrich-user-profiles-with-data\} 入力されたデータをユーザープロファイルにすぐ紐付けて、同じ情報を二度聞かないようにするには、アクションを処理するタイミングで入力データを使って[ユーザープロファイルを更新](android-setting-user-attributes)する必要があります。 たとえば、ID が `name` のテキストフィールドに名前を入力してもらい、その値をユーザーの名(first name)として設定したいとします。また、`email` フィールドにメールアドレスを入力してもらう場合、アプリのコードは次のようになります。 ```kotlin showLineNumbers override fun onStateUpdatedAction(action: AdaptyOnboardingStateUpdatedAction, context: Context) { // Store user preferences or responses when (val params = action.params) { is AdaptyOnboardingStateUpdatedParams.Input -> { // Handle text input val builder = AdaptyProfileParameters.Builder() // Map elementId to appropriate profile field when (action.elementId) { "name" -> { when (val inputParams = params.params) { is AdaptyOnboardingInputParams.Text -> { builder.withFirstName(inputParams.value) } } } "email" -> { when (val inputParams = params.params) { is AdaptyOnboardingInputParams.Email -> { builder.withEmail(inputParams.value) } } } } Adapty.updateProfile(builder.build()) { error -> if (error != null) { // handle the error } } } } } ``` ### 回答に基づいてペイウォールをカスタマイズする \{#customize-paywalls-based-on-answers\} オンボーディングのクイズを活用して、オンボーディング完了後にユーザーへ表示するペイウォールをカスタマイズすることもできます。 たとえば、スポーツの経験について質問し、ユーザーグループごとに異なる CTA やプロダクトを表示できます。 1. オンボーディングビルダーで[クイズを追加](onboarding-quizzes)し、各選択肢に意味のある ID を割り当てます。 2. ID に基づいてクイズの回答を処理し、ユーザーに[カスタム属性を設定](android-setting-user-attributes)します。 ```kotlin showLineNumbers override fun onStateUpdatedAction(action: AdaptyOnboardingStateUpdatedAction, context: Context) { // Handle quiz responses and set custom attributes when (val params = action.params) { is AdaptyOnboardingStateUpdatedParams.Select -> { // Handle quiz selection val builder = AdaptyProfileParameters.Builder() // Map quiz responses to custom attributes when (action.elementId) { "experience" -> { // Set custom attribute 'experience' with the selected value (beginner, amateur, pro) builder.withCustomAttribute("experience", params.params.value) } } Adapty.updateProfile(builder.build()) { error -> if (error != null) { // handle the error } } } } } ``` 3. カスタム属性の値ごとに[セグメントを作成](segments)します。 4. [プレースメント](placements)を作成し、作成した各セグメントに対して[オーディエンス](audience)を追加します。 5. アプリのコードでそのプレースメントの[ペイウォールを表示](android-paywalls)します。オンボーディングにペイウォールを開くボタンがある場合は、[そのボタンのアクションへの応答](android-handle-onboarding-events#opening-a-paywall)としてペイウォールのコードを実装してください。 Human --- # File: android-sdk-call-order --- --- title: "Android SDKの呼び出し順序" description: "Adapty SDKのメソッドを正しい順序で呼び出すことで、プレミアムアクセスの喪失、アトリビューションの欠落、断続的なADAPTY_NOT_INITIALIZEDエラーを回避できます。" --- `Adapty.activate()` が完了してから、他のAdapty SDKメソッドを呼び出す必要があります。完了するまでSDKは状態を持ちません。`activate()` の前または並行して発行された呼び出しはすべて [`ADAPTY_NOT_INITIALIZED`](android-sdk-error-handling) で失敗します。 アプリがユーザーを認証し、起動後にカスタマーユーザーIDを取得する場合は、そのタイミングで `Adapty.identify()` を呼び出してください。`identify` の完了コールバックが発火するまで、ユーザー操作に関わるメソッドを呼び出さないようにしてください。`identify` と競合する呼び出しは、コールバックでエラーが返るか、アクティベーション時に作成された匿名プロファイルに対して処理されます。この状態になると、アトリビューション、`appsflyer_id` などのMMP ID、インストールの所有権が識別済みプロファイルに正しく引き継がれないことがあります。アプリがユーザーを認証しない場合は `identify` をスキップし、匿名プロファイルのまま利用を続けてください。 MMP・アナリティクスSDK(AppsFlyer、Adjust、Branch、PostHog)も同じルールに従います。先にそれらを初期化し、UIDコールバックを待ってから `Adapty.activate` を呼び出してください。そうしないと、MMP IDが一時的な匿名プロファイルに紐付けられ、識別済みプロファイルに必ずしも引き継がれません。AppsFlyer固有の詳細については、[AppsFlyer](appsflyer) を参照してください。 ## 正しい順序 \{#the-correct-order\} どのパスをたどるかは、カスタマーユーザーIDをいつ取得するか、そしてMMPやアナリティクスSDKを使用するかどうかによって異なります。 - **ステップ2と5**: すべてのアプリで必須です。SDKをアクティベートしてから、SDKメソッドを呼び出します。 - **ステップ1と3**: MMPまたはアナリティクスSDK(AppsFlyer、Adjust、Branch、PostHog)を連携する場合のみ必要です。 - **ステップ4**: アプリがユーザーを認証し、起動後にカスタマーユーザーIDを収集する場合のみ必要です。 アプリ起動時にカスタマーユーザーIDが取得できる場合は、`activate()` を呼び出す前に(ステップ2a)`AdaptyConfig.Builder` に渡してください。このパスでは匿名プロファイルが作成されないため、ステップ4は不要です。 | ステップ | 呼び出し | タイミング | 備考 | |------|---------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------| | 1 | MMPまたはアナリティクスSDKの初期化(AppsFlyer、Adjust、PostHog、Branch) | アプリ起動時、最初に | MMPのUIDコールバック(例: `getAppsFlyerUID`)を待つこと。 | | 2a | `Adapty.activate(context, AdaptyConfig.Builder("KEY").withCustomerUserId(...).build())` | アプリ起動時、ステップ1の後、カスタマーユーザーIDが取得できる場合 | 推奨。匿名プロファイルは一切作成されない。 | | 2b | `Adapty.activate(context, AdaptyConfig.Builder("KEY").build())` — `customerUserId` なし | アプリ起動時、ステップ1の後、カスタマーユーザーIDが取得できない場合(または取得しない場合) | Adaptyが匿名プロファイルを作成する。 | | 3 | 各MMPに対して `Adapty.setIntegrationIdentifier("appsflyer_id", uid)` | ステップ2の後、ユーザー操作の呼び出しより前 | MMP IDを正しいプロファイルに紐付けるために必要。 | | 4 | `Adapty.identify("YOUR_USER_ID") { error -> ... }` | ステップ3の後(MMPがない場合はステップ2の後)、ステップ5より前 — 認証ありのパス2bのみ | 完了コールバックを使用すること。`identify` 中の並行呼び出しは匿名プロファイルに対して処理される場合がある。 | | 5 | `getPaywall`、`getPaywallProducts`、`restorePurchases`、`makePurchase`、`updateAttribution`、`updateProfile` | `identify` を呼び出す場合はステップ4の後、それ以外はステップ3の後(またはMMPがない場合はステップ2の後) | これらの呼び出しには安定したプロファイルが必要。 | :::important これらのステップをスキップすると、再インストールユーザーのプレミアムアクセスが失われたり、プロファイルに `appsflyer_id` が記録されなかったり、誤ったオーディエンスに対してペイウォールが返されたりする原因となります。 ::: ## Web2appおよびウェブファネル経由のインストール \{#web2app-and-web-funnel-installs\} ユーザーがウェブチェックアウト(Stripe、Paddle)で購入し、後からネイティブアプリをインストールした場合、デバイス初回の `activate()` により新しい匿名プロファイルが作成されます。このプロファイルはウェブプロファイルとは紐付けられません。認証フローやインストールリファラーなどからアプリ起動前にカスタマーユーザーIDを解決できる場合は、`AdaptyConfig.Builder` に直接渡してください。それ以外の場合、`identify("YOUR_USER_ID")` を呼び出して `restorePurchases` を実行するまで、ウェブでの購入はデバイス上に表示されません。 各ウェブチェックアウトで送信するメタデータについては、以下を参照してください。 - [Stripe](stripe) - [Paddle](paddle) --- # File: android-optimize-paywall-fetching --- --- title: "Android SDKでペイウォールの取得を最適化する" description: "Android向けにAdaptyペイウォールを確実に取得する:タイミング、キャッシュ、フォールバックのパターン。" --- Android上での信頼性の高いペイウォール取得は、3つのことを実現します:高速なレンダリング、オーディエンスターゲティングされたペイウォールの返却、そしてネットワークが遅い場合のグレースフルなフォールバック。以下のルールは、これを実現するためのタイミング、キャッシュ、フォールバックのパターンをカバーしています。 :::tip これらのルールは、`Adapty.activate()` と `Adapty.identify()` がすでに完了していることを前提としています。[Android SDKの呼び出し順序](android-sdk-call-order)を参照してください。 ::: ## ルールと注意点 \{#rules-and-pitfalls\} | こうする | こうしない | 理由 | |---|---|---| | これから表示するプレースメントを取得する。 | 起動時にすべてのプレースメントを並列でプリフェッチする。 | 一括プリフェッチはメインスレッドをブロックし、バースト中にブラックスクリーンが表示される。 | | アトリビューションが解決される機会を持った後に `getPaywall` を取得する — たとえば、`activate` の1〜2秒後、または `setOnProfileUpdatedListener` が発火した後。 | `Application.onCreate()` で `getPaywall` を呼び出す。 | アトリビューションがまだ反映されていない。ペイウォールはデフォルトのオーディエンスに対して解決され、セグメントやASAのパーソナライゼーションが暗黙的にスキップされる。 | | `loadTimeout` を設定し、すべてのプレースメントに[フォールバックペイウォール](fallback-paywalls)を設定する。 | `getPaywall` を無期限に待つ。 | タイムアウトがないと、接続が不安定なユーザーはネットワークが解決するまで、またはアプリを閉じるまで空白の画面を見続けることになる。 | `fetchPolicy` と `loadTimeout` パラメーターのリファレンスは[ペイウォールとプロダクトの取得](fetch-paywalls-and-products-android)を、適切なプレースメントの選び方は[プレースメント](placements)を参照してください。 ## 接続が不安定な環境向けのチューニング \{#tune-for-poor-connectivity\} 接続が常に不安定な市場(農村部、交通機関、ルーティングの問題が多い地域)向けには: - 最初の取得を除くすべての取得で、`fetchPolicy` を `AdaptyPlacementFetchPolicy.ReturnCacheDataElseLoad` に設定する。 - Adapty ダッシュボードのすべてのプレースメントに[フォールバックペイウォール](fallback-paywalls)を設定する。 - `loadTimeout` を3〜5秒に設定し、タイムアウト発生時はフォールバックを受け入れる。 - `getProfile` にペイウォールの表示を依存させない。`getPaywall` は独立して呼び出し、プロファイルの取得が遅くてもUIをブロックしないようにする。 --- # File: android-test --- --- title: "Android SDKのテストとリリース" description: "AdaptyでAndroidアプリのサブスクリプション状態を確認する方法を学びます。" --- AdaptyのSDKをAndroidアプリに実装済みの場合は、すべてが正しく設定されており、購入が期待通りに動作することをテストする必要があります。これには、SDK統合のテストと、Google Playのサンドボックス環境での実際の購入フローのテストが含まれます。 ## アプリをテストする \{#test-your-app\} サンドボックステストやクローズドトラックの検証を含む、アプリ内課金の包括的なテスト方法については、[テストガイド](testing-on-android)をご覧ください。 ## リリースの準備 \{#prepare-for-release\} アプリをストアに申請する前に、[リリースチェックリスト](release-checklist)に従って以下を確認してください: - ストア接続とサーバー通知が設定されている - 購入が完了し、Adaptyに報告されている - アクセスが正しくアンロックおよび復元される - プライバシーとレビューの要件が満たされている --- # File: android-sdk-error-handling --- --- title: "Android SDKのエラーを処理する" description: "AdaptyのトラブルシューティングガイドでAndroid SDKのエラーを効果的に処理しましょう。" --- SDKから返されるエラーはすべて `AdaptyError` です。 :::tip **デバッグ前に詳細ログを有効にしてください。** ほとんどの `AdaptyError` は、Play Billing、ネットワーク、またはバックエンドのエラーをラップしています。詳細ログを有効にすると(`Adapty.logLevel = AdaptyLogLevel.VERBOSE` — [ログ記録](sdk-installation-android#logging)を参照)、ラップされたエラーがコンソールに出力され、実際の原因がわかることがほとんどです。 ::: :::important これらの解決策で問題が解決しない場合は、サポートに問い合わせる前に[その他の問題](#other-issues)を参照して、より効率的にサポートできるよう手順をご確認ください。 ::: | エラー | 解決策 | |----------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | UNKNOWN | 不明または予期しないエラーが発生したことを示します。 | | [ITEM_UNAVAILABLE](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_UNAVAILABLE()) | このエラーは主にテスト段階で発生します。プロダクトが本番環境に存在しないか、ユーザーが Google Play のテスターグループに属していない可能性があります。 | | ADAPTY_NOT_INITIALIZED | Adapty SDK が有効化されていません。
スプラッシュスクリーンや初期の UI フックが `Adapty.activate` の完了前に Adapty のメソッドを呼び出している場合によく見られます。実機ではエミュレーターと実行タイミングが異なるため、再現しないこともあります。`Adapty.activate` が完了してから、他の SDK 呼び出しを行うようにしてください。完全な手順については [Android SDK の呼び出し順序](android-sdk-call-order) を参照してください。また、`Adapty.activate` メソッドを使用して [Adapty SDK を正しく設定](sdk-installation-android#activate-adapty-module-of-adapty-sdk) する必要があります。 | | PROFILE_WAS_CHANGED | 操作中にユーザープロファイルが変更されました。
`Adapty.identify` の実行中に別のメソッドを呼び出すと発生します。実行中の呼び出しが切り替え直前のプロファイルに対して行われ、SDK によって拒否されます。`Adapty.identify` の完了後に他の SDK 呼び出しを行うようにしてください。[Android SDK の呼び出し順序](android-sdk-call-order) を参照してください。 | | PRODUCT_NOT_FOUND | 購入しようとしたプロダクトがストアで利用できないことを示します。 | | INVALID_JSON |

ローカルのフォールバックペイウォール JSON が無効です。

デフォルトの英語のペイウォールを修正してから、無効なローカルペイウォールを置き換えてください。ペイウォールの修正方法については [リモートコンフィグでペイウォールをカスタマイズする](customize-paywall-with-remote-config) を、ローカルペイウォールの置き換え方法については [ローカルフォールバックペイウォールを定義する](fallback-paywalls) を参照してください。

| |

CURRENT_SUBSCRIPTION_TO_UPDATE

\_NOT_FOUND_IN_HISTORY

| 置き換え対象の元のサブスクリプションが有効なサブスクリプションの中に見つかりません。 | | [BILLING_SERVICE_TIMEOUT](https://developer.android.com/google/play/billing/errors#service_timeout_error_code_-3) | Google Play が応答する前にリクエストが最大タイムアウトに達したことを示します。Play Billing Library の呼び出しで要求されたアクションの実行が遅延した場合などに発生します。 | | [FEATURE_NOT_SUPPORTED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#FEATURE_NOT_SUPPORTED()) | 要求された機能が現在のデバイスの Play Store でサポートされていません。 | | [BILLING_SERVICE_DISCONNECTED](https://developer.android.com/google/play/billing/errors#service_disconnected_error_code_-1) | クライアントアプリと `BillingClient` 経由の Google Play Store サービスとの接続が切断されたことを示します。 | | [BILLING_SERVICE_UNAVAILABLE](https://developer.android.com/google/play/billing/errors#service_unavailable_error_code_2) | Google Play Billing サービスが現在利用できないことを示します。ほとんどの場合、クライアントデバイスと Google Play Billing サービスの間のどこかでネットワーク接続の問題が発生しています。 | | [BILLING_UNAVAILABLE](https://developer.android.com/google/play/billing/errors#billing_unavailable_error_code_3) |

購入プロセス中に請求に関する問題が発生したことを示します。考えられる原因は以下のとおりです:

1. ユーザーのデバイスに Play Store アプリがインストールされていないか、古いバージョンです。

2. ユーザーがサポートされていない国にいます。

3. ユーザーが、管理者によって購入が無効化されているエンタープライズアカウントに属しています。

4. Google Play がユーザーの支払い方法に請求できませんでした(例:クレジットカードの有効期限切れ)。

5. ユーザーが Play Store アプリにログインしていません。

| | [DEVELOPER_ERROR](https://developer.android.com/google/play/billing/errors#developer_error) | API の使い方が正しくないことを示します。 | | [BILLING_ERROR](https://developer.android.com/google/play/billing/errors#error_error_code_6) | Google Play 自体の内部的な問題を示します。 | | [ITEM_ALREADY_OWNED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_ALREADY_OWNED()) | そのプロダクトはすでに購入済みです。 | | [ITEM_NOT_OWNED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_NOT_OWNED()) | ユーザーがそのアイテムを所有していないため、要求されたアクションが失敗したことを示します。 | | [BILLING_NETWORK_ERROR](https://developer.android.com/google/play/billing/errors#network_error_error_code_12) | デバイスと Play のシステム間のネットワーク接続に問題があったことを示します。 | | NO_PRODUCT_IDS_FOUND |

ペイウォール内のプロダクトがいずれもストアで利用できないことを示します。

このエラーが発生した場合は、以下の手順で解決してください:

  1. すべてのプロダクトが Adapty ダッシュボードに追加されているか確認してください。
  2. アプリの **Package name** が Google Play Console のものと一致していることを確認してください。
  3. アプリストアのプロダクト ID がダッシュボードに追加したものと一致していることを確認してください。ストアにすでに Bundle ID が含まれている場合を除き、ID に Bundle ID を含めないようにしてください。
  4. Google の税設定でアプリの有料ステータスが **Active** になっていることを確認してください。税情報が最新であり、証明書が有効であることも確認してください。
  5. 収益化の対象となるよう、アプリに銀行口座が紐付けられているか確認してください。
  6. プロダクトがお住まいの地域で利用可能か確認してください。
  7. アプリがいずれかのテストトラックに登録されていることを確認してください。**Internal testing** トラックはレビュー不要でアプリが顧客に公開されないため、最も手軽な選択肢です。
| | NO_PURCHASES_TO_RESTORE | Google Play が復元する購入を見つけられなかったことを示します。 | | AUTHENTICATION_ERROR | `Adapty.activate` メソッドを使用して [Adapty SDK を正しく設定](sdk-installation-android#activate-adapty-module-of-adapty-sdk) する必要があります。 | | BAD_REQUEST | リクエストが不正です。
[Google Play との連携](google-play-store-connection-configuration) に必要なすべての手順を完了していることを確認してください。 | | SERVER_ERROR | サーバーエラーです。 | | REQUEST_FAILED | 正確に特定できないネットワークの問題を示します。 | | DECODING_FAILED | レスポンスのデコードに失敗しました。
コードを確認し、送信しているパラメータが有効であることを確認してください。例えば、無効な API キーを使用している場合にもこのエラーが発生することがあります。 | | ANALYTICS_DISABLED | [無効化されている](analytics-integration#disabling-external-analytics-for-a-specific-customer) ため、アナリティクスイベントを処理できません。 | | WRONG_PARAMETER | パラメータの一部が正しくないことを示します。空白にできない箇所が空白になっている、型が間違っているなどが原因として考えられます。 | ## その他の問題 \{#other-issues\} まだ解決策が見つかっていない場合は、次のステップを試してみてください。 - **SDKを最新バージョンにアップグレードする**: 最新のSDKバージョンは安定性が高く、既知の問題の修正が含まれているため、常にアップグレードをおすすめします。 - **サポートチームへの問い合わせ、またはコミュニティでの質問**: [サポートフォーラム](https://adapty.featurebase.app/)で他の開発者に質問することもできます。 - **[support@adapty.io](mailto:support@adapty.io) またはチャットでサポートチームに連絡する**: SDKのアップグレードが難しい場合や、アップグレードしても解決しない場合は、サポートチームにお問い合わせください。[詳細ログを有効化](sdk-installation-android#logging)してログを共有いただくと、問題の解決が早くなります。関連するコードスニペットを添付することもできます。 --- # File: migration-to-android-312 --- --- title: "Adapty Android SDK を v3.12 に移行する" description: "パフォーマンス向上と新しいマネタイズ機能のために Adapty Android SDK v3.12 に移行する。" --- Adapty SDK 3.12.0 では、`logShowOnboarding` メソッドを SDK から削除しました。 このメソッドを使用していた場合、SDK をバージョン 3.12 以降にアップグレードすると利用できなくなります。 代わりに、[Adapty のノーコード オンボーディングビルダーでオンボーディングを作成](onboardings)できます。これらのオンボーディングの分析は自動的に追跡され、カスタマイズオプションも豊富に用意されています。 --- # File: migration-to-android-310 --- --- title: "Android Adapty SDK 3.10.0 移行ガイド" description: "" --- Adapty SDK 3.10.0 はメジャーリリースであり、いくつかの改善が含まれていますが、移行作業が必要な場合があります。 1. `AdaptyUiPersonalizedOfferResolver` が削除されました。使用している場合は、`onAwaitingPurchaseParams` コールバックで渡してください。 2. ペイウォールビルダーのペイウォールで使用している `onAwaitingSubscriptionUpdateParams` メソッドのシグネチャを更新してください。 ## 購入パラメータコールバックの更新 \{#update-purchase-parameters-callback\} `onAwaitingSubscriptionUpdateParams` メソッドは `onAwaitingPurchaseParams` に名称変更され、`AdaptySubscriptionUpdateParameters` の代わりに `AdaptyPurchaseParameters` を使用するようになりました。これにより、サブスクリプション切り替えパラメータ(クロスグレード)の指定、価格が個人向けかどうかの指定([詳細はこちら](https://developer.android.com/google/play/billing/integrate#personalized-price))、その他の購入パラメータを設定できます。 ```diff showLineNumbers - override fun onAwaitingSubscriptionUpdateParams( - product: AdaptyPaywallProduct, - context: Context, - onSubscriptionUpdateParamsReceived: SubscriptionUpdateParamsCallback, - ) { - onSubscriptionUpdateParamsReceived(AdaptySubscriptionUpdateParameters(...)) - } + override fun onAwaitingPurchaseParams( + product: AdaptyPaywallProduct, + context: Context, + onPurchaseParamsReceived: AdaptyUiEventListener.PurchaseParamsCallback, + ): AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked { + onPurchaseParamsReceived( + AdaptyPurchaseParameters.Builder() + .withSubscriptionUpdateParams(AdaptySubscriptionUpdateParameters(...)) + .withOfferPersonalized(true) + .build() + ) + return AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked + } ``` 追加パラメータが不要な場合は、次のように記述できます。 ```kotlin showLineNumbers + override fun onAwaitingPurchaseParams( product: AdaptyPaywallProduct, context: Context, onPurchaseParamsReceived: AdaptyUiEventListener.PurchaseParamsCallback, ): AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked { onPurchaseParamsReceived(AdaptyPurchaseParameters.Empty) return AdaptyUiEventListener.PurchaseParamsCallback.IveBeenInvoked } ``` --- # File: migration-to-android-sdk-34 --- --- title: "Adapty Android SDK を v3.4 へ移行する" description: "Adapty Android SDK v3.4 への移行で、パフォーマンス向上と新しいマネタイズ機能を活用しましょう。" --- Adapty SDK 3.4.0 はメジャーリリースであり、お客様側での移行作業が必要な改善が含まれています。 ## フォールバックペイウォールファイルの更新 \{#update-fallback-paywall-files\} 新しい SDK バージョンとの互換性を確保するため、フォールバックペイウォールファイルを更新してください。 1. Adapty ダッシュボードから[更新済みのフォールバックペイウォールファイルをダウンロード](fallback-paywalls)します。 2. モバイルアプリ内の[既存のフォールバックペイウォールを新しいファイルに置き換え](android-use-fallback-paywalls)ます。 ## オブザーバーモードの実装を更新する \{#update-implementation-of-observer-mode\} オブザーバーモードを使用している場合は、その実装を更新してください。 以前のバージョンでは、オブザーバーモードで Adapty が独自インフラ経由のトランザクションに直接アクセスできないため、Adapty に認識させるには購入を復元する必要がありました。ペイウォールを使用していた場合は、各トランザクションをそれを起点としたペイウォールに手動で紐付ける必要もありました。 新しいバージョンでは、Adapty にトランザクションを認識させるために各トランザクションを明示的にレポートする必要があります。ペイウォールを使用している場合は、トランザクションを使用したペイウォールに紐付けるためにバリエーション ID も渡す必要があります。 :::warning **トランザクションのレポートを省略しないでください!** `reportTransaction` を呼び出さないと、Adapty はトランザクションを認識できず、アナリティクスに表示されず、インテグレーションにも送信されません。 ::: ```diff showLineNumbers - Adapty.restorePurchases { result -> - if (result is AdaptyResult.Success) { - // success - } - } - - Adapty.setVariationId(transactionId, variationId) { error -> - if (error == null) { - // success - } - } + val transactionInfo = TransactionInfo.fromPurchase(purchase) + + Adapty.reportTransaction(transactionInfo, variationId) { result -> + if (result is AdaptyResult.Success) { + // success + } + } ``` ```diff showLineNumbers - Adapty.restorePurchases(result -> { - if (result instanceof AdaptyResult.Success) { - // success - } - }); - - Adapty.setVariationId(transactionId, variationId, error -> { - if (error == null) { - // success - } - }); + TransactionInfo transactionInfo = TransactionInfo.fromPurchase(purchase); + + Adapty.reportTransaction(transactionInfo, variationId, result -> { + if (result instanceof AdaptyResult.Success) { + // success + } + }); ``` --- # File: migration-to-android330 --- --- title: "Adapty Android SDK を v3.3 に移行する" description: "パフォーマンス向上と新しいマネタイズ機能のために Adapty Android SDK v3.3 に移行します。" --- Adapty SDK 3.3.0 はメジャーリリースであり、いくつかの改善が含まれていますが、移行手順が必要になる場合があります。 1. ペイウォールビルダーで作成されていないペイウォールでの購入処理を更新してください。`USER_CANCELED` および `PENDING_PURCHASE` エラーコードの処理を停止してください。キャンセルされた購入はエラーとして扱われなくなり、エラーなしの購入結果として返されます。 2. ペイウォールビルダーで作成されたペイウォールの `onPurchaseCanceled` および `onPurchaseSuccess` イベントを、新しい `onPurchaseFinished` イベントに置き換えてください。この変更も同じ理由です:キャンセルされた購入はエラーとして扱われなくなり、エラーなしの購入結果に含まれます。 3. ペイウォールビルダーのペイウォールに対する `onAwaitingSubscriptionUpdateParams` のメソッドシグネチャを変更してください。 4. ファイル URI を直接渡してフォールバックペイウォールを提供している場合は、その方法を更新してください。 5. Adjust、AirBridge、Amplitude、AppMetrica、Appsflyer、Branch、Facebook Ads、Firebase and Google Analytics、Mixpanel、OneSignal、Pushwoosh のインテグレーション設定を更新してください。 ## 購入処理の更新 \{#update-making-purchase\} 以前は、キャンセルされた購入と保留中の購入はエラーとして扱われ、それぞれ `USER_CANCELED` および `PENDING_PURCHASE` コードが返されていました。 新しい `AdaptyPurchaseResult` クラスを使用して、キャンセル・成功・保留中の購入を示すようになりました。以下のように購入コードを更新してください: ~~~diff Adapty.makePurchase(activity, product) { result -> when (result) { is AdaptyResult.Success -> { - val info = result.value - val profile = info?.profile - - if (profile?.accessLevels?.get("YOUR_ACCESS_LEVEL")?.isActive == true) { - // Grant access to the paid features - } + when (val purchaseResult = result.value) { + is AdaptyPurchaseResult.Success -> { + val profile = purchaseResult.profile + if (profile.accessLevels["YOUR_ACCESS_LEVEL"]?.isActive == true) { + // Grant access to the paid features + } + } + + is AdaptyPurchaseResult.UserCanceled -> { + // Handle the case where the user canceled the purchase + } + + is AdaptyPurchaseResult.Pending -> { + // Handle deferred purchases (e.g., the user will pay offline with cash + } + } } is AdaptyResult.Error -> { val error = result.error // Handle the error } } } ~~~ 完全なコード例については、[モバイルアプリで購入する](android-making-purchases#make-purchase) ページをご覧ください。 ## ペイウォールビルダーの購入イベントを変更する \{#modify-paywall-builder-purchase-events\} 1. `onPurchaseFinished` イベントを追加します: ```diff showLineNumbers + public override fun onPurchaseFinished( + purchaseResult: AdaptyPurchaseResult, + product: AdaptyPaywallProduct, + context: Context, + ) { + when (purchaseResult) { + is AdaptyPurchaseResult.Success -> { + // Grant access to the paid features + } + is AdaptyPurchaseResult.UserCanceled -> { + // Handle the case where the user canceled the purchase + } + is AdaptyPurchaseResult.Pending -> { + // Handle deferred purchases (e.g., the user will pay offline with cash) + } + } + } ``` 完全なコード例については、[成功・キャンセル・保留中の購入](android-handling-events#successful-canceled-or-pending-purchase) とイベントの説明をご覧ください。 2. `onPurchaseCancelled` イベントの処理を削除します: ```diff showLineNumbers - public override fun onPurchaseCanceled( - product: AdaptyPaywallProduct, - context: Context, - ) {} ``` 3. `onPurchaseSuccess` を削除します: ```diff showLineNumbers - public override fun onPurchaseSuccess( - profile: AdaptyProfile?, - product: AdaptyPaywallProduct, - context: Context, - ) { - // Your logic on successful purchase - } ``` ## onAwaitingSubscriptionUpdateParams メソッドのシグネチャを変更する \{#change-the-signature-of--onawaitingsubscriptionupdateparams-method\} 別のサブスクリプションがアクティブな状態で新しいサブスクリプションが購入された場合、新しいサブスクリプションで既存のサブスクリプションを置き換えるには `onSubscriptionUpdateParamsReceived(AdaptySubscriptionUpdateParameters...))` を、既存のサブスクリプションをアクティブに維持しながら新しいサブスクリプションを別途追加するには `onSubscriptionUpdateParamsReceived(null)` を呼び出してください: ```diff showLineNumbers - public override fun onAwaitingSubscriptionUpdateParams( - product: AdaptyPaywallProduct, - context: Context, - ): AdaptySubscriptionUpdateParameters? { - return AdaptySubscriptionUpdateParameters(...) - } + public override fun onAwaitingSubscriptionUpdateParams( + product: AdaptyPaywallProduct, + context: Context, + onSubscriptionUpdateParamsReceived: SubscriptionUpdateParamsCallback, + ) { + onSubscriptionUpdateParamsReceived(AdaptySubscriptionUpdateParameters(...)) + } ``` 最終的なコード例については、[サブスクリプションのアップグレード](android-handling-events#upgrade-subscription) のドキュメントセクションをご覧ください。 ## フォールバックペイウォールの提供方法を更新する \{#update-providing-fallback-paywalls\} フォールバックペイウォールを提供するためにファイル URI を渡している場合は、以下のように更新してください: ```diff showLineNumbers val fileUri: Uri = // Get the URI for the file with fallback paywalls - Adapty.setFallbackPaywalls(fileUri, callback) + Adapty.setFallbackPaywalls(FileLocation.fromFileUri(fileUri), callback) ``` ```diff showLineNumbers Uri fileUri = // Get the URI for the file with fallback paywalls - Adapty.setFallbackPaywalls(fileUri, callback); + Adapty.setFallbackPaywalls(FileLocation.fromFileUri(fileUri), callback); ``` ## サードパーティインテグレーションの SDK 設定を更新する \{#update-third-party-integration-sdk-configuration\} Adapty Android SDK 3.3.0 以降でインテグレーションが正しく動作するように、以下のセクションに従って各インテグレーションの SDK 設定を更新してください。 ### Adjust 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[Adjust インテグレーションの SDK 設定](adjust#connect-your-app-to-adjust) をご覧ください。 ```diff showLineNumbers - Adjust.getAttribution { attribution -> - if (attribution == null) return@getAttribution - - Adjust.getAdid { adid -> - if (adid == null) return@getAdid - - Adapty.updateAttribution(attribution, AdaptyAttributionSource.ADJUST, adid) { error -> - // Handle the error - } - } - } + Adjust.getAdid { adid -> + if (adid == null) return@getAdid + + Adapty.setIntegrationIdentifier("adjust_device_id", adid) { error -> + if (error != null) { + // Handle the error + } + } + } + + Adjust.getAttribution { attribution -> + if (attribution == null) return@getAttribution + + Adapty.updateAttribution(attribution, "adjust") { error -> + if (error != null) { + // Handle the error + } + } + } ``` ```diff showLineNumbers val config = AdjustConfig(context, adjustAppToken, environment) config.setOnAttributionChangedListener { attribution -> attribution?.let { attribution -> - Adapty.updateAttribution(attribution, AdaptyAttributionSource.ADJUST) { error -> + Adapty.updateAttribution(attribution, "adjust") { error -> if (error != null) { // Handle the error } } } } Adjust.onCreate(config) ``` ### AirBridge 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[AirBridge インテグレーションの SDK 設定](airbridge#connect-your-app-to-airbridge) をご覧ください。 ```diff showLineNumbers Airbridge.getDeviceInfo().getUUID(object: AirbridgeCallback.SimpleCallback() { override fun onSuccess(result: String) { - val params = AdaptyProfileParameters.Builder() - .withAirbridgeDeviceId(result) - .build() - Adapty.updateProfile(params) { error -> - if (error != null) { - // Handle the error - } - } + Adapty.setIntegrationIdentifier("airbridge_device_id", result) { error -> + if (error != null) { + // Handle the error + } + } } override fun onFailure(throwable: Throwable) { } }) ``` ### Amplitude 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[Amplitude インテグレーションの SDK 設定](amplitude#sdk-configuration) をご覧ください。 ```diff showLineNumbers // For Amplitude maintenance SDK (obsolete) val amplitude = Amplitude.getInstance() val amplitudeDeviceId = amplitude.getDeviceId() val amplitudeUserId = amplitude.getUserId() //for actual Amplitude Kotlin SDK val amplitude = Amplitude( Configuration( apiKey = AMPLITUDE_API_KEY, context = applicationContext ) ) val amplitudeDeviceId = amplitude.store.deviceId val amplitudeUserId = amplitude.store.userId // - val params = AdaptyProfileParameters.Builder() - .withAmplitudeDeviceId(amplitudeDeviceId) - .withAmplitudeUserId(amplitudeUserId) - .build() - Adapty.updateProfile(params) { error -> - if (error != null) { - // Handle the error - } - } + Adapty.setIntegrationIdentifier("amplitude_user_id", amplitudeUserId) { error -> + if (error != null) { + // Handle the error + } + } + Adapty.setIntegrationIdentifier("amplitude_device_id", amplitudeDeviceId) { error -> + if (error != null) { + // Handle the error + } + } ``` ### AppMetrica 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[AppMetrica インテグレーションの SDK 設定](appmetrica#sdk-configuration) をご覧ください。 ```diff showLineNumbers val startupParamsCallback = object: StartupParamsCallback { override fun onReceive(result: StartupParamsCallback.Result?) { val deviceId = result?.deviceId ?: return - val params = AdaptyProfileParameters.Builder() - .withAppmetricaDeviceId(deviceId) - .withAppmetricaProfileId("YOUR_ADAPTY_CUSTOMER_USER_ID") - .build() - Adapty.updateProfile(params) { error -> - if (error != null) { - // Handle the error - } - } + Adapty.setIntegrationIdentifier("appmetrica_device_id", deviceId) { error -> + if (error != null) { + // Handle the error + } + } + + Adapty.setIntegrationIdentifier("appmetrica_profile_id", "YOUR_ADAPTY_CUSTOMER_USER_ID") { error -> + if (error != null) { + // Handle the error + } + } } override fun onRequestError( reason: StartupParamsCallback.Reason, result: StartupParamsCallback.Result? ) { // Handle the error } } AppMetrica.requestStartupParams(context, startupParamsCallback, listOf(StartupParamsCallback.APPMETRICA_DEVICE_ID)) ``` ### AppsFlyer 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[AppsFlyer インテグレーションの SDK 設定](appsflyer#connect-your-app-to-appsflyer) をご覧ください。 ```diff showLineNumbers val conversionListener: AppsFlyerConversionListener = object : AppsFlyerConversionListener { override fun onConversionDataSuccess(conversionData: Map) { - Adapty.updateAttribution( - conversionData, - AdaptyAttributionSource.APPSFLYER, - AppsFlyerLib.getInstance().getAppsFlyerUID(context) - ) { error -> - if (error != null) { - // Handle the error - } - } + val uid = AppsFlyerLib.getInstance().getAppsFlyerUID(context) + Adapty.setIntegrationIdentifier("appsflyer_id", uid) { error -> + if (error != null) { + // Handle the error + } + } + Adapty.updateAttribution(conversionData, "appsflyer") { error -> + if (error != null) { + // Handle the error + } + } } } ``` ### Branch 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[Branch インテグレーションの SDK 設定](branch#connect-your-app-to-branch) をご覧ください。 ```diff showLineNumbers // Login and update attribution Branch.getAutoInstance(this) .setIdentity("YOUR_USER_ID") { referringParams, error -> referringParams?.let { data -> - Adapty.updateAttribution(data, AdaptyAttributionSource.BRANCH) { error -> - if (error != null) { - // Handle the error - } - } + Adapty.updateAttribution(data, "branch") { error -> + if (error != null) { + // Handle the error + } + } } } // Logout Branch.getAutoInstance(context).logout() ``` ### Facebook Ads 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[Facebook Ads インテグレーションの SDK 設定](facebook-ads#connect-your-app-to-facebook-ads) をご覧ください。 ```diff showLineNumbers - val builder = AdaptyProfileParameters.Builder() - .withFacebookAnonymousId(AppEventsLogger.getAnonymousAppDeviceGUID(context)) - - Adapty.updateProfile(builder.build()) { error -> - if (error != null) { - // Handle the error - } - } + Adapty.setIntegrationIdentifier( + "facebook_anonymous_id", + AppEventsLogger.getAnonymousAppDeviceGUID(context) + ) { error -> + if (error != null) { + // Handle the error + } + } ``` ### Firebase and Google Analytics 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[Firebase and Google Analytics インテグレーションの SDK 設定](firebase-and-google-analytics) をご覧ください。 ```diff showLineNumbers // After Adapty.activate() FirebaseAnalytics.getInstance(context).appInstanceId.addOnSuccessListener { appInstanceId -> - Adapty.updateProfile( - AdaptyProfileParameters.Builder() - .withFirebaseAppInstanceId(appInstanceId) - .build() - ) { error -> - if (error != null) { - // Handle the error - } - } + Adapty.setIntegrationIdentifier("firebase_app_instance_id", appInstanceId) { error -> + if (error != null) { + // Handle the error + } + } } ``` ```diff showLineNumbers // After Adapty.activate() - FirebaseAnalytics.getInstance(context).getAppInstanceId().addOnSuccessListener(appInstanceId -> { - AdaptyProfileParameters params = new AdaptyProfileParameters.Builder() - .withFirebaseAppInstanceId(appInstanceId) - .build(); - - Adapty.updateProfile(params, error -> { - if (error != null) { - // Handle the error - } - }); - }); + FirebaseAnalytics.getInstance(context).getAppInstanceId().addOnSuccessListener(appInstanceId -> { + Adapty.setIntegrationIdentifier("firebase_app_instance_id", appInstanceId, error -> { + if (error != null) { + // Handle the error + } + }); + }); ``` ### Mixpanel 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[Mixpanel インテグレーションの SDK 設定](mixpanel#sdk-configuration) をご覧ください。 ```diff showLineNumbers - val params = AdaptyProfileParameters.Builder() - .withMixpanelUserId(mixpanelAPI.distinctId) - .build() - - Adapty.updateProfile(params) { error -> - if (error != null) { - // Handle the error - } - } + Adapty.setIntegrationIdentifier("mixpanel_user_id", mixpanelAPI.distinctId) { error -> + if (error != null) { + // Handle the error + } + } ``` ### OneSignal 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[OneSignal インテグレーションの SDK 設定](onesignal#sdk-configuration) をご覧ください。 ```diff showLineNumbers // SubscriptionID val oneSignalSubscriptionObserver = object: IPushSubscriptionObserver { override fun onPushSubscriptionChange(state: PushSubscriptionChangedState) { - val params = AdaptyProfileParameters.Builder() - .withOneSignalSubscriptionId(state.current.id) - .build() - - Adapty.updateProfile(params) { error -> + Adapty.setIntegrationIdentifier("one_signal_subscription_id", state.current.id) { error -> if (error != null) { // Handle the error } } } } ``` ```diff showLineNumbers // SubscriptionID IPushSubscriptionObserver oneSignalSubscriptionObserver = state -> { - AdaptyProfileParameters params = new AdaptyProfileParameters.Builder() - .withOneSignalSubscriptionId(state.getCurrent().getId()) - .build(); - Adapty.updateProfile(params, error -> { + Adapty.setIntegrationIdentifier("one_signal_subscription_id", state.getCurrent().getId(), error -> { if (error != null) { // Handle the error } }); }; ``` ```diff showLineNumbers // PlayerID val osSubscriptionObserver = OSSubscriptionObserver { stateChanges -> stateChanges?.to?.userId?.let { playerId -> - val params = AdaptyProfileParameters.Builder() - .withOneSignalPlayerId(playerId) - .build() - - Adapty.updateProfile(params) { error -> + Adapty.setIntegrationIdentifier("one_signal_player_id", playerId) { error -> if (error != null) { // Handle the error } - } } } ``` ```diff showLineNumbers // PlayerID OSSubscriptionObserver osSubscriptionObserver = stateChanges -> { OSSubscriptionState to = stateChanges != null ? stateChanges.getTo() : null; String playerId = to != null ? to.getUserId() : null; if (playerId != null) { - AdaptyProfileParameters params1 = new AdaptyProfileParameters.Builder() - .withOneSignalPlayerId(playerId) - .build(); - - Adapty.updateProfile(params1, error -> { + Adapty.setIntegrationIdentifier("one_signal_player_id", playerId, error -> { if (error != null) { // Handle the error } - }); } }; ``` ### Pushwoosh 以下のようにモバイルアプリのコードを更新してください。完全なコード例については、[Pushwoosh インテグレーションの SDK 設定](pushwoosh#sdk-configuration) をご覧ください。 ```diff showLineNumbers - val params = AdaptyProfileParameters.Builder() - .withPushwooshHwid(Pushwoosh.getInstance().hwid) - .build() - Adapty.updateProfile(params) { error -> + Adapty.setIntegrationIdentifier("pushwoosh_hwid", Pushwoosh.getInstance().hwid) { error -> if (error != null) { // Handle the error } } ``` ```diff showLineNumbers - AdaptyProfileParameters params = new AdaptyProfileParameters.Builder() - .withPushwooshHwid(Pushwoosh.getInstance().getHwid()) - .build(); - - Adapty.updateProfile(params, error -> { + Adapty.setIntegrationIdentifier("pushwoosh_hwid", Pushwoosh.getInstance().getHwid(), error -> { if (error != null) { // Handle the error } }); ``` --- # File: migration-to-android-sdk-v3 --- --- title: "Adapty Android SDK を v3.0 に移行する" description: "Adapty Android SDK v3.0 に移行して、パフォーマンスの向上と新しいマネタイゼーション機能を活用しましょう。" --- Adapty SDK v3.0 では、新しい [Adapty ペイウォールビルダー](adapty-paywall-builder)をサポートしています。これはペイウォールをノーコードで作成できる使いやすいツールの新バージョンです。高い柔軟性と豊富なデザイン機能により、より効果的で収益性の高いペイウォールを作成できます。 Adapty SDK は BoM(Bill of Materials)として提供されており、アプリ内の Adapty SDK と AdaptyUI SDK のバージョンを常に一致させることができます。 v3.0 に移行するには、以下のようにコードを更新してください: ```diff showLineNumbers dependencies { ... - implementation 'io.adapty:android-sdk:2.11.5' - implementation 'io.adapty:android-ui:2.11.3' + implementation platform('io.adapty:adapty-bom:3.0.4') + implementation 'io.adapty:android-sdk' + implementation 'io.adapty:android-ui' } ``` ```diff showLineNumbers dependencies { ... - implementation("io.adapty:android-sdk:2.11.5") - implementation("io.adapty:android-ui:2.11.3") + implementation(platform("io.adapty:adapty-bom:3.0.4")) + implementation("io.adapty:android-sdk") + implementation("io.adapty:android-ui") } ``` ```diff showLineNumbers //libs.versions.toml [versions] .. - adapty = "2.11.5" - adaptyUi = "2.11.3" + adaptyBom = "3.0.4" [libraries] .. - adapty = { group = "io.adapty", name = "android-sdk", version.ref = "adapty" } - adapty-ui = { group = "io.adapty", name = "android-ui", version.ref = "adaptyUi" } + adapty-bom = { module = "io.adapty:adapty-bom", version.ref = "adaptyBom" } + adapty = { module = "io.adapty:android-sdk" } + adapty-ui = { module = "io.adapty:android-ui" } //module-level build.gradle.kts dependencies { ... + implementation(libs.adapty.bom) implementation(libs.adapty) implementation(libs.adapty.ui) } ``` --- # End of Documentation _Generated on: 2026-06-24T14:36:28.457Z_ _Successfully processed: 40/40 files_