Memulai
-
Instal paket
Terminal window npm i @capgo/capacitor-ibeaconTerminal window pnpm add @capgo/capacitor-ibeaconTerminal window yarn add @capgo/capacitor-ibeaconTerminal window bun add @capgo/capacitor-ibeacon -
Sinkronkan dengan proyek native
Terminal window npx cap syncTerminal window pnpm cap syncTerminal window yarn cap syncTerminal window bunx cap sync
Konfigurasi
Section titled “Konfigurasi”Konfigurasi iOS
Section titled “Konfigurasi iOS”Tambahkan berikut ini ke Info.plist Anda:
<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>Konfigurasi Android
Section titled “Konfigurasi Android”Tambahkan berikut ini ke AndroidManifest.xml Anda:
<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>Penting: Untuk Android, Anda perlu mengintegrasikan library AltBeacon ke dalam proyek Anda agar deteksi beacon berfungsi.
Tambahkan ke build.gradle aplikasi Anda:
dependencies { implementation 'org.altbeacon:android-beacon-library:2.20+'}Penggunaan
Section titled “Penggunaan”Pengaturan Dasar
Section titled “Pengaturan Dasar”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};Minta Izin
Section titled “Minta Izin”// 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);};Periksa Kemampuan Perangkat
Section titled “Periksa Kemampuan Perangkat”// 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);};Pantau Wilayah Beacon
Section titled “Pantau Wilayah Beacon”Pemantauan mendeteksi saat Anda memasuki atau keluar dari wilayah beacon. Ini berfungsi di background.
// 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' });};Range Beacon
Section titled “Range Beacon”Ranging memberikan pembaruan berkelanjutan tentang beacon terdekat dan jaraknya. Ini memerlukan aplikasi di foreground.
// 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' });};Dengarkan Event
Section titled “Dengarkan Event”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();};Iklankan sebagai iBeacon (iOS saja)
Section titled “Iklankan sebagai iBeacon (iOS saja)”Ubah perangkat Anda menjadi transmitter 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();};Contoh Lengkap
Section titled “Contoh Lengkap”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 = []; }}Referensi API
Section titled “Referensi API”startMonitoringForRegion(options)
Section titled “startMonitoringForRegion(options)”Mulai memantau wilayah beacon. Memicu event saat masuk/keluar.
interface BeaconRegion { identifier: string; uuid: string; major?: number; minor?: number; notifyEntryStateOnDisplay?: boolean;}
await CapacitorIbeacon.startMonitoringForRegion(options);stopMonitoringForRegion(options)
Section titled “stopMonitoringForRegion(options)”Hentikan pemantauan wilayah beacon.
await CapacitorIbeacon.stopMonitoringForRegion(options);startRangingBeaconsInRegion(options)
Section titled “startRangingBeaconsInRegion(options)”Mulai ranging beacon di wilayah untuk pembaruan jarak berkelanjutan.
await CapacitorIbeacon.startRangingBeaconsInRegion(options);stopRangingBeaconsInRegion(options)
Section titled “stopRangingBeaconsInRegion(options)”Hentikan ranging beacon di wilayah.
await CapacitorIbeacon.stopRangingBeaconsInRegion(options);startAdvertising(options)
Section titled “startAdvertising(options)”Mulai mengiklankan perangkat sebagai iBeacon (iOS saja).
interface BeaconAdvertisingOptions { uuid: string; major: number; minor: number; identifier: string; measuredPower?: number; // Calibrated power at 1 meter}
await CapacitorIbeacon.startAdvertising(options);stopAdvertising()
Section titled “stopAdvertising()”Hentikan pengiklanan perangkat sebagai iBeacon.
await CapacitorIbeacon.stopAdvertising();requestWhenInUseAuthorization()
Section titled “requestWhenInUseAuthorization()”Minta otorisasi lokasi “When In Use”.
const result = await CapacitorIbeacon.requestWhenInUseAuthorization();// Returns: { status: string }requestAlwaysAuthorization()
Section titled “requestAlwaysAuthorization()”Minta otorisasi lokasi “Always” (diperlukan untuk pemantauan background).
const result = await CapacitorIbeacon.requestAlwaysAuthorization();// Returns: { status: string }getAuthorizationStatus()
Section titled “getAuthorizationStatus()”Dapatkan status otorisasi lokasi saat ini.
const result = await CapacitorIbeacon.getAuthorizationStatus();// Returns: { status: 'not_determined' | 'restricted' | 'denied' | 'authorized_always' | 'authorized_when_in_use' }isBluetoothEnabled()
Section titled “isBluetoothEnabled()”Periksa apakah Bluetooth diaktifkan.
const result = await CapacitorIbeacon.isBluetoothEnabled();// Returns: { enabled: boolean }isRangingAvailable()
Section titled “isRangingAvailable()”Periksa apakah ranging tersedia pada perangkat.
const result = await CapacitorIbeacon.isRangingAvailable();// Returns: { available: boolean }enableARMAFilter(options)
Section titled “enableARMAFilter(options)”Aktifkan filtering ARMA untuk perhitungan jarak (Android saja).
await CapacitorIbeacon.enableARMAFilter({ enabled: true });didRangeBeacons
Section titled “didRangeBeacons”Dipicu saat beacon terdeteksi selama ranging.
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}didEnterRegion
Section titled “didEnterRegion”Dipicu saat memasuki wilayah beacon yang dipantau.
interface RegionEvent { region: BeaconRegion;}didExitRegion
Section titled “didExitRegion”Dipicu saat keluar dari wilayah beacon yang dipantau.
interface RegionEvent { region: BeaconRegion;}didDetermineStateForRegion
Section titled “didDetermineStateForRegion”Dipicu saat status wilayah ditentukan.
interface StateEvent { region: BeaconRegion; state: 'inside' | 'outside' | 'unknown';}Nilai Kedekatan
Section titled “Nilai Kedekatan”- immediate: Sangat dekat (< 0.5 meter)
- near: Relatif dekat (0.5 - 3 meter)
- far: Lebih jauh (> 3 meter)
- unknown: Jarak tidak dapat ditentukan
Praktik Terbaik
Section titled “Praktik Terbaik”-
Minta izin yang sesuai
- Gunakan “When In Use” untuk fitur foreground
- Minta “Always” hanya jika Anda memerlukan pemantauan background
- Jelaskan dengan jelas mengapa Anda memerlukan akses lokasi
-
Tangani status Bluetooth
const { enabled } = await CapacitorIbeacon.isBluetoothEnabled();if (!enabled) {// Prompt user to enable Bluetooth} -
Optimasi baterai
- Gunakan monitoring daripada ranging bila memungkinkan (lebih hemat baterai)
- Hentikan ranging saat tidak diperlukan secara aktif
- Pertimbangkan menggunakan rentang major/minor yang lebih besar untuk mengurangi pemrosesan
-
Penanganan error
try {await CapacitorIbeacon.startMonitoringForRegion(region);} catch (error) {console.error('Failed to start monitoring:', error);} -
Bersihkan listener Selalu hapus event listener saat komponen unmount untuk mencegah kebocoran memori.
Catatan Platform
Section titled “Catatan Platform”- Memerlukan iOS 10.0+
- Menggunakan framework CoreLocation native
- Mendukung pemantauan background dengan izin “Always”
- Dapat mengiklankan sebagai iBeacon menggunakan CoreBluetooth
- Ranging memerlukan aplikasi di foreground
Android
Section titled “Android”- Memerlukan Android 6.0 (API 23)+
- Menggunakan library AltBeacon
- Memerlukan izin lokasi meskipun beacon menggunakan Bluetooth
- Pemantauan background memerlukan ACCESS_BACKGROUND_LOCATION (Android 10+)
- Tidak dapat mengiklankan sebagai iBeacon (keterbatasan hardware pada sebagian besar perangkat)
- Tidak didukung pada platform web
Kasus Penggunaan Umum
Section titled “Kasus Penggunaan Umum”- Marketing Kedekatan: Picu notifikasi atau konten saat pengguna mendekati toko Anda
- Navigasi Dalam Ruangan: Pandu pengguna melalui gedung menggunakan waypoint beacon
- Pelacakan Kehadiran: Otomatis check-in saat pengguna memasuki lokasi
- Pelacakan Aset: Pantau pergerakan peralatan atau inventaris
- Tur Museum: Berikan informasi kontekstual saat pengunjung mendekati pameran
- Smart Home: Picu otomasi berdasarkan kehadiran di ruangan
Pemecahan Masalah
Section titled “Pemecahan Masalah”Beacon tidak terdeteksi
Section titled “Beacon tidak terdeteksi”- Pastikan Bluetooth diaktifkan
- Verifikasi izin lokasi diberikan
- Periksa UUID beacon cocok persis (case-sensitive)
- Konfirmasi beacon dihidupkan dan mentransmisi
- Coba tanpa filter major/minor terlebih dahulu
Pemantauan background tidak berfungsi
Section titled “Pemantauan background tidak berfungsi”- Pastikan izin lokasi “Always” diberikan
- Tambahkan
locationke UIBackgroundModes (iOS) - Minta ACCESS_BACKGROUND_LOCATION (Android 10+)
- Catatan: iOS mungkin menunda callback background untuk menghemat baterai
Pengukuran jarak tidak akurat
Section titled “Pengukuran jarak tidak akurat”- RSSI beacon bervariasi dengan lingkungan (dinding, interferensi)
- Gunakan beberapa beacon untuk triangulasi
- Kalibrasi measuredPower pada jarak 1 meter dari beacon
- Aktifkan filtering ARMA di Android untuk nilai yang lebih halus