as

Settings
Sign out
Notifications
Alexa
Amazonアプリストア
AWS
ドキュメント
Support
Contact Us
My Cases
デバイス
ビルド
テスト
公開
関連情報
ドキュメント

GetUserAgeData APIの統合とテスト

GetUserAgeData APIの統合とテスト

このページには、アプリからGetUserAgeData APIにアクセスする方法と、そのレスポンスの利用方法を示すサンプルコードが含まれています。このサンプルコードで紹介するテスト実装を使用すれば、2026年1月1日に先立って、実際のAPIの動作を今すぐシミュレートできます。GetUserAgeData APIの統合を開発およびテストするには、AmazonUserDataClientクラスで提供されている非本番用の値を、モックデータを提供するTestContentProviderクラスと組み合わせて使用してください。

概要

GetUserAgeData APIをアプリに統合するための大まかな手順は次のとおりです。

  1. モックデータを使用してテストする場合は、テスト対象のアプリのAndroidマニフェストにTestContentProviderクラスを登録します。
  2. ユーザーの年齢データを保持するシンプルなJavaオブジェクトを作成します。
  3. このJavaオブジェクトから抽出されたユーザーの年齢データをモデリングするヘルパークラスを作成します。
  4. ユーザーの年齢データをクエリするAmazonUserDataClientクラスを実装します。
  5. アプリからAmazonUserDataClientクラスを呼び出して、レスポンスを処理するロジックを追加します。

テスト環境

テストに使用するAmazonUserDataClientクラスのバージョンで、以下のように設定します。

  • AUTHORITY文字列をamzn_test_appstoreに設定する
  • PATH文字列を/getUserAgeData?testOption=kに設定する(kは1~10の数値)

これらは非本番用の値であり、Amazonシステムにはアクセスできません。

このページに記載されているTestContentProviderクラスの実装は、GetUserAgeData APIの実際のレスポンス構成に基づいてモックレスポンスの組み合わせを返します。この機能をテストするには、testOptionクエリパラメーターに1~10の値を渡します。TestContentProviderクラスは、testOptionパラメーターの値に対応するレスポンスを返します。提供されているモックレスポンスの一覧は、テストデータのレスポンスを参照してください。

本番環境

本番環境では、TestContentProviderクラスとそのマニフェスト登録を除外し、アプリで本番用のGetUserAgeData APIを参照します。

本番用のGetUserAgeData APIを使用するには、AmazonUserDataClientクラスで以下のように設定します。

  • AUTHORITY文字列をamzn_appstoreに設定する
  • PATH文字列を/getUserAgeDataに設定する

GetUserAgeData APIがライブレスポンスを返す工程は、2026年1月1日から開始されます。2026年1月1日より前に呼び出した場合は、nullExceptionFEATURE_NOT_SUPPORTEDのうちいずれかの値が返されます。

AmazonUserDataClient

以下は、モックGetUserAgeData APIをアプリから呼び出す場合のサンプルコードです。

クリップボードにコピーしました。

import android.content.Context;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.CancellationSignal;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.Optional;

public class AmazonUserDataClient {
    
    // 以下に指定されているエンドポイントは完全なテスト用です。
    // 本番用/ライブAPIでは「amzn_appstore」に置き換えてください。
    public static final String AUTHORITY = "amzn_test_appstore";

    // 以下に指定されているPATHは完全なテスト用です。
    // クエリパラメーターtestOptionに1~10の値を設定して(例:testOption=1~testOption=10)、
    // TestContentProviderの対応する出力(getResponse1()~getResponse10())を取得します。
    
    // 本番用/ライブAPIの「/getUserAgeData」に置き換えてください。
    private static final String PATH = "/getUserAgeData?testOption=1";

