Empezando
-
Instalar el paquete
Ventana de terminal npm i @capgo/capacitor-ibeaconVentana de terminal pnpm add @capgo/capacitor-ibeaconVentana de terminal yarn add @capgo/capacitor-ibeaconVentana de terminal bun add @capgo/capacitor-ibeacon -
Sincronización con proyectos nativos
Ventana de terminal npx cap syncVentana de terminal pnpm cap syncVentana de terminal yarn cap syncVentana de terminal bunx cap sync
Configuración
Section titled “Configuración”iOS Configuración
Section titled “iOS Configuración”Agregue lo siguiente a su Info.plist:
<key>NSLocationWhenInUseUsageDescription</key><string>This app needs location access to detect nearby beacons</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key><string>This app needs location access to monitor beacons in the background</string>
<key>NSBluetoothAlwaysUsageDescription</key><string>This app uses Bluetooth to detect nearby beacons</string>
<key>UIBackgroundModes</key><array> <string>location</string></array>Android Configuración
Section titled “Android Configuración”Agregue lo siguiente a su AndroidManifest.xml:
<manifest> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /></manifest>Importante: Para Android, debe integrar la biblioteca AltBeacon en su proyecto para que funcione la detección de balizas.
Agregue al build.gradle de su aplicación:
dependencies { implementation 'org.altbeacon:android-beacon-library:2.20+'}Configuración básica
Section titled “Configuración básica”import { CapacitorIbeacon } from '@capgo/capacitor-ibeacon';
// Define your beacon regionconst beaconRegion = { identifier: 'MyStore', uuid: 'B9407F30-F5F8-466E-AFF9-25556B57FE6D', major: 1, // Optional minor: 2 // Optional};Solicitar permisos
Section titled “Solicitar permisos”// Request "When In Use" permissionconst requestPermission = async () => { const { status } = await CapacitorIbeacon.requestWhenInUseAuthorization(); console.log('Permission status:', status); // status: 'not_determined' | 'restricted' | 'denied' | 'authorized_always' | 'authorized_when_in_use'};
// Request "Always" permission (for background monitoring)const requestAlwaysPermission = async () => { const { status } = await CapacitorIbeacon.requestAlwaysAuthorization(); console.log('Always permission status:', status);};
// Check current authorization statusconst checkPermission = async () => { const { status } = await CapacitorIbeacon.getAuthorizationStatus(); console.log('Current status:', status);};Verifique las capacidades del dispositivo
Section titled “Verifique las capacidades del dispositivo”// Check if Bluetooth is enabledconst checkBluetooth = async () => { const { enabled } = await CapacitorIbeacon.isBluetoothEnabled(); if (!enabled) { console.log('Please enable Bluetooth'); }};
// Check if ranging is availableconst checkRanging = async () => { const { available } = await CapacitorIbeacon.isRangingAvailable(); console.log('Ranging available:', available);};Monitorear regiones de baliza
Section titled “Monitorear regiones de baliza”El monitoreo detecta cuando ingresa o sale de una región de baliza. Esto funciona en segundo plano.
// Start monitoringconst startMonitoring = async () => { await CapacitorIbeacon.startMonitoringForRegion({ identifier: 'MyStore', uuid: 'B9407F30-F5F8-466E-AFF9-25556B57FE6D', major: 1, minor: 2 }); console.log('Started monitoring for beacons');};
// Stop monitoringconst stopMonitoring = async () => { await CapacitorIbeacon.stopMonitoringForRegion({ identifier: 'MyStore', uuid: 'B9407F30-F5F8-466E-AFF9-25556B57FE6D' });};Balizas de alcance
Section titled “Balizas de alcance”La medición de distancia proporciona actualizaciones continuas sobre las balizas cercanas y sus distancias. Esto requiere que la aplicación esté en primer plano.
// Start rangingconst startRanging = async () => { await CapacitorIbeacon.startRangingBeaconsInRegion({ identifier: 'MyStore', uuid: 'B9407F30-F5F8-466E-AFF9-25556B57FE6D' }); console.log('Started ranging beacons');};
// Stop rangingconst stopRanging = async () => { await CapacitorIbeacon.stopRangingBeaconsInRegion({ identifier: 'MyStore', uuid: 'B9407F30-F5F8-466E-AFF9-25556B57FE6D' });};Escuchar eventos
Section titled “Escuchar eventos”import { PluginListenerHandle } from '@capacitor/core';
// Listen for ranging events (continuous distance updates)const rangingListener: PluginListenerHandle = await CapacitorIbeacon.addListener( 'didRangeBeacons', (data) => { console.log('Beacons detected:', data.beacons); data.beacons.forEach(beacon => { console.log(`UUID: ${beacon.uuid}`); console.log(`Major: ${beacon.major}, Minor: ${beacon.minor}`); console.log(`Distance: ${beacon.accuracy}m`); console.log(`Proximity: ${beacon.proximity}`); // immediate, near, far, unknown console.log(`RSSI: ${beacon.rssi}`); }); });
// Listen for region enter eventsconst enterListener: PluginListenerHandle = await CapacitorIbeacon.addListener( 'didEnterRegion', (data) => { console.log('Entered region:', data.region.identifier); // Show welcome notification or trigger action });
// Listen for region exit eventsconst exitListener: PluginListenerHandle = await CapacitorIbeacon.addListener( 'didExitRegion', (data) => { console.log('Exited region:', data.region.identifier); // Trigger goodbye action });
// Listen for region state changesconst stateListener: PluginListenerHandle = await CapacitorIbeacon.addListener( 'didDetermineStateForRegion', (data) => { console.log(`Region ${data.region.identifier}: ${data.state}`); // state: 'inside' | 'outside' | 'unknown' });
// Clean up listeners when doneconst cleanup = () => { rangingListener.remove(); enterListener.remove(); exitListener.remove(); stateListener.remove();};Anuncie como iBeacon (solo iOS)
Section titled “Anuncie como iBeacon (solo iOS)”Convierta su dispositivo en un transmisor iBeacon.
// Start advertisingconst startAdvertising = async () => { await CapacitorIbeacon.startAdvertising({ uuid: 'B9407F30-F5F8-466E-AFF9-25556B57FE6D', major: 1, minor: 2, identifier: 'MyBeacon', measuredPower: -59 // Optional: calibrated power at 1 meter }); console.log('Started advertising as iBeacon');};
// Stop advertisingconst stopAdvertising = async () => { await CapacitorIbeacon.stopAdvertising();};Ejemplo completo
Section titled “Ejemplo completo”import { CapacitorIbeacon } from '@capgo/capacitor-ibeacon';import { PluginListenerHandle } from '@capacitor/core';
export class BeaconService { private listeners: PluginListenerHandle[] = [];
async init() { // Request permissions const { status } = await CapacitorIbeacon.requestWhenInUseAuthorization();
if (status !== 'authorized_when_in_use' && status !== 'authorized_always') { throw new Error('Location permission denied'); }
// Check Bluetooth const { enabled } = await CapacitorIbeacon.isBluetoothEnabled(); if (!enabled) { throw new Error('Bluetooth is not enabled'); }
// Set up event listeners this.setupListeners(); }
private setupListeners() { this.listeners.push( await CapacitorIbeacon.addListener('didEnterRegion', (data) => { console.log('Welcome! Entered:', data.region.identifier); this.onEnterRegion(data.region); }) );
this.listeners.push( await CapacitorIbeacon.addListener('didExitRegion', (data) => { console.log('Goodbye! Left:', data.region.identifier); this.onExitRegion(data.region); }) );
this.listeners.push( await CapacitorIbeacon.addListener('didRangeBeacons', (data) => { this.onRangeBeacons(data.beacons); }) ); }
async startMonitoring(uuid: string, identifier: string, major?: number, minor?: number) { await CapacitorIbeacon.startMonitoringForRegion({ identifier, uuid, major, minor }); }
async startRanging(uuid: string, identifier: string) { await CapacitorIbeacon.startRangingBeaconsInRegion({ identifier, uuid }); }
private onEnterRegion(region: any) { // Handle region entry (e.g., show notification, trigger content) console.log('Entered beacon region:', region); }
private onExitRegion(region: any) { // Handle region exit console.log('Left beacon region:', region); }
private onRangeBeacons(beacons: any[]) { // Process beacon distances const nearestBeacon = beacons.reduce((nearest, beacon) => { return beacon.accuracy < nearest.accuracy ? beacon : nearest; }, beacons[0]);
if (nearestBeacon) { console.log('Nearest beacon:', nearestBeacon); this.handleProximity(nearestBeacon); } }
private handleProximity(beacon: any) { switch (beacon.proximity) { case 'immediate': // < 0.5m console.log('Very close to beacon'); break; case 'near': // 0.5m - 3m console.log('Near beacon'); break; case 'far': // > 3m console.log('Far from beacon'); break; case 'unknown': console.log('Distance unknown'); break; } }
cleanup() { this.listeners.forEach(listener => listener.remove()); this.listeners = []; }}API Referencia
Section titled “API Referencia”iniciarMonitoreoParaRegión(opciones)
Section titled “iniciarMonitoreoParaRegión(opciones)”Inicie el monitoreo de una región de baliza. Activa eventos al entrar/salir.
interface BeaconRegion { identifier: string; uuid: string; major?: number; minor?: number; notifyEntryStateOnDisplay?: boolean;}
await CapacitorIbeacon.startMonitoringForRegion(options);detenerMonitoringForRegion(opciones)
Section titled “detenerMonitoringForRegion(opciones)”Detener el monitoreo de una región de baliza.
await CapacitorIbeacon.stopMonitoringForRegion(options);iniciarRangingBeaconsInRegion(opciones)
Section titled “iniciarRangingBeaconsInRegion(opciones)”Comience a localizar balizas en una región para obtener actualizaciones continuas de distancia.
await CapacitorIbeacon.startRangingBeaconsInRegion(options);detenerRangingBeaconsInRegion(opciones)
Section titled “detenerRangingBeaconsInRegion(opciones)”Detener el alcance de las balizas en una región.
await CapacitorIbeacon.stopRangingBeaconsInRegion(options);iniciarPublicidad(opciones)
Section titled “iniciarPublicidad(opciones)”Comience a anunciar el dispositivo como un iBeacon (solo iOS).
interface BeaconAdvertisingOptions { uuid: string; major: number; minor: number; identifier: string; measuredPower?: number; // Calibrated power at 1 meter}
await CapacitorIbeacon.startAdvertising(options);detener la publicidad()
Section titled “detener la publicidad()”Deje de anunciar el dispositivo como un iBeacon.
await CapacitorIbeacon.stopAdvertising();solicitudCuandoInUseAuthorization()
Section titled “solicitudCuandoInUseAuthorization()”Solicite autorización de ubicación “Cuando esté en uso”.
const result = await CapacitorIbeacon.requestWhenInUseAuthorization();// Returns: { status: string }solicitarAlwaysAuthorization()
Section titled “solicitarAlwaysAuthorization()”Solicite autorización de ubicación “Siempre” (requerida para el monitoreo en segundo plano).
const result = await CapacitorIbeacon.requestAlwaysAuthorization();// Returns: { status: string }obtener estado de autorización()
Section titled “obtener estado de autorización()”Obtenga el estado de autorización de ubicación actual.
const result = await CapacitorIbeacon.getAuthorizationStatus();// Returns: { status: 'not_determined' | 'restricted' | 'denied' | 'authorized_always' | 'authorized_when_in_use' }está habilitado para Bluetooth ()
Section titled “está habilitado para Bluetooth ()”Compruebe si Bluetooth está habilitado.
const result = await CapacitorIbeacon.isBluetoothEnabled();// Returns: { enabled: boolean }estáRangingAvailable()
Section titled “estáRangingAvailable()”Compruebe si el alcance está disponible en el dispositivo.
const result = await CapacitorIbeacon.isRangingAvailable();// Returns: { available: boolean }habilitarARMAFilter(opciones)
Section titled “habilitarARMAFilter(opciones)”Habilite el filtrado ARMA para cálculos de distancia (solo Android).
await CapacitorIbeacon.enableARMAFilter({ enabled: true });Eventos
Section titled “Eventos”didRangeBeacons
Section titled “didRangeBeacons”Se dispara cuando se detectan balizas durante el alcance.
interface RangingEvent { region: BeaconRegion; beacons: Beacon[];}
interface Beacon { uuid: string; major: number; minor: number; rssi: number; // Signal strength proximity: 'immediate' | 'near' | 'far' | 'unknown'; accuracy: number; // Distance in meters}entró en la región
Section titled “entró en la región”Se dispara al ingresar a una región de baliza monitoreada.
interface RegionEvent { region: BeaconRegion;}didExitRegión
Section titled “didExitRegión”Se dispara al salir de una región de baliza monitoreada.
interface RegionEvent { region: BeaconRegion;}didDetermineStateForRegión
Section titled “didDetermineStateForRegión”Se activa cuando se determina el estado de la región.
interface StateEvent { region: BeaconRegion; state: 'inside' | 'outside' | 'unknown';}Valores de proximidad
Section titled “Valores de proximidad”- inmediato: Muy cerca (< 0.5 meters)
- near: Relatively close (0.5 - 3 meters)
- far: Further away (> 3 metros)
- desconocido: No se puede determinar la distancia
Mejores prácticas
Section titled “Mejores prácticas”-
Solicite los permisos adecuados
- Utilice “Cuando esté en uso” para funciones de primer plano
- Solicite “Siempre” solo si necesita monitoreo en segundo plano
- Explique claramente por qué necesita acceso a la ubicación.2. Manejar el estado de Bluetooth
const { enabled } = await CapacitorIbeacon.isBluetoothEnabled();if (!enabled) {// Prompt user to enable Bluetooth} -
Optimización de la batería
- Use monitoreo en lugar de rango cuando sea posible (más eficiencia de batería)
- Dejar de realizar rangos cuando no sea necesario activamente
- Considere el uso de rangos mayores/menores más grandes para reducir el procesamiento
-
Manejo de errores
try {await CapacitorIbeacon.startMonitoringForRegion(region);} catch (error) {console.error('Failed to start monitoring:', error);} -
Limpiar a los oyentes Elimine siempre los detectores de eventos cuando el componente se desmonte para evitar pérdidas de memoria.
Notas de plataforma
Section titled “Notas de plataforma”- Requiere iOS 10.0+
- Utiliza el marco nativo CoreLocation
- Admite monitoreo en segundo plano con permiso “Siempre”
- Puede anunciarse como iBeacon usando CoreBluetooth
- El rango requiere que la aplicación esté en primer plano
Android
Section titled “Android”- Requiere Android 6.0 (API 23)+
- Utiliza la biblioteca AltBeacon
- Requiere permisos de ubicación aunque las balizas usen Bluetooth
- La supervisión en segundo plano requiere ACCESS_BACKGROUND_LOCATION (Android 10+)
- No se puede anunciar como iBeacon (limitación de hardware en la mayoría de los dispositivos)
- No compatible con la plataforma web
Casos de uso comunes
Section titled “Casos de uso comunes”- Marketing de proximidad: active notificaciones o contenido cuando los usuarios se acerquen a su tienda.
- Navegación interior: guía a los usuarios a través de edificios utilizando puntos de referencia de balizas
- Seguimiento de asistencia: regístrese automáticamente cuando los usuarios ingresan a una ubicación
- Seguimiento de activos: monitorear el movimiento de equipos o inventario
- Visitas a museos: proporcione información contextual a medida que los visitantes se acerquen a las exhibiciones.
- Hogar inteligente: activa automatizaciones según la presencia de la habitación
Solución de problemas
Section titled “Solución de problemas”Balizas no detectadas
Section titled “Balizas no detectadas”- Asegúrese de que Bluetooth esté habilitado
- Verificar que se concedan los permisos de ubicación
- Verifique que el UUID de la baliza coincida exactamente (distingue entre mayúsculas y minúsculas)
- Confirmar que la baliza esté encendida y transmitiendo.
- Pruebe primero sin filtros mayores/menores
La supervisión en segundo plano no funciona
Section titled “La supervisión en segundo plano no funciona”- Asegúrese de que se conceda el permiso de ubicación “Siempre”
- Agregue
locationa UIBackgroundModes (iOS) - Solicitar ACCESS_BACKGROUND_LOCATION (Android 10+)
- Nota: iOS puede retrasar las devoluciones de llamadas en segundo plano para ahorrar batería
Mediciones de distancia inexactas
Section titled “Mediciones de distancia inexactas”- La baliza RSSI varía según el entorno (paredes, interferencias)
- Utilice múltiples balizas para la triangulación.
- Calibrar la potencia medida a 1 metro de la baliza.
- Habilite el filtrado ARMA en Android para valores más suaves