开始使用
-
安装包
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 服务的 Android 设备
- 最低 Android API 级别 21(Android 5.0)
- 设备上安装了 Google Play 商店
检查年龄信号
Section titled “检查年龄信号”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'); // Allow access to age-restricted content break;
case UserStatus.Supervised: console.log(`Supervised user aged ${result.ageLower}-${result.ageUpper}`); // Apply age-appropriate restrictions break;
case UserStatus.SupervisedApprovalPending: console.log('Waiting for guardian approval'); console.log('Pending since:', result.mostRecentApprovalDate); // Inform user to wait for guardian approval break;
case UserStatus.SupervisedApprovalDenied: console.log('Guardian denied access'); console.log('Last approval:', result.mostRecentApprovalDate); // Block access or show alternative content break;
case UserStatus.Unknown: console.log('User status unknown - prompt to verify in Play Store'); // Guide user to verify their age in Google Play break;
case UserStatus.Empty: console.log('No age signal available'); // Handle as unverified user 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) { // Apply COPPA restrictions console.log('User is under 13 - COPPA applies'); disableDataCollection(); disableSocialFeatures(); requireParentalConsent(); } else if (age < 18) { // Apply teen restrictions console.log('User is 13-17 - Teen restrictions apply'); enableModeratedSocialFeatures(); restrictAds(); }
// Track install ID for revocation notifications console.log('Install ID:', result.installId); saveInstallId(result.installId); }}实现年龄门槛
Section titled “实现年龄门槛”async function ageGate() { const result = await AgeSignals.checkAgeSignals();
// Allow verified 18+ users if (result.userStatus === UserStatus.Verified) { return true; }
// Check supervised user age if (result.userStatus === UserStatus.Supervised) { return result.ageUpper >= 18; }
// Block users with pending or denied approvals if ( result.userStatus === UserStatus.SupervisedApprovalPending || result.userStatus === UserStatus.SupervisedApprovalDenied ) { return false; }
// For unknown/empty, implement fallback age verification 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);
// Show message to user 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);
// Show blocked message showMessage( 'Your guardian did not approve this app. ' + 'Contact them for more information.' ); }}API 参考
Section titled “API 参考”checkAgeSignals()
Section titled “checkAgeSignals()”请求当前活跃用户的 Play 年龄信号。
const result = await AgeSignals.checkAgeSignals();返回值:
interface CheckAgeSignalsResult { userStatus: UserStatus; ageLower?: number; ageUpper?: number; mostRecentApprovalDate?: string; installId?: string;}UserStatus Enum
Section titled “UserStatus Enum”enum UserStatus { Verified = 'VERIFIED', // 18+ verified Supervised = 'SUPERVISED', // Supervised account SupervisedApprovalPending = 'SUPERVISED_APPROVAL_PENDING', SupervisedApprovalDenied = 'SUPERVISED_APPROVAL_DENIED', Unknown = 'UNKNOWN', // Unknown status Empty = 'EMPTY' // No signal}userStatus
Section titled “userStatus”Google Play 报告的用户验证状态。
- Verified:用户已年满 18 周岁并已通过 Google 验证
- Supervised:用户拥有受监督的 Google 账户
- SupervisedApprovalPending:等待监护人批准更改
- SupervisedApprovalDenied:监护人拒绝应用访问
- Unknown:用户应在 Play 商店中验证状态
- 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
1. COPPA 合规
Section titled “1. COPPA 合规”async function applyCoppaRestrictions() { const result = await AgeSignals.checkAgeSignals();
if (result.userStatus === UserStatus.Supervised && result.ageLower < 13) { // Disable data collection disableAnalytics(); disableAdvertising();
// Disable social features hideChatFeatures(); disableUserProfiles();
// Require verifiable parental consent 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'; // Default safe rating }
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) { // Store install ID for revocation handling localStorage.setItem('ageSignalsInstallId', installId); }
async checkRevocation() { const result = await AgeSignals.checkAgeSignals(); const storedId = localStorage.getItem('ageSignalsInstallId');
if (result.installId && storedId && result.installId !== storedId) { // Install ID changed - likely revoked and reinstalled console.log('App was revoked and reinstalled'); return true; }
return false; }}- 应用启动时检查:在应用启动时验证年龄信号
- 缓存结果:缓存结果但定期刷新
- 处理所有状态:为所有 UserStatus 值实现逻辑
- 尊重拒绝:当监护人拒绝批准时不允许访问
- 存储安装 ID:跟踪安装 ID 以检测撤销
- 回退逻辑:为 Unknown/Empty 状态提供回退年龄验证
- 隐私优先:不收集受监督用户的不必要数据
COPPA(儿童在线隐私保护法)
Section titled “COPPA(儿童在线隐私保护法)”对于 13 岁以下的用户:
- 获得可验证的家长同意
- 限制数据收集
- 禁用行为广告
- 提供家长控制
GDPR(通用数据保护条例)
Section titled “GDPR(通用数据保护条例)”对于受监督用户:
- 合法处理数据
- 提供监护人同意机制
- 允许数据访问和删除
- 实施隐私设计
Android
Section titled “Android”- 需要 Google Play 服务
- 最低 API 级别 21(Android 5.0+)
- 仅适用于安装了 Play 商店的设备
- 信号可能在所有地区都不可用
- 如果监护人修改设置,结果可能会改变
iOS / Web
Section titled “iOS / Web”- 不支持 - 这是一个仅限 Android 的插件
- 在不支持的平台上调用时会抛出错误
未返回信号(空状态)
Section titled “未返回信号(空状态)”以下情况是正常的:
- 不在支持地区的用户
- 没有 Google Play 服务的设备
- 未设置 Family Link 的用户
- 未验证的新账户
用户应该:
- 打开 Google Play 商店
- 进入设置 → 家庭
- 完成年龄验证过程
确保:
- Google Play 服务已更新
- 应用在 Play 控制台中有正确的包名
- 在真实设备上测试(不是没有 Play 服务的模拟器)