    private static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + PATH);

    private Context context;

    public AmazonUserDataClient(Context context) {
        this.context = context;
    }

    public UserData getMyData(Context context) throws TimeoutException, InterruptedException, ExecutionException {
        CancellationSignal signal = new CancellationSignal();
        CompletableFuture<UserData> future = CompletableFuture.supplyAsync(() ->
            queryUserDataInternal(context, signal)
        );
        try {
            return future.get(5, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            signal.cancel();
            throw e;
        }
    }
    
    private UserData queryUserDataInternal(Context context, CancellationSignal signal) {
        try (Cursor cursor = context.getContentResolver().query(CONTENT_URI, null, null, null, null, signal)) {
            int ageLowerColumnIndex = cursor.getColumnIndex(UserAgeDataResponse.COLUMN_AGE_LOWER);
            int ageUpperColumnIndex = cursor.getColumnIndex(UserAgeDataResponse.COLUMN_AGE_UPPER);
            return Optional.ofNullable(cursor)
                .filter(Cursor::moveToFirst)
                .map(c -> new UserData(
                    c.getString(c.getColumnIndex(UserAgeDataResponse.COLUMN_RESPONSE_STATUS)),
                    c.getString(c.getColumnIndex(UserAgeDataResponse.COLUMN_USER_STATUS)),
                    !c.isNull(ageLowerColumnIndex) ? c.getInt(ageLowerColumnIndex) : null,
                    !c.isNull(ageUpperColumnIndex) ? c.getInt(ageUpperColumnIndex) : null,
                    c.getString(c.getColumnIndex(UserAgeDataResponse.COLUMN_USER_ID)),
                    c.getString(c.getColumnIndex(UserAgeDataResponse.COLUMN_MOST_RECENT_APPROVAL_DATE))
                ))
                .orElseThrow(() -> new RuntimeException("ユーザーデータがありません"));
        } catch (Exception e) {
            throw new RuntimeException("クエリに失敗しました", e);
        }
    }
}

ユーザーデータレスポンスを処理するには、以下の「Plain Old Java Objectct」(POJO)モデルを使用します。詳細については、GetUserAgeData APIを参照してください。

クリップボードにコピーしました。

public class UserData {
    private final String responseStatus;
    private final String userStatus;
    private final Integer ageLower;
    private final Integer ageUpper;
    private final String userId;
    private final String mostRecentApprovalDate;

    public UserData(String responseStatus, String userStatus, Integer ageLower, 
                   Integer ageUpper, String userId, String mostRecentApprovalDate) {
        this.responseStatus = responseStatus;
        this.userStatus = userStatus;
        this.ageLower = ageLower;
        this.ageUpper = ageUpper;
        this.userId = userId;
        this.mostRecentApprovalDate = mostRecentApprovalDate;
    }

    public String getResponseStatus() { return responseStatus; }
    public String getUserStatus() { return userStatus; }
    public Integer getAgeLower() { return ageLower; }
    public Integer getAgeUpper() { return ageUpper; }
    public String getUserId() { return userId; }
    public String getMostRecentApprovalDate() { return mostRecentApprovalDate; }
}

UserAgeDataResponse

AmazonUserDataClientクラスでは、抽出したユーザーの年齢データをモデリングする以下のヘルパークラスを使用できます。AmazonUserDataClientセクションのサンプルコードでは、このヘルパークラスを使用しています。

クリップボードにコピーしました。

public final class UserAgeDataResponse {
    private UserAgeDataResponse() {}
    public static final String COLUMN_RESPONSE_STATUS = "responseStatus";
    public static final String COLUMN_USER_STATUS = "userStatus";
    public static final String COLUMN_USER_ID = "userId";
    public static final String COLUMN_MOST_RECENT_APPROVAL_DATE = "mostRecentApprovalDate";
    public static final String COLUMN_AGE_LOWER = "ageLower";
    public static final String COLUMN_AGE_UPPER = "ageUpper";
}

TestContentProvider

以下の実装は完全にスタンドアロンであり、Amazonアプリストアとやり取りしません。このクラスは、開発の初期段階、単体テスト、またはテスト目的でのみ使用してください。フルスタックの統合テストや本番環境での使用を目的としたものではありません。

