はじめに
-
パッケージをインストール
Terminal window npm i @capgo/capacitor-android-age-signalsTerminal window pnpm add @capgo/capacitor-android-age-signalsTerminal window yarn add @capgo/capacitor-android-age-signalsTerminal window bun add @capgo/capacitor-android-age-signals -
Androidプロジェクトと同期
Terminal window npx cap sync androidTerminal window pnpm cap sync androidTerminal window yarn cap sync androidTerminal window bunx cap sync android
- Google Play Servicesを搭載したAndroidデバイス
- 最小Android APIレベル21(Android 5.0)
- デバイスにGoogle Play Storeがインストールされていること
Age Signalsの確認
Section titled “Age Signalsの確認”import { AgeSignals, UserStatus } from '@capgo/capacitor-android-age-signals';
try { const result = await AgeSignals.checkAgeSignals();
console.log('User status:', result.userStatus);
switch (result.userStatus) { case UserStatus.Verified: console.log('User is 18+ and verified by Google'); // 年齢制限コンテンツへのアクセスを許可 break;
case UserStatus.Supervised: console.log(`Supervised user aged ${result.ageLower}-${result.ageUpper}`); // 年齢に応じた制限を適用 break;
case UserStatus.SupervisedApprovalPending: console.log('Waiting for guardian approval'); console.log('Pending since:', result.mostRecentApprovalDate); // 保護者の承認を待つようユーザーに通知 break;
case UserStatus.SupervisedApprovalDenied: console.log('Guardian denied access'); console.log('Last approval:', result.mostRecentApprovalDate); // アクセスをブロックするか、代替コンテンツを表示 break;
case UserStatus.Unknown: console.log('User status unknown - prompt to verify in Play Store'); // Google Playで年齢を確認するようユーザーに案内 break;
case UserStatus.Empty: console.log('No age signal available'); // 未認証ユーザーとして処理 break; }} catch (error) { console.error('Failed to check age signals:', error);}監視ユーザーの処理
Section titled “監視ユーザーの処理”async function handleSupervisedUser() { const result = await AgeSignals.checkAgeSignals();
if (result.userStatus === UserStatus.Supervised) { const age = result.ageLower;
if (age < 13) { // COPPAの制限を適用 console.log('User is under 13 - COPPA applies'); disableDataCollection(); disableSocialFeatures(); requireParentalConsent(); } else if (age < 18) { // 10代の制限を適用 console.log('User is 13-17 - Teen restrictions apply'); enableModeratedSocialFeatures(); restrictAds(); }
// 取り消し通知用のインストールIDを追跡 console.log('Install ID:', result.installId); saveInstallId(result.installId); }}年齢ゲートの実装
Section titled “年齢ゲートの実装”async function ageGate() { const result = await AgeSignals.checkAgeSignals();
// 認証済みの18歳以上のユーザーを許可 if (result.userStatus === UserStatus.Verified) { return true; }
// 監視ユーザーの年齢を確認 if (result.userStatus === UserStatus.Supervised) { return result.ageUpper >= 18; }
// 保留中または拒否された承認のユーザーをブロック if ( result.userStatus === UserStatus.SupervisedApprovalPending || result.userStatus === UserStatus.SupervisedApprovalDenied ) { return false; }
// 不明/空の場合は、フォールバック年齢確認を実装 return await showAgeVerificationDialog();}承認ステータスの監視
Section titled “承認ステータスの監視”async function checkApprovalStatus() { const result = await AgeSignals.checkAgeSignals();
if (result.userStatus === UserStatus.SupervisedApprovalPending) { console.log('Guardian approval pending'); console.log('Age range:', result.ageLower, '-', result.ageUpper); console.log('Most recent approval:', result.mostRecentApprovalDate);
// ユーザーにメッセージを表示 showMessage( 'Your guardian needs to approve this app. ' + 'We notified them on ' + result.mostRecentApprovalDate ); } else if (result.userStatus === UserStatus.SupervisedApprovalDenied) { console.log('Guardian denied approval'); console.log('Last approved on:', result.mostRecentApprovalDate);
// ブロックメッセージを表示 showMessage( 'Your guardian did not approve this app. ' + 'Contact them for more information.' ); }}APIリファレンス
Section titled “APIリファレンス”checkAgeSignals()
Section titled “checkAgeSignals()”アクティブユーザーの現在のPlay Age Signalsをリクエストします。
const result = await AgeSignals.checkAgeSignals();戻り値:
interface CheckAgeSignalsResult { userStatus: UserStatus; ageLower?: number; ageUpper?: number; mostRecentApprovalDate?: string; installId?: string;}UserStatus列挙型
Section titled “UserStatus列挙型”enum UserStatus { Verified = 'VERIFIED', // 18歳以上認証済み Supervised = 'SUPERVISED', // 監視アカウント SupervisedApprovalPending = 'SUPERVISED_APPROVAL_PENDING', SupervisedApprovalDenied = 'SUPERVISED_APPROVAL_DENIED', Unknown = 'UNKNOWN', // 不明なステータス Empty = 'EMPTY' // シグナルなし}結果フィールド
Section titled “結果フィールド”userStatus
Section titled “userStatus”Google Playによって報告されたユーザーの認証ステータス。
- Verified: ユーザーは18歳以上でGoogleによって年齢認証済み
- Supervised: ユーザーは監視されたGoogleアカウントを持っている
- SupervisedApprovalPending: 変更に対する保護者の承認を待機中
- SupervisedApprovalDenied: 保護者がアプリアクセスを拒否
- Unknown: ユーザーはPlay Storeでステータスを確認する必要がある
- Empty: その他すべてのユーザー(デフォルト状態)
ageLower
Section titled “ageLower”監視ユーザーの年齢範囲の下限(含む)。
userStatusが次の場合にのみ存在:
SUPERVISEDSUPERVISED_APPROVAL_PENDINGSUPERVISED_APPROVAL_DENIED
ageUpper
Section titled “ageUpper”監視ユーザーの年齢範囲の上限(含む)。
次の場合にのみ存在:
userStatusが監視ステータスのいずれか- ユーザーの年齢が18歳未満と報告されている場合
mostRecentApprovalDate
Section titled “mostRecentApprovalDate”保護者の承認を受けた最新の重要な変更の日付文字列。
userStatusが次の場合にのみ存在:
SUPERVISED_APPROVAL_PENDINGSUPERVISED_APPROVAL_DENIED
形式: ISO 8601日付文字列
installId
Section titled “installId”Google Playで監視対象インストールに割り当てられた識別子。
保護者がアプリの承認を取り消したときの取り消し通知に使用されます。
userStatusが次の場合にのみ存在:
SUPERVISEDSUPERVISED_APPROVAL_PENDINGSUPERVISED_APPROVAL_DENIED
ユースケース
Section titled “ユースケース”1. COPPAコンプライアンス
Section titled “1. COPPAコンプライアンス”async function applyCoppaRestrictions() { const result = await AgeSignals.checkAgeSignals();
if (result.userStatus === UserStatus.Supervised && result.ageLower < 13) { // データ収集を無効化 disableAnalytics(); disableAdvertising();
// ソーシャル機能を無効化 hideChatFeatures(); disableUserProfiles();
// 検証可能な保護者の同意が必要 await requestParentalConsent(result.installId); }}2. 年齢に適したコンテンツ
Section titled “2. 年齢に適したコンテンツ”async function filterContent() { const result = await AgeSignals.checkAgeSignals();
let contentRating;
if (result.userStatus === UserStatus.Verified) { contentRating = 'MATURE'; } else if (result.userStatus === UserStatus.Supervised) { if (result.ageUpper < 13) { contentRating = 'EVERYONE'; } else if (result.ageUpper < 18) { contentRating = 'TEEN'; } else { contentRating = 'MATURE'; } } else { contentRating = 'TEEN'; // デフォルトの安全な評価 }
loadContentForRating(contentRating);}3. 保護者ダッシュボード
Section titled “3. 保護者ダッシュボード”async function getGuardianInfo() { const result = await AgeSignals.checkAgeSignals();
if ( result.userStatus === UserStatus.Supervised || result.userStatus === UserStatus.SupervisedApprovalPending || result.userStatus === UserStatus.SupervisedApprovalDenied ) { return { isSupervised: true, ageRange: `${result.ageLower}-${result.ageUpper}`, approvalStatus: result.userStatus, lastApprovalDate: result.mostRecentApprovalDate, installId: result.installId, }; }
return { isSupervised: false };}import { AgeSignals, UserStatus } from '@capgo/capacitor-android-age-signals';
export class AgeVerificationService { async verifyAge(): Promise<{ allowed: boolean; reason: string; restrictions: string[]; }> { try { const result = await AgeSignals.checkAgeSignals();
switch (result.userStatus) { case UserStatus.Verified: return { allowed: true, reason: 'User is verified 18+', restrictions: [], };
case UserStatus.Supervised: return this.handleSupervised(result);
case UserStatus.SupervisedApprovalPending: return { allowed: false, reason: 'Waiting for guardian approval', restrictions: ['Guardian approval required'], };
case UserStatus.SupervisedApprovalDenied: return { allowed: false, reason: 'Guardian denied access', restrictions: ['Access denied by guardian'], };
case UserStatus.Unknown: return { allowed: false, reason: 'Age verification required', restrictions: ['Verify age in Google Play'], };
case UserStatus.Empty: default: return { allowed: false, reason: 'No age signal available', restrictions: ['Age verification needed'], }; } } catch (error) { console.error('Age verification failed:', error); return { allowed: false, reason: 'Verification error', restrictions: ['Try again later'], }; } }
private handleSupervised(result: any) { const age = result.ageLower; const restrictions: string[] = [];
if (age < 13) { restrictions.push('No data collection (COPPA)'); restrictions.push('No social features'); restrictions.push('Parental consent required'); return { allowed: false, reason: `User is under 13 (${result.ageLower}-${result.ageUpper})`, restrictions, }; } else if (age < 18) { restrictions.push('Age-appropriate content only'); restrictions.push('Moderated social features'); return { allowed: true, reason: `Teen user (${result.ageLower}-${result.ageUpper})`, restrictions, }; } else { return { allowed: true, reason: `Adult supervised user (${result.ageLower}+)`, restrictions: [], }; } }
async saveInstallId(installId: string) { // 取り消し処理用のインストールIDを保存 localStorage.setItem('ageSignalsInstallId', installId); }
async checkRevocation() { const result = await AgeSignals.checkAgeSignals(); const storedId = localStorage.getItem('ageSignalsInstallId');
if (result.installId && storedId && result.installId !== storedId) { // インストールIDが変更された - おそらく取り消されて再インストールされた console.log('App was revoked and reinstalled'); return true; }
return false; }}ベストプラクティス
Section titled “ベストプラクティス”- アプリ起動時に確認: アプリの起動時に年齢シグナルを確認
- 結果をキャッシュ: 結果をキャッシュするが、定期的に更新
- すべての状態を処理: すべてのUserStatus値のロジックを実装
- 拒否を尊重: 保護者が承認を拒否した場合はアクセスを許可しない
- インストールIDを保存: 取り消し検出のためにインストールIDを追跡
- フォールバックロジック: 不明/空の状態のフォールバック年齢確認を用意
- プライバシー優先: 監視ユーザーから不要なデータを収集しない
コンプライアンスガイドライン
Section titled “コンプライアンスガイドライン”COPPA(児童オンラインプライバシー保護法)
Section titled “COPPA(児童オンラインプライバシー保護法)”13歳未満のユーザーの場合:
- 検証可能な保護者の同意を取得
- データ収集を制限
- 行動ターゲティング広告を無効化
- 保護者管理機能を提供
GDPR(一般データ保護規則)
Section titled “GDPR(一般データ保護規則)”監視ユーザーの場合:
- データを合法的に処理
- 保護者の同意メカニズムを提供
- データアクセスと削除を許可
- プライバシーバイデザインを実装
プラットフォームノート
Section titled “プラットフォームノート”Android
Section titled “Android”- Google Play Servicesが必要
- 最小APIレベル21(Android 5.0以上)
- Play Storeを搭載したデバイスでのみ動作
- すべての地域でシグナルが利用できるわけではない
- 保護者が設定を変更すると結果が変わる可能性がある
iOS / Web
Section titled “iOS / Web”- サポート対象外 - これはAndroid専用プラグインです
- サポートされていないプラットフォームで呼び出された場合、エラーがスローされます
トラブルシューティング
Section titled “トラブルシューティング”シグナルが返されない(空のステータス)
Section titled “シグナルが返されない(空のステータス)”これは以下の場合は正常です:
- サポートされている地域外のユーザー
- Google Play Servicesを搭載していないデバイス
- Family Linkを設定していないユーザー
- 認証のない新しいアカウント
不明なステータス
Section titled “不明なステータス”ユーザーは次を実行する必要があります:
- Google Play Storeを開く
- 設定 → ファミリーに移動
- 年齢確認プロセスを完了
以下を確認:
- Google Play Servicesが更新されている
- Play Consoleでアプリのパッケージ名が正しい
- 実機でテスト(Play Servicesなしのエミュレーターではない)