Getting Started
Este contenido aún no está disponible en tu idioma.
-
Install the package
Ventana de terminal npm i @capgo/capacitor-android-age-signalsVentana de terminal pnpm add @capgo/capacitor-android-age-signalsVentana de terminal yarn add @capgo/capacitor-android-age-signalsVentana de terminal bun add @capgo/capacitor-android-age-signals -
Sync with Android project
Ventana de terminal npx cap sync androidVentana de terminal pnpm cap sync androidVentana de terminal yarn cap sync androidVentana de terminal bunx cap sync android
Prerequisites
Section titled “Prerequisites”- Android device with Google Play Services
- Minimum Android API level 21 (Android 5.0)
- Google Play Store installed on the device
Check Age Signals
Section titled “Check 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'); // 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);}Handle Supervised Users
Section titled “Handle Supervised Users”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); }}Implement Age Gate
Section titled “Implement Age Gate”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();}Monitor Approval Status
Section titled “Monitor Approval Status”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 Reference
Section titled “API Reference”checkAgeSignals()
Section titled “checkAgeSignals()”Request the current Play Age Signals for the active user.
const result = await AgeSignals.checkAgeSignals();Returns:
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}Result Fields
Section titled “Result Fields”userStatus
Section titled “userStatus”The user’s verification status as reported by Google Play.
- Verified: User is over 18 and age-verified by Google
- Supervised: User has a supervised Google Account
- SupervisedApprovalPending: Pending guardian approval for changes
- SupervisedApprovalDenied: Guardian denied app access
- Unknown: User should verify status in Play Store
- Empty: All other users (default state)
ageLower
Section titled “ageLower”Inclusive lower bound of the supervised user’s age range.
Only present when userStatus is:
SUPERVISEDSUPERVISED_APPROVAL_PENDINGSUPERVISED_APPROVAL_DENIED
ageUpper
Section titled “ageUpper”Inclusive upper bound of the supervised user’s age range.
Only present when:
userStatusis one of the supervised statuses- User’s age is reported as less than 18
mostRecentApprovalDate
Section titled “mostRecentApprovalDate”Date string for the most recent significant change that received guardian approval.
Only present when userStatus is:
SUPERVISED_APPROVAL_PENDINGSUPERVISED_APPROVAL_DENIED
Format: ISO 8601 date string
installId
Section titled “installId”Identifier assigned to supervised installs in Google Play.
Used for revocation notifications when guardian revokes app approval.
Only present when userStatus is:
SUPERVISEDSUPERVISED_APPROVAL_PENDINGSUPERVISED_APPROVAL_DENIED
Use Cases
Section titled “Use Cases”1. COPPA Compliance
Section titled “1. COPPA Compliance”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. Age-Appropriate Content
Section titled “2. Age-Appropriate Content”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. Guardian Dashboard
Section titled “3. Guardian Dashboard”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 };}Complete Example
Section titled “Complete Example”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; }}Best Practices
Section titled “Best Practices”- Check on App Start: Verify age signals when the app launches
- Cache Results: Cache results but refresh periodically
- Handle All States: Implement logic for all UserStatus values
- Respect Denials: Don’t allow access when guardian denies approval
- Store Install ID: Track install ID for revocation detection
- Fallback Logic: Have fallback age verification for Unknown/Empty states
- Privacy First: Don’t collect unnecessary data from supervised users
Compliance Guidelines
Section titled “Compliance Guidelines”COPPA (Children’s Online Privacy Protection Act)
Section titled “COPPA (Children’s Online Privacy Protection Act)”For users under 13:
- Obtain verifiable parental consent
- Limit data collection
- Disable behavioral advertising
- Provide parental controls
GDPR (General Data Protection Regulation)
Section titled “GDPR (General Data Protection Regulation)”For supervised users:
- Process data lawfully
- Provide guardian consent mechanisms
- Allow data access and deletion
- Implement privacy by design
Platform Notes
Section titled “Platform Notes”Android
Section titled “Android”- Requires Google Play Services
- Minimum API level 21 (Android 5.0+)
- Only works on devices with Play Store
- Signals may not be available in all regions
- Results can change if guardian modifies settings
iOS / Web
Section titled “iOS / Web”- Not supported - This is an Android-only plugin
- Will throw an error if called on unsupported platforms
Troubleshooting
Section titled “Troubleshooting”No Signal Returned (Empty Status)
Section titled “No Signal Returned (Empty Status)”This is normal for:
- Users outside supported regions
- Devices without Google Play Services
- Users who haven’t set up Family Link
- New accounts without verification
Unknown Status
Section titled “Unknown Status”User should:
- Open Google Play Store
- Go to Settings → Family
- Complete age verification process
Permission Issues
Section titled “Permission Issues”Ensure:
- Google Play Services is updated
- App has correct package name in Play Console
- Testing on real device (not emulator without Play Services)