TestContentProviderクラスを実装すると、実際のGetUserAgeData APIの動作をシミュレートできます。新規アプリ、テストアプリ、または実際のアプリのテストロジックでは、TestContentProviderクラスを使用してモックレスポンスを取得します。

GetUserAgeData APIレスポンスの詳細については、GetUserAgeData APIを参照してください。

クリップボードにコピーしました。

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;

/**
 * 年齢シグナルを提供するコンテンツプロバイダー。
 * responseStatus、userStatus、ageLower、ageUpper、userId、mostRecentApprovalDateを返します。
 */
public class TestContentProvider extends ContentProvider {


    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        sUriMatcher.addURI(AmazonUserDataClient.AUTHORITY, "getUserAgeData", 1);
    }

    @Override
    public boolean onCreate() {
        return true;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        throw new UnsupportedOperationException("挿入はサポートされていません");
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException("削除はサポートされていません");
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException("更新はサポートされていません");
    }

    @Override
    public final Cursor query(Uri uri, String[] projection, Bundle queryArgs, CancellationSignal cancellationSignal) {
        return query(uri, null, null, null, null, cancellationSignal);
    }

    @Override
    public final Cursor query(final Uri uri, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) {
        return query(uri, projection, selection, selectionArgs, sortOrder, null);
    }

    @Override
    public final Cursor query(final Uri uri, final String[] projection, final String selection,
                              final String[] selectionArgs, final String sortOrder, CancellationSignal cancellationSignal) {
        int match = sUriMatcher.match(uri);
        if (match != 1) {
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }

        String param1 = uri.getQueryParameter("testOption");
        if (param1 == null) {
            throw new IllegalArgumentException("testOptionパラメーターが必要です");
        }

        int option;
        try {
            option = Integer.parseInt(param1);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("testOptionには有効な整数を指定する必要があります");
        }

        if (option < 1 || option > 10) {
            throw new IllegalArgumentException("testOptionには1~10を指定する必要があります");
        }
        MatrixCursor cursor = createCursor();
        cursor.addRow(getResponse(option));
        return cursor;
    }

    private Object[] getResponse(int option) {
        switch (option) {
            case 2: return getResponse2();
            case 3: return getResponse3();
            case 4: return getResponse4();
            case 5: return getResponse5();
            case 6: return getResponse6();
            case 7: return getResponse7();
            case 8: return getResponse8();
            case 9: return getResponse9();
            case 10: return getResponse10();
        }
        return getResponse1();
    }

    private MatrixCursor createCursor() {
        return new MatrixCursor(new String[]{
                UserAgeDataResponse.COLUMN_RESPONSE_STATUS,
                UserAgeDataResponse.COLUMN_USER_STATUS,
                UserAgeDataResponse.COLUMN_AGE_LOWER,
                UserAgeDataResponse.COLUMN_AGE_UPPER,
                UserAgeDataResponse.COLUMN_USER_ID,
                UserAgeDataResponse.COLUMN_MOST_RECENT_APPROVAL_DATE
        });
    }

    /***
     * ユーザーが18歳以上で、年齢確認が済んでいる場合のサンプルレスポンス。
     * 詳細については、APIドキュメントを参照してください。
     */
    private static Object[] getResponse1() {
        return new Object[]{ "SUCCESS", "VERIFIED", 18, null, null, null };
    }


    /***
     * ユーザーの年齢確認が済んでいない、または同意が得られていない場合のサンプルレスポンス。
     * 詳細については、APIドキュメントを参照してください。
     */
    private static Object[] getResponse2() {
        return new Object[]{ "SUCCESS", "UNKNOWN", null, null, null, null };
    }


    /***
     * ユーザーの年齢が0~12歳の場合のレスポンス。
     * 詳細については、APIドキュメントを参照してください。
     */
    private static Object[] getResponse3() {
        return new Object[]{ "SUCCESS", "SUPERVISED", 0, 12, "randomTestUserId1jC3QQeivdAytchaIVkWOjDiDlvz8xglhUcLwkbUHNQZKKw", "2023-07-01T00:00:00.008+02:00" };
    }


    /***
     * ユーザーの年齢が13~15歳の場合のレスポンス。
     * 詳細については、APIドキュメントを参照してください。
     */
    private static Object[] getResponse4() {
        return new Object[]{ "SUCCESS", "SUPERVISED", 13, 15, "randomTestUserId1jC3QQeivdAytchaIVkWOjDiDlvz8pUxhUcLwkbUHNQZKKw", "2023-07-01T00:00:00.008Z" };
    }


    /***
     * ユーザーの年齢が16~17歳の場合のレスポンス。
     * 詳細については、APIドキュメントを参照してください。
     */
    private static Object[] getResponse5() {
        return new Object[]{ "SUCCESS", "SUPERVISED", 16, 17, "randomTestUserId1jC3QQeivdhBcchaIVkWOjDiDlvz8pUxhUcLwkbUHNQZKKw", "2023-07-01T00:00:00.008Z" };
    }


    /***
     * 年齢確認に関する法律が適用されない一般的なシナリオでのレスポンス。
     * 詳細については、APIドキュメントを参照してください。
     */
    private static Object[] getResponse6() {
        return new Object[]{ "SUCCESS", "", null, null, null, null };
    }


    /***
     * APIがAPP_NOT_OWNEDステータスを返した場合のレスポンス。
     * 詳細については、APIドキュメントを参照してください。
     */
    private static Object[] getResponse7() {
        return new Object[]{ "APP_NOT_OWNED", "", null, null, null, null };
    }


    /***
     * APIがINTERNAL_TRANSIENT_ERRORステータスを返した場合のレスポンス。
     * 詳細については、APIドキュメントを参照してください。
     */
    private static Object[] getResponse8() {
        return new Object[]{ "INTERNAL_TRANSIENT_ERROR", "", null, null, null, null };
    }


    /***
     * APIがINTERNAL_ERRORステータスを返した場合のレスポンス。
     * 詳細については、APIドキュメントを参照してください。
     */
    private static Object[] getResponse9() {
        return new Object[]{ "INTERNAL_ERROR", "", null, null, null, null };
    }


    /***
     * APIがFEATURE_NOT_SUPPORTEDステータスを返した場合のレスポンス。
     * 詳細については、APIドキュメントを参照してください。
     */
    private static Object[] getResponse10() {
        return new Object[]{ "FEATURE_NOT_SUPPORTED", "", null, null, null, null };
    }
}

テストデータのレスポンス

以下は、前のセクションで説明したTestContentProvider APIによって返される10個のモックレスポンスの一覧です。testOptionは、ユーザーデータのモッククエリでのみ使用されるクエリパラメーターで、以下の定義済みレスポンスを提供します。

testOption値 ユースケース レスポンスデータ
1 ユーザーが18歳以上で、年齢確認が済んでいる場合のレスポンス。
{
  "responseStatus": "SUCCESS",
  "userStatus": "VERIFIED",
  "ageLower": 18,
  "ageUpper": null,
  "userId": null,
  "mostRecentApprovalDate": null
}
2 ユーザーの年齢確認が済んでいない、または同意が得られていない場合のレスポンス。
{
  "responseStatus": "SUCCESS",
  "userStatus": "UNKNOWN",
  "ageLower": null,
  "ageUpper": null,
  "userId": null,
  "mostRecentApprovalDate": null
}
3 ユーザーが0~12歳以下の場合のレスポンス。
{
  "responseStatus": "SUCCESS",
  "userStatus": "SUPERVISED",
  "ageLower": 0,
  "ageUpper": 12,
  "userId": "randomTestUserId1jC3QQeivdAytchaIVkWOjDiDlvz8xglhUcLwkbUHNQZKKw",
  "mostRecentApprovalDate": "2023-07-01T00:00:00.008+02:00"
}
4 ユーザーが13~15歳以下の場合のレスポンス。
{
  "responseStatus": "SUCCESS",
  "userStatus": "SUPERVISED",
  "ageLower": 13,
  "ageUpper": 15,
  "userId": "randomTestUserId1jC3QQeivdAytchaIVkWOjDiDlvz8pUxhUcLwkbUHNQZKKw",
  "mostRecentApprovalDate": "2023-07-01T00:00:00.008Z"
}
5 ユーザーが16~17歳以下の場合のレスポンス。
{
  "responseStatus": "SUCCESS",
  "userStatus": "SUPERVISED",
  "ageLower": 16,
  "ageUpper": 17,
  "userId": "randomTestUserId1jC3QQeivdhBcchaIVkWOjDiDlvz8pUxhUcLwkbUHNQZKKw",
  "mostRecentApprovalDate": "2023-07-01T00:00:00.008Z"
}
6 年齢確認に関する法律が適用されないシナリオでのレスポンス。
{
  "responseStatus": "SUCCESS",
  "userStatus": "",
  "ageLower": null,
  "ageUpper": null,
  "userId": null,
  "mostRecentApprovalDate": null
}
7 APIがAPP_NOT_OWNEDステータスを返した場合のレスポンス。
{
  "responseStatus": "APP_NOT_OWNED",
  "userStatus": "",
  "ageLower": null,
  "ageUpper": null,
  "userId": null,
  "mostRecentApprovalDate": null
}
8 APIがINTERNAL_TRANSIENT_ERRORステータスを返した場合のレスポンス。
{
  "responseStatus": "INTERNAL_TRANSIENT_ERROR",
  "userStatus": "",
  "ageLower": null,
  "ageUpper": null,
  "userId": null,
  "mostRecentApprovalDate": null
}
9 APIがINTERNAL_ERRORステータスを返した場合のレスポンス。
{
  "responseStatus": "INTERNAL_ERROR",
  "userStatus": "",
  "ageLower": null,
  "ageUpper": null,
  "userId": null,
  "mostRecentApprovalDate": null
}
10 APIがFEATURE_NOT_SUPPORTEDステータスを返した場合のレスポンス。
{
  "responseStatus": "FEATURE_NOT_SUPPORTED",
  "userStatus": "",
  "ageLower": null,
  "ageUpper": null,
  "userId": null,
  "mostRecentApprovalDate": null
}

TestContentProviderクラスをAndroidマニフェストに登録する

TestContentProviderクラスを使用するには、このクラスをAndroidManifest.xmlファイルに登録する必要があります。この登録ステップが必要なのは、テストアプリなど、TestContentProvider APIロジックを提供するアプリだけです。provider要素のandroid:name属性を、TestContentProviderクラスの完全修飾クラス名と一致するように変更します。

<application
            android:name="{.MainApplicationまたは該当するアプリ}"
            android:label="テストアプリ">

        <!-- テストコンテンツプロバイダー -->
        <provider
                android:name="com.test_app.TestContentProvider"
                android:authorities="amzn_test_appstore"
                android:exported="true" />

</application>

Amazonによって提供されるユーザーデータにアプリからアクセスする

次のコードは、AmazonUserDataClientクラスによって提供されるユーザーデータを取得する方法を示しています。このコードをアプリで使用して、ユーザーの年齢確認ステータスとユーザーの年齢層を処理するロジックを追加します。

// //アプリの呼び出し元で、次の操作を実行します。
UserData userData = new AmazonUserDataClient().getUserData(context);
// if("SUCCESS".equals(userData.getResponseStatus())) {
//     // userStatusと年齢層の値に基づく適切なロジック。
//     //詳細については、APIドキュメントを参照してください。
// }
// //その他のステータスを適切に処理します。

その他の言語での記述方法

ここではサンプルコードのみを示します。完全な構文については、各言語またはフレームワークの公式ドキュメントを参照してください。

React Native

// React Native ContentResolverブリッジで直接実行
const userData = await ContentResolver.query('content://amzn_appstore/getUserAgeData');

Flutter

// プラットフォームチャネルで実行
final userData = await platform.invokeMethod('queryContentProvider', {
'uri': 'content://amzn_appstore/getUserAgeData'
});

Last updated: 2025年11月6日