expo-beacon 0.8.9 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -744,6 +744,50 @@ CarPlay observation is **persistent** — the enabled flag is stored in native p
744
744
  - On iOS, if the JS bundle is suspended in the background, the JS event delivery is deferred until the app resumes, but the native lifecycle delegate (used by the geolocation plugin) fires immediately on connect.
745
745
  - On Android, when CarPlay monitoring is enabled without beacon monitoring, the foreground service shows a generic "Connected device monitoring active" notification.
746
746
 
747
+ **Android Auto registration (automatic via config plugin)**
748
+
749
+ On Android 14+ — and especially with **wireless Android Auto** — `CarConnection.getType()` silently returns `NOT_CONNECTED` for any app that has not declared itself Android-Auto-aware. The bundled config plugin handles this for you: on the next `expo prebuild` it injects a `com.google.android.gms.car.application` meta-data entry into `AndroidManifest.xml` and writes `res/xml/automotive_app_desc.xml` with `<uses name="template"/>`. No manual native edits are required.
750
+
751
+ If you need to disable this (e.g. you already ship your own Android Auto template app and don't want a duplicate registration) or you need to declare a different capability than `template`, configure the plugin in your app config:
752
+
753
+ ```json
754
+ {
755
+ "expo": {
756
+ "plugins": [
757
+ ["expo-beacon", {
758
+ "android": {
759
+ "androidAuto": {
760
+ "register": true,
761
+ "usesName": "template"
762
+ }
763
+ }
764
+ }]
765
+ ]
766
+ }
767
+ }
768
+ ```
769
+
770
+ `usesName` accepts any value supported by Android's [`automotiveApp` schema](https://developer.android.com/training/cars/apps#manifest) (`template`, `media`, `notification`, …). Setting `register: false` skips both the meta-data and the resource file.
771
+
772
+ **Diagnostics**
773
+
774
+ If `onCarPlayConnected` never fires on Android, call `getCarPlayDiagnostics()` to inspect the native state:
775
+
776
+ ```ts
777
+ const d = await ExpoBeacon.getCarPlayDiagnostics();
778
+ // {
779
+ // platform: "android",
780
+ // carPlayEnabled: true,
781
+ // isCarAppMetadataPresent: true, // false → config plugin didn't run; prebuild again
782
+ // isCarProviderQueryable: true, // false → Android Auto app not installed on device
783
+ // lastRawConnectionType: 0, // 0=DISCONNECTED 1=PROJECTION 2=NATIVE
784
+ // observerActive: true,
785
+ // serviceAlive: true,
786
+ // }
787
+ ```
788
+
789
+ A response with `isCarAppMetadataPresent: false` indicates the AA registration didn't make it into the built APK — re-run `expo prebuild --clean` to apply the plugin changes.
790
+
747
791
  ---
748
792
 
749
793
  ## Full API Reference
@@ -22,7 +22,8 @@ dependencies {
22
22
  implementation 'org.altbeacon:android-beacon-library:2.21.2'
23
23
  // androidx.car.app provides CarConnection LiveData for detecting Android Auto sessions.
24
24
  // No Android Auto certification or extra permissions required for read-only state.
25
- implementation 'androidx.car.app:app:1.4.0'
25
+ // 1.7.0 fixes known wireless-AA + Android 14 issues that existed in 1.4.0/1.5.x.
26
+ implementation 'androidx.car.app:app:1.7.0'
26
27
  // WorkManager powers the CarPlay watchdog (periodic restart of the foreground
27
28
  // service if it was killed by the OS / OEM cleaners while CarPlay observation
28
29
  // is enabled). Minimum periodic interval is 15 min; an AlarmManager loop in
@@ -158,8 +158,12 @@ class BeaconForegroundService : Service(), BeaconConsumer {
158
158
  Log.e(TAG, "startForeground failed (retry=$retryCount) — stopping service", e)
159
159
  sendErrorBroadcast(null, "SERVICE_START_FAILED", "startForeground failed (retry=$retryCount): ${e.message}")
160
160
  // Schedule a retry so monitoring can recover without user interaction, capped to
161
- // avoid infinite crash loops. Only retry if monitoring should still be active.
162
- if (retryCount < MAX_STARTFOREGROUND_RETRIES && isMonitoringActive(this)) {
161
+ // avoid infinite crash loops. Retry if EITHER beacon monitoring OR CarPlay
162
+ // observation is supposed to be active — without the CarPlay branch the
163
+ // service silently dies when the very first startCarPlayMonitoring() call
164
+ // races with a transient BT permission / FGS-restriction failure.
165
+ if (retryCount < MAX_STARTFOREGROUND_RETRIES &&
166
+ (isMonitoringActive(this) || isCarPlayEnabled(this))) {
163
167
  scheduleServiceRetry(retryCount + 1)
164
168
  }
165
169
  stopSelf()
@@ -1226,6 +1230,46 @@ class BeaconForegroundService : Service(), BeaconConsumer {
1226
1230
  return mapOf("connected" to connected)
1227
1231
  }
1228
1232
 
1233
+ /**
1234
+ * Returns a diagnostic snapshot of the CarPlay / Android Auto detection
1235
+ * pipeline. Probes for the host-app AA registration meta-data and the
1236
+ * resolvability of the CarConnection content provider so callers can
1237
+ * tell from JS whether the underlying detection requirements are met.
1238
+ */
1239
+ fun getCarPlayDiagnostics(context: Context): Map<String, Any?> {
1240
+ val pm = context.packageManager
1241
+ // 1) Is the host app declared as an Android-Auto-aware app?
1242
+ val metadataPresent = try {
1243
+ val ai = pm.getApplicationInfo(
1244
+ context.packageName,
1245
+ android.content.pm.PackageManager.GET_META_DATA,
1246
+ )
1247
+ ai.metaData?.containsKey("com.google.android.gms.car.application") == true
1248
+ } catch (_: Throwable) { false }
1249
+
1250
+ // 2) Can the system resolve any provider for the CAR_PROVIDER action?
1251
+ // This combines (a) <queries> visibility on API 30+, and (b) a
1252
+ // Gearhead / AAOS install that actually advertises the provider.
1253
+ val providerQueryable = try {
1254
+ val intent = Intent("androidx.car.app.connection.action.CAR_PROVIDER")
1255
+ val resolved = pm.queryIntentContentProviders(intent, 0)
1256
+ resolved.isNotEmpty()
1257
+ } catch (_: Throwable) { false }
1258
+
1259
+ val monitor = activeService?.carPlayMonitor
1260
+ val lastRaw: Int? = if (monitor != null && monitor.hasObservedValue) monitor.lastObservedType else null
1261
+ val observerActive = monitor?.isObserving() == true
1262
+ val serviceAlive = activeService != null
1263
+
1264
+ return mapOf(
1265
+ "isCarAppMetadataPresent" to metadataPresent,
1266
+ "isCarProviderQueryable" to providerQueryable,
1267
+ "lastRawConnectionType" to lastRaw,
1268
+ "observerActive" to observerActive,
1269
+ "serviceAlive" to serviceAlive,
1270
+ )
1271
+ }
1272
+
1229
1273
  /**
1230
1274
  * Ensure the notification channel exists. Must be called before building
1231
1275
  * a notification from a non-service context (e.g. ExpoBeaconModule).
@@ -47,7 +47,18 @@ internal class CarPlayMonitor(private val context: Context) {
47
47
  */
48
48
  private var pendingDisconnectCheck: Runnable? = null
49
49
  /** Most recent raw type seen from the LiveData; used by the grace re-check. */
50
- @Volatile private var lastObservedType: Int = CarConnection.CONNECTION_TYPE_NOT_CONNECTED
50
+ @Volatile internal var lastObservedType: Int = CarConnection.CONNECTION_TYPE_NOT_CONNECTED
51
+ private set
52
+
53
+ /**
54
+ * Whether the observer has ever received a value from the LiveData since
55
+ * [start] was called. Useful for diagnostics — if this is `false` 5+
56
+ * seconds after `start()`, the `CarConnection` content provider isn't
57
+ * resolving (most commonly because the host app isn't registered as an
58
+ * Android Auto app via `automotive_app_desc.xml`).
59
+ */
60
+ @Volatile internal var hasObservedValue: Boolean = false
61
+ private set
51
62
 
52
63
  /**
53
64
  * Begin observing connection state. Idempotent — calling twice replaces the
@@ -68,7 +79,23 @@ internal class CarPlayMonitor(private val context: Context) {
68
79
  observer = obs
69
80
  try {
70
81
  liveData.observeForever(obs)
71
- Log.d(TAG, "CarPlay monitoring started (seeded lastConnected=$lastConnected)")
82
+ Log.d(TAG, "CarPlay monitoring started (seeded lastConnected=$lastConnected, lib=androidx.car.app)")
83
+ // Diagnostic safety-net: if no value arrives within
84
+ // [DIAGNOSTIC_PROBE_MS], emit a loud warning. The most
85
+ // common cause is a missing `com.google.android.gms.car.application`
86
+ // meta-data entry in the host app's manifest — Gearhead
87
+ // then silently returns NOT_CONNECTED and the LiveData
88
+ // never updates beyond the bootstrap value.
89
+ mainHandler.postDelayed({
90
+ if (!hasObservedValue) {
91
+ Log.w(TAG, "CarPlay diagnostic: no CarConnection value received after ${DIAGNOSTIC_PROBE_MS}ms. " +
92
+ "Host app is likely missing the AndroidAuto registration meta-data " +
93
+ "(<meta-data android:name=\"com.google.android.gms.car.application\" android:resource=\"@xml/automotive_app_desc\"/>). " +
94
+ "Enable the expo-beacon plugin's `android.androidAuto.register` option (default in 0.9+) and re-run `expo prebuild`.")
95
+ } else {
96
+ Log.d(TAG, "CarPlay diagnostic: lastObservedType=$lastObservedType after ${DIAGNOSTIC_PROBE_MS}ms (OK)")
97
+ }
98
+ }, DIAGNOSTIC_PROBE_MS)
72
99
  } catch (e: Exception) {
73
100
  Log.w(TAG, "Failed to start CarPlay monitoring: ${e.message}")
74
101
  }
@@ -122,6 +149,7 @@ internal class CarPlayMonitor(private val context: Context) {
122
149
 
123
150
  private fun handleType(type: Int) {
124
151
  lastObservedType = type
152
+ hasObservedValue = true
125
153
  val connected = type != CarConnection.CONNECTION_TYPE_NOT_CONNECTED
126
154
  val previous = lastConnected
127
155
 
@@ -248,6 +276,13 @@ internal class CarPlayMonitor(private val context: Context) {
248
276
  * (e.g. after the app is swiped away and START_STICKY revives us).
249
277
  */
250
278
  private const val BOOTSTRAP_GRACE_MS = 3_000L
279
+ /**
280
+ * Delay after which [start] emits a loud diagnostic log if the
281
+ * LiveData has not delivered a single value. 5 s comfortably covers
282
+ * the cold-start content-provider resolution path even on slow
283
+ * devices.
284
+ */
285
+ private const val DIAGNOSTIC_PROBE_MS = 5_000L
251
286
  // ISO 8601 UTC with millisecond precision. Safe for all supported APIs (minSdk 23).
252
287
  private val ISO_FORMAT = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US).apply {
253
288
  timeZone = TimeZone.getTimeZone("UTC")
@@ -1,4 +1,4 @@
1
- package expo.modules.beacon
1
+ package expo.modules.beacon
2
2
 
3
3
  import android.content.Context
4
4
  import android.util.Log
@@ -18,8 +18,13 @@ import java.util.concurrent.TimeUnit
18
18
  * alive this is a cheap no-op; if it is dead it cold-starts a fresh
19
19
  * foreground instance and re-attaches [CarPlayMonitor].
20
20
  *
21
- * WorkManager guarantees a minimum 15-minute period. A second
22
- * `AlarmManager` loop in [BootReceiver] covers the sub-15-min gap.
21
+ * WorkManager guarantees a minimum 15-minute period. A second AlarmManager
22
+ * loop in [BootReceiver] covers the sub-15-min gap AND — critically on
23
+ * API 31+ — is the path the OS allows to call startForegroundService from
24
+ * background: broadcast receivers running an exact-alarm trigger are granted
25
+ * the brief foreground-importance window required. If enableCarPlay throws
26
+ * here from a background worker (ForegroundServiceStartNotAllowedException),
27
+ * the next alarm tick will recover.
23
28
  */
24
29
  internal class CarPlayWatchdogWorker(
25
30
  appContext: Context,
@@ -29,7 +34,6 @@ internal class CarPlayWatchdogWorker(
29
34
  override fun doWork(): Result {
30
35
  val ctx = applicationContext
31
36
  if (!BeaconForegroundService.isCarPlayEnabled(ctx)) {
32
- // User turned CarPlay off — let the periodic work fade out via cancel().
33
37
  Log.d(TAG, "Watchdog tick: CarPlay disabled, no action")
34
38
  return Result.success()
35
39
  }
@@ -37,10 +41,17 @@ internal class CarPlayWatchdogWorker(
37
41
  BeaconForegroundService.enableCarPlay(ctx)
38
42
  Log.d(TAG, "Watchdog tick: ensured BeaconForegroundService is running for CarPlay")
39
43
  } catch (t: Throwable) {
40
- Log.w(TAG, "Watchdog tick: enableCarPlay failed", t)
41
- // Returning retry would just defer to the next period; success keeps
42
- // the periodic schedule running and avoids burning the retry budget.
44
+ // Expected on API 31+ when the worker runs while the app is fully
45
+ // backgrounded startForegroundService is blocked. The AlarmManager
46
+ // loop in BootReceiver runs in a receiver context and IS permitted
47
+ // to make the same call, so recovery still happens within ~11 min.
48
+ Log.d(
49
+ TAG,
50
+ "Watchdog tick: enableCarPlay deferred to alarm loop (${t.javaClass.simpleName}): ${t.message}",
51
+ )
43
52
  }
53
+ // Always success — don't burn WorkManager's retry budget on a known
54
+ // OS-level background restriction.
44
55
  return Result.success()
45
56
  }
46
57
 
@@ -67,9 +78,6 @@ internal class CarPlayWatchdogWorker(
67
78
  )
68
79
  Log.d(TAG, "Watchdog scheduled (15 min period)")
69
80
  } catch (t: Throwable) {
70
- // WorkManager.getInstance() can throw IllegalStateException if the
71
- // host app has not initialised it. Fall back silently — the
72
- // AlarmManager loop in BootReceiver still provides coverage.
73
81
  Log.w(TAG, "Failed to schedule CarPlay watchdog", t)
74
82
  }
75
83
  }
@@ -611,6 +611,20 @@ class ExpoBeaconModule : Module(), BeaconConsumer {
611
611
  BeaconForegroundService.getCarPlayStatus(ctx)
612
612
  }
613
613
 
614
+ Function("getCarPlayDiagnostics") {
615
+ val ctx = appContext.reactContext
616
+ if (ctx == null) {
617
+ return@Function mapOf(
618
+ "isCarAppMetadataPresent" to false,
619
+ "isCarProviderQueryable" to false,
620
+ "lastRawConnectionType" to null,
621
+ "observerActive" to false,
622
+ "serviceAlive" to false,
623
+ )
624
+ }
625
+ BeaconForegroundService.getCarPlayDiagnostics(ctx)
626
+ }
627
+
614
628
  OnCreate {
615
629
  // Register this module instance for best-effort JS-bridge fan-out
616
630
  // of CarPlay events emitted by the foreground service. The service
@@ -333,6 +333,61 @@ export type CarPlayConnectionStatus = {
333
333
  /** ISO 8601 UTC timestamp of last connect. Present only when `connected` is `true`. */
334
334
  timestampIso?: string;
335
335
  };
336
+ /**
337
+ * Diagnostic snapshot for troubleshooting CarPlay / Android Auto detection.
338
+ * Returned by {@link ExpoBeaconModule.getCarPlayDiagnostics}.
339
+ *
340
+ * The most common failure mode on Android is that the host app is not
341
+ * registered as an Android Auto-aware app (missing
342
+ * `com.google.android.gms.car.application` meta-data + `automotive_app_desc.xml`
343
+ * resource). When that happens, Gearhead silently reports
344
+ * `CONNECTION_TYPE_NOT_CONNECTED` to the app regardless of `<queries>`
345
+ * declarations, so `onCarPlayConnected` events never fire.
346
+ *
347
+ * Inspect this object after calling `startCarPlayMonitoring()` and confirming
348
+ * Android Auto is connected on the head unit. If `isCarAppMetadataPresent` or
349
+ * `isCarProviderQueryable` is `false`, the consumer app needs to enable the
350
+ * config plugin's `android.androidAuto.register` option (default in recent
351
+ * versions) and re-run `expo prebuild`.
352
+ *
353
+ * On iOS the diagnostic is a best-effort stub — most fields are not applicable
354
+ * because CarPlay detection uses `AVAudioSession` rather than a content
355
+ * provider.
356
+ */
357
+ export type CarPlayDiagnostics = {
358
+ /**
359
+ * Android: `true` if the host app's manifest declares the
360
+ * `com.google.android.gms.car.application` meta-data tag (required for
361
+ * Gearhead to expose connection state to the app). iOS: always `true`.
362
+ */
363
+ isCarAppMetadataPresent: boolean;
364
+ /**
365
+ * Android: `true` if the system can resolve at least one provider for the
366
+ * `androidx.car.app.connection.action.CAR_PROVIDER` intent (requires the
367
+ * `<queries>` declaration shipped by this library AND a compatible Gearhead
368
+ * / AAOS install on the device). iOS: always `true`.
369
+ */
370
+ isCarProviderQueryable: boolean;
371
+ /**
372
+ * Android: most recent raw value read from `CarConnection.getType()`.
373
+ * `0` = `NOT_CONNECTED`, `1` = `NATIVE` (AAOS), `2` = `PROJECTION`.
374
+ * `null` if the observer has not yet received any value (or is not running).
375
+ * iOS: `null`.
376
+ */
377
+ lastRawConnectionType: number | null;
378
+ /**
379
+ * `true` if the underlying connection observer is currently active.
380
+ * On Android, equivalent to "the foreground service is running AND
381
+ * `CarPlayMonitor.start()` succeeded". On iOS, the audio-session observer
382
+ * is registered.
383
+ */
384
+ observerActive: boolean;
385
+ /**
386
+ * Android: `true` if the foreground service hosting the observer is alive.
387
+ * iOS: always `true` (no background service involved).
388
+ */
389
+ serviceAlive: boolean;
390
+ };
336
391
  /** Payload for native beacon error events (monitoring/ranging failures). */
337
392
  export type BeaconErrorEvent = {
338
393
  /** Region or constraint identifier, empty string if unavailable. */
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoBeacon.types.d.ts","sourceRoot":"","sources":["../src/ExpoBeacon.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ExpoBeacon.types.d.ts","sourceRoot":"","sources":["../src/ExpoBeacon.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoBeacon.types.js","sourceRoot":"","sources":["../src/ExpoBeacon.types.ts"],"names":[],"mappings":"","sourcesContent":["/** Raw beacon discovered during a scan. */\r\nexport type BeaconScanResult = {\r\n uuid: string; // iBeacon proximity UUID (uppercase, formatted)\r\n major: number; // iBeacon major value (0–65535)\r\n minor: number; // iBeacon minor value (0–65535)\r\n rssi: number; // Signal strength in dBm (negative number)\r\n distance: number; // Estimated distance in meters\r\n txPower: number; // Calibrated TX power\r\n /** BLE advertising device name. May be undefined on iOS (CoreLocation does not expose it for iBeacon). */\r\n name?: string;\r\n};\r\n\r\n/**\r\n * A beacon that has been paired/registered for monitoring.\r\n *\r\n * Note: Paired beacon data is stored unencrypted in UserDefaults (iOS) /\r\n * SharedPreferences (Android) and may be included in device backups.\r\n */\r\nexport type PairedBeacon = {\r\n identifier: string; // User-defined label (e.g. \"lobby-door\")\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n /** BLE advertising device name, if provided at pairing time. */\r\n name?: string;\r\n /**\r\n * Timeout in seconds. When set, the module fires `onBeaconTimeout` once\r\n * after the beacon has been continuously in range for this duration.\r\n * The timer resets if the beacon exits and re-enters range.\r\n *\r\n * The timeout countdown also starts if no BLE readings are received\r\n * for 60 seconds (e.g. due to Doze mode or background throttling).\r\n */\r\n timeoutSeconds?: number;\r\n};\r\n\r\n/** Payload for enter/exit region events. */\r\nexport type BeaconRegionEvent = {\r\n identifier: string; // Matches PairedBeacon.identifier\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n event: \"enter\" | \"exit\";\r\n /** Measured distance in metres at the time of the event (–1 if unavailable). */\r\n distance: number;\r\n /** Signal strength in dBm at the time of the event (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for periodic distance update events during monitoring. */\r\nexport type BeaconDistanceEvent = {\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n distance: number;\r\n /** Signal strength in dBm (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for beacon timeout events (beacon in range for configured duration). */\r\nexport type BeaconTimeoutEvent = {\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n /** Current distance in metres at the time the timeout fired. */\r\n distance: number;\r\n};\r\n\r\n/** Configuration for beacon enter/exit event notifications. */\r\nexport type BeaconNotificationConfig = {\r\n /** Whether to show enter/exit notifications. Default: true. */\r\n enabled?: boolean;\r\n /** Notification title on beacon enter. Default: \"Beacon Entered\". */\r\n enterTitle?: string;\r\n /** Notification title on beacon exit. Default: \"Beacon Exited\". */\r\n exitTitle?: string;\r\n /** Notification title on beacon timeout. Default: \"Beacon Timeout\". */\r\n timeoutTitle?: string;\r\n /**\r\n * Notification body template. Supports {identifier} and {event} placeholders.\r\n * Default: \"{identifier} region {event}ed\".\r\n */\r\n body?: string;\r\n /** Play a sound with the notification (iOS only). Default: true. */\r\n sound?: boolean;\r\n /** Android drawable resource name for the notification icon (e.g. \"ic_notification\"). */\r\n icon?: string;\r\n};\r\n\r\n/** Configuration for the Android foreground service notification (persistent status bar entry). */\r\nexport type ForegroundServiceConfig = {\r\n /** Title of the persistent notification. Default: \"Beacon Monitoring Active\". */\r\n title?: string;\r\n /** Body text of the persistent notification. Default: \"Monitoring for iBeacons in the background\". */\r\n text?: string;\r\n /** Android drawable resource name for the notification icon. */\r\n icon?: string;\r\n};\r\n\r\n/** Configuration for the Android notification channel. */\r\nexport type NotificationChannelConfig = {\r\n /** Channel display name shown in system settings. Default: \"Beacon Monitoring\". */\r\n name?: string;\r\n /** Channel description shown in system settings. Default: \"Used for background iBeacon region monitoring\". */\r\n description?: string;\r\n /**\r\n * Channel importance level. Default: 'low'.\r\n * Note: Android may ignore decreases in importance after first channel creation until the app is reinstalled.\r\n */\r\n importance?: \"low\" | \"default\" | \"high\";\r\n};\r\n\r\n/** Configuration for CarPlay / Android Auto connect/disconnect notifications. */\r\nexport type CarPlayNotificationConfig = {\r\n /** Whether to show CarPlay connect/disconnect notifications. Default: true. */\r\n enabled?: boolean;\r\n /** Notification title on CarPlay/Android Auto connect. Default: \"CarPlay Connected\". */\r\n connectedTitle?: string;\r\n /** Notification title on CarPlay/Android Auto disconnect. Default: \"CarPlay Disconnected\". */\r\n disconnectedTitle?: string;\r\n /**\r\n * Notification body template. Supports `{event}` (\"connected\"/\"disconnected\") and\r\n * `{transport}` (e.g. \"wired\", \"wireless\", \"projection\", \"native\", \"unknown\") placeholders.\r\n * Note: `{transport}` is only meaningful for connect events; on disconnect it is replaced with an empty string.\r\n * Default: \"CarPlay session {event}\".\r\n */\r\n body?: string;\r\n /** Play a sound with the notification (iOS only). Default: true. */\r\n sound?: boolean;\r\n /** Android drawable resource name for the notification icon (e.g. \"ic_notification\"). */\r\n icon?: string;\r\n};\r\n\r\n/** Configuration for the Android notification channel used for CarPlay events. */\r\nexport type CarPlayChannelConfig = {\r\n /** Channel display name shown in system settings. Default: \"CarPlay / Android Auto\". */\r\n name?: string;\r\n /** Channel description shown in system settings. Default: \"CarPlay and Android Auto connect/disconnect notifications\". */\r\n description?: string;\r\n /**\r\n * Channel importance level. Default: 'default' (so connect/disconnect events make a sound).\r\n * Note: Android may ignore decreases in importance after first channel creation until the app is reinstalled.\r\n */\r\n importance?: \"low\" | \"default\" | \"high\";\r\n};\r\n\r\n/** Combined notification configuration for all notification types. */\r\nexport type NotificationConfig = {\r\n /** Settings for beacon enter/exit event notifications. */\r\n beaconEvents?: BeaconNotificationConfig;\r\n /** Settings for CarPlay / Android Auto connect/disconnect notifications. */\r\n carPlayEvents?: CarPlayNotificationConfig;\r\n /** Settings for the persistent foreground service notification (Android only). */\r\n foregroundService?: ForegroundServiceConfig;\r\n /** Settings for the Android notification channel (Android only). */\r\n channel?: NotificationChannelConfig;\r\n /** Settings for the Android notification channel used for CarPlay events (Android only). */\r\n carPlayChannel?: CarPlayChannelConfig;\r\n};\r\n\r\n/** Snapshot of the current monitoring configuration and active state. */\r\nexport type MonitoringConfig = {\r\n /** Whether background monitoring is currently active. */\r\n isMonitoring: boolean;\r\n maxDistance?: number;\r\n exitDistance?: number;\r\n minRssi?: number;\r\n level?: 'all' | 'events';\r\n /** Seconds after last beacon sighting before an exit event fires. Default: 300. */\r\n exitTimeoutSeconds?: number;\r\n notifications?: NotificationConfig;\r\n};\r\n\r\n/** Current state snapshot for a paired monitored device. */\r\nexport type MonitoredDeviceState =\r\n | {\r\n kind: \"ibeacon\";\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n state: \"entered\" | \"exited\";\r\n /** Current distance in metres, or null when exited or no live reading is available. */\r\n distance: number | null;\r\n }\r\n | {\r\n kind: \"eddystone\";\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n state: \"entered\" | \"exited\";\r\n /** Current distance in metres, or null when exited or no live reading is available. */\r\n distance: number | null;\r\n };\r\n\r\n/** Options accepted by startMonitoring(). */\r\nexport type MonitoringOptions = {\r\n /**\r\n * Maximum distance in metres for distance-based enter events.\r\n * Exit events are always emitted when the region is lost.\r\n */\r\n maxDistance?: number;\r\n /**\r\n * Distance in metres at which exit events fire (must be ≥ maxDistance).\r\n * Creates a hysteresis band between enter and exit thresholds to prevent\r\n * rapid toggling near the boundary.\r\n *\r\n * Default when omitted: `maxDistance + min(maxDistance × 0.5, 2.5)`.\r\n * Only used when `maxDistance` is set.\r\n */\r\n exitDistance?: number;\r\n /**\r\n * Minimum RSSI (dBm) for a beacon reading to be considered valid.\r\n * Readings below this threshold are discarded as unreliable, preventing\r\n * false detections from reflected or distant signals.\r\n *\r\n * Default: -85. Typical range: -100 (very permissive) to -70 (strict).\r\n */\r\n minRssi?: number;\r\n /**\r\n * Controls which event types are emitted, logged, and forwarded to the API.\r\n *\r\n * - `'all'` (default): distance + enter + exit + timeout events.\r\n * - `'events'`: enter + exit + timeout only (no distance events).\r\n */\r\n level?: 'all' | 'events';\r\n /**\r\n * Seconds after last beacon sighting before an exit event fires when the beacon\r\n * disappears without moving outside the exit distance threshold.\r\n *\r\n * Default: 300 (5 minutes). Minimum: 1.\r\n */\r\n exitTimeoutSeconds?: number;\r\n /** Notification configuration overrides to apply for this monitoring session. */\r\n notifications?: NotificationConfig;\r\n};\r\n\r\n/** Eddystone frame type. */\r\nexport type EddystoneFrameType = \"uid\" | \"url\";\r\n\r\n/** Raw Eddystone beacon discovered during a scan. */\r\nexport type EddystoneScanResult = {\r\n frameType: EddystoneFrameType;\r\n /** 10-byte namespace ID as hex string (20 chars). Present for UID frames. */\r\n namespace?: string;\r\n /** 6-byte instance ID as hex string (12 chars). Present for UID frames. */\r\n instance?: string;\r\n /** Decoded URL. Present for URL frames. */\r\n url?: string;\r\n rssi: number;\r\n distance: number;\r\n txPower: number;\r\n /** BLE advertising device name. */\r\n name?: string;\r\n};\r\n\r\n/**\r\n * An Eddystone-UID beacon that has been paired/registered for monitoring.\r\n *\r\n * Note: Paired beacon data is stored unencrypted in UserDefaults (iOS) /\r\n * SharedPreferences (Android) and may be included in device backups.\r\n */\r\nexport type PairedEddystone = {\r\n identifier: string;\r\n /** 10-byte namespace ID as hex string (20 chars). */\r\n namespace: string;\r\n /** 6-byte instance ID as hex string (12 chars). */\r\n instance: string;\r\n /** BLE advertising device name, if provided at pairing time. */\r\n name?: string;\r\n /**\r\n * Timeout in seconds. When set, the module fires `onEddystoneTimeout` once\r\n * after the beacon has been continuously in range for this duration.\r\n * The timer resets if the beacon exits and re-enters range.\r\n *\r\n * The timeout countdown also starts if no BLE readings are received\r\n * for 60 seconds (e.g. due to Doze mode or background throttling).\r\n */\r\n timeoutSeconds?: number;\r\n};\r\n\r\n/** Payload for Eddystone enter/exit region events. */\r\nexport type EddystoneRegionEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n event: \"enter\" | \"exit\";\r\n /** Measured distance in metres at the time of the event (–1 if unavailable). */\r\n distance: number;\r\n /** Signal strength in dBm at the time of the event (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for periodic Eddystone distance update events during monitoring. */\r\nexport type EddystoneDistanceEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n distance: number;\r\n /** Signal strength in dBm (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for Eddystone timeout events (beacon in range for configured duration). */\r\nexport type EddystoneTimeoutEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n /** Current distance in metres at the time the timeout fired. */\r\n distance: number;\r\n};\r\n\r\n/** Transport reported with CarPlay / Android Auto connection events. */\r\nexport type CarPlayTransport =\r\n | \"wired\" // iOS CarPlay over USB / Lightning\r\n | \"wireless\" // iOS CarPlay over Bluetooth + Wi-Fi\r\n | \"projection\" // Android Auto projection (phone projecting to head unit)\r\n | \"native\" // Android Automotive OS (running on the head unit)\r\n | \"unknown\";\r\n\r\n/** Payload fired when the device connects to a CarPlay or Android Auto session. */\r\nexport type CarPlayConnectedEvent = {\r\n transport: CarPlayTransport;\r\n /** Timestamp in milliseconds since epoch. */\r\n timestamp: number;\r\n /** ISO 8601 UTC representation of {@link timestamp} (e.g. \"2026-05-12T14:23:45.678Z\"). */\r\n timestampIso?: string;\r\n};\r\n\r\n/** Payload fired when the device disconnects from a CarPlay or Android Auto session. */\r\nexport type CarPlayDisconnectedEvent = {\r\n /** Timestamp in milliseconds since epoch. */\r\n timestamp: number;\r\n /** ISO 8601 UTC representation of {@link timestamp} (e.g. \"2026-05-12T14:23:45.678Z\"). */\r\n timestampIso?: string;\r\n /**\r\n * Reason this disconnect was emitted. Absent for normal real-time disconnects.\r\n * `\"reconciled\"` indicates the disconnect was synthesized after the module was\r\n * recreated in a new process and detected that the previously persisted CarPlay\r\n * state no longer matches the current connection — i.e. the disconnect happened\r\n * off-process (force-quit, OS reclaim, abrupt cable yank) and is being delivered\r\n * post-hoc. Emitted on both iOS and Android.\r\n */\r\n reason?: \"reconciled\";\r\n};\r\n\r\n/**\r\n * Snapshot of the current CarPlay / Android Auto connection state, returned by\r\n * {@link ExpoBeaconModule.getCarPlayConnectionStatus}.\r\n */\r\nexport type CarPlayConnectionStatus = {\r\n /** `true` if a CarPlay or Android Auto session is currently active. */\r\n connected: boolean;\r\n /**\r\n * Connection transport type. Present only when `connected` is `true`.\r\n * See {@link CarPlayTransport} for possible values.\r\n */\r\n transport?: CarPlayTransport;\r\n /** Unix-millisecond timestamp of last connect. Present only when `connected` is `true`. */\r\n timestamp?: number;\r\n /** ISO 8601 UTC timestamp of last connect. Present only when `connected` is `true`. */\r\n timestampIso?: string;\r\n};\r\n\r\n/** Payload for native beacon error events (monitoring/ranging failures). */\r\nexport type BeaconErrorEvent = {\r\n /** Region or constraint identifier, empty string if unavailable. */\r\n identifier: string;\r\n /** Machine-readable error code (e.g. \"MONITORING_FAILED\", \"RANGING_FAILED\", \"SECURITY_EXCEPTION\"). */\r\n code: string;\r\n /** Human-readable error message from the native layer. */\r\n message: string;\r\n};\r\n\r\n/** Module event map. */\r\nexport type ExpoBeaconModuleEvents = {\r\n onBeaconEnter: (params: BeaconRegionEvent) => void;\r\n onBeaconExit: (params: BeaconRegionEvent) => void;\r\n onBeaconDistance: (params: BeaconDistanceEvent) => void;\r\n /** Fired once after a paired beacon has been continuously in range for its configured `timeoutSeconds`. */\r\n onBeaconTimeout: (params: BeaconTimeoutEvent) => void;\r\n /** Fired continuously during a live scan as each iBeacon is detected. */\r\n onBeaconFound: (params: BeaconScanResult) => void;\r\n /** Fired continuously during a live scan as each Eddystone beacon is detected. */\r\n onEddystoneFound: (params: EddystoneScanResult) => void;\r\n onEddystoneEnter: (params: EddystoneRegionEvent) => void;\r\n onEddystoneExit: (params: EddystoneRegionEvent) => void;\r\n onEddystoneDistance: (params: EddystoneDistanceEvent) => void;\r\n /** Fired once after a paired Eddystone has been continuously in range for its configured `timeoutSeconds`. */\r\n onEddystoneTimeout: (params: EddystoneTimeoutEvent) => void;\r\n /** Fired when a native monitoring or ranging failure occurs (logged to DB and forwarded to JS). */\r\n onBeaconError: (params: BeaconErrorEvent) => void;\r\n /** Fired when the device connects to a CarPlay (iOS) or Android Auto (Android) session. */\r\n onCarPlayConnected: (params: CarPlayConnectedEvent) => void;\r\n /** Fired when the device disconnects from a CarPlay (iOS) or Android Auto (Android) session. */\r\n onCarPlayDisconnected: (params: CarPlayDisconnectedEvent) => void;\r\n};\r\n\r\n/** Options for filtering event logs. */\r\nexport type EventLogQueryOptions = {\r\n /** Maximum number of log entries to return (default: 1000, max: 10000). */\r\n limit?: number;\r\n /** Filter by event type (e.g. \"onBeaconEnter\", \"onBeaconExit\"). */\r\n eventType?: string;\r\n /** Only return events with timestamp >= this value (ms since epoch). */\r\n sinceTimestamp?: number;\r\n};\r\n\r\n/** A single logged beacon event entry. */\r\nexport type EventLogEntry = {\r\n id: number;\r\n /** Timestamp in milliseconds since epoch. */\r\n timestamp: number;\r\n /** The event type that was logged (e.g. \"onBeaconEnter\"). */\r\n eventType: string;\r\n /** Beacon identifier, if available. */\r\n identifier?: string;\r\n /** The full event payload that was sent to JS. */\r\n data: Record<string, unknown>;\r\n};\r\n"]}
1
+ {"version":3,"file":"ExpoBeacon.types.js","sourceRoot":"","sources":["../src/ExpoBeacon.types.ts"],"names":[],"mappings":"","sourcesContent":["/** Raw beacon discovered during a scan. */\r\nexport type BeaconScanResult = {\r\n uuid: string; // iBeacon proximity UUID (uppercase, formatted)\r\n major: number; // iBeacon major value (0–65535)\r\n minor: number; // iBeacon minor value (0–65535)\r\n rssi: number; // Signal strength in dBm (negative number)\r\n distance: number; // Estimated distance in meters\r\n txPower: number; // Calibrated TX power\r\n /** BLE advertising device name. May be undefined on iOS (CoreLocation does not expose it for iBeacon). */\r\n name?: string;\r\n};\r\n\r\n/**\r\n * A beacon that has been paired/registered for monitoring.\r\n *\r\n * Note: Paired beacon data is stored unencrypted in UserDefaults (iOS) /\r\n * SharedPreferences (Android) and may be included in device backups.\r\n */\r\nexport type PairedBeacon = {\r\n identifier: string; // User-defined label (e.g. \"lobby-door\")\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n /** BLE advertising device name, if provided at pairing time. */\r\n name?: string;\r\n /**\r\n * Timeout in seconds. When set, the module fires `onBeaconTimeout` once\r\n * after the beacon has been continuously in range for this duration.\r\n * The timer resets if the beacon exits and re-enters range.\r\n *\r\n * The timeout countdown also starts if no BLE readings are received\r\n * for 60 seconds (e.g. due to Doze mode or background throttling).\r\n */\r\n timeoutSeconds?: number;\r\n};\r\n\r\n/** Payload for enter/exit region events. */\r\nexport type BeaconRegionEvent = {\r\n identifier: string; // Matches PairedBeacon.identifier\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n event: \"enter\" | \"exit\";\r\n /** Measured distance in metres at the time of the event (–1 if unavailable). */\r\n distance: number;\r\n /** Signal strength in dBm at the time of the event (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for periodic distance update events during monitoring. */\r\nexport type BeaconDistanceEvent = {\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n distance: number;\r\n /** Signal strength in dBm (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for beacon timeout events (beacon in range for configured duration). */\r\nexport type BeaconTimeoutEvent = {\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n /** Current distance in metres at the time the timeout fired. */\r\n distance: number;\r\n};\r\n\r\n/** Configuration for beacon enter/exit event notifications. */\r\nexport type BeaconNotificationConfig = {\r\n /** Whether to show enter/exit notifications. Default: true. */\r\n enabled?: boolean;\r\n /** Notification title on beacon enter. Default: \"Beacon Entered\". */\r\n enterTitle?: string;\r\n /** Notification title on beacon exit. Default: \"Beacon Exited\". */\r\n exitTitle?: string;\r\n /** Notification title on beacon timeout. Default: \"Beacon Timeout\". */\r\n timeoutTitle?: string;\r\n /**\r\n * Notification body template. Supports {identifier} and {event} placeholders.\r\n * Default: \"{identifier} region {event}ed\".\r\n */\r\n body?: string;\r\n /** Play a sound with the notification (iOS only). Default: true. */\r\n sound?: boolean;\r\n /** Android drawable resource name for the notification icon (e.g. \"ic_notification\"). */\r\n icon?: string;\r\n};\r\n\r\n/** Configuration for the Android foreground service notification (persistent status bar entry). */\r\nexport type ForegroundServiceConfig = {\r\n /** Title of the persistent notification. Default: \"Beacon Monitoring Active\". */\r\n title?: string;\r\n /** Body text of the persistent notification. Default: \"Monitoring for iBeacons in the background\". */\r\n text?: string;\r\n /** Android drawable resource name for the notification icon. */\r\n icon?: string;\r\n};\r\n\r\n/** Configuration for the Android notification channel. */\r\nexport type NotificationChannelConfig = {\r\n /** Channel display name shown in system settings. Default: \"Beacon Monitoring\". */\r\n name?: string;\r\n /** Channel description shown in system settings. Default: \"Used for background iBeacon region monitoring\". */\r\n description?: string;\r\n /**\r\n * Channel importance level. Default: 'low'.\r\n * Note: Android may ignore decreases in importance after first channel creation until the app is reinstalled.\r\n */\r\n importance?: \"low\" | \"default\" | \"high\";\r\n};\r\n\r\n/** Configuration for CarPlay / Android Auto connect/disconnect notifications. */\r\nexport type CarPlayNotificationConfig = {\r\n /** Whether to show CarPlay connect/disconnect notifications. Default: true. */\r\n enabled?: boolean;\r\n /** Notification title on CarPlay/Android Auto connect. Default: \"CarPlay Connected\". */\r\n connectedTitle?: string;\r\n /** Notification title on CarPlay/Android Auto disconnect. Default: \"CarPlay Disconnected\". */\r\n disconnectedTitle?: string;\r\n /**\r\n * Notification body template. Supports `{event}` (\"connected\"/\"disconnected\") and\r\n * `{transport}` (e.g. \"wired\", \"wireless\", \"projection\", \"native\", \"unknown\") placeholders.\r\n * Note: `{transport}` is only meaningful for connect events; on disconnect it is replaced with an empty string.\r\n * Default: \"CarPlay session {event}\".\r\n */\r\n body?: string;\r\n /** Play a sound with the notification (iOS only). Default: true. */\r\n sound?: boolean;\r\n /** Android drawable resource name for the notification icon (e.g. \"ic_notification\"). */\r\n icon?: string;\r\n};\r\n\r\n/** Configuration for the Android notification channel used for CarPlay events. */\r\nexport type CarPlayChannelConfig = {\r\n /** Channel display name shown in system settings. Default: \"CarPlay / Android Auto\". */\r\n name?: string;\r\n /** Channel description shown in system settings. Default: \"CarPlay and Android Auto connect/disconnect notifications\". */\r\n description?: string;\r\n /**\r\n * Channel importance level. Default: 'default' (so connect/disconnect events make a sound).\r\n * Note: Android may ignore decreases in importance after first channel creation until the app is reinstalled.\r\n */\r\n importance?: \"low\" | \"default\" | \"high\";\r\n};\r\n\r\n/** Combined notification configuration for all notification types. */\r\nexport type NotificationConfig = {\r\n /** Settings for beacon enter/exit event notifications. */\r\n beaconEvents?: BeaconNotificationConfig;\r\n /** Settings for CarPlay / Android Auto connect/disconnect notifications. */\r\n carPlayEvents?: CarPlayNotificationConfig;\r\n /** Settings for the persistent foreground service notification (Android only). */\r\n foregroundService?: ForegroundServiceConfig;\r\n /** Settings for the Android notification channel (Android only). */\r\n channel?: NotificationChannelConfig;\r\n /** Settings for the Android notification channel used for CarPlay events (Android only). */\r\n carPlayChannel?: CarPlayChannelConfig;\r\n};\r\n\r\n/** Snapshot of the current monitoring configuration and active state. */\r\nexport type MonitoringConfig = {\r\n /** Whether background monitoring is currently active. */\r\n isMonitoring: boolean;\r\n maxDistance?: number;\r\n exitDistance?: number;\r\n minRssi?: number;\r\n level?: 'all' | 'events';\r\n /** Seconds after last beacon sighting before an exit event fires. Default: 300. */\r\n exitTimeoutSeconds?: number;\r\n notifications?: NotificationConfig;\r\n};\r\n\r\n/** Current state snapshot for a paired monitored device. */\r\nexport type MonitoredDeviceState =\r\n | {\r\n kind: \"ibeacon\";\r\n identifier: string;\r\n uuid: string;\r\n major: number;\r\n minor: number;\r\n state: \"entered\" | \"exited\";\r\n /** Current distance in metres, or null when exited or no live reading is available. */\r\n distance: number | null;\r\n }\r\n | {\r\n kind: \"eddystone\";\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n state: \"entered\" | \"exited\";\r\n /** Current distance in metres, or null when exited or no live reading is available. */\r\n distance: number | null;\r\n };\r\n\r\n/** Options accepted by startMonitoring(). */\r\nexport type MonitoringOptions = {\r\n /**\r\n * Maximum distance in metres for distance-based enter events.\r\n * Exit events are always emitted when the region is lost.\r\n */\r\n maxDistance?: number;\r\n /**\r\n * Distance in metres at which exit events fire (must be ≥ maxDistance).\r\n * Creates a hysteresis band between enter and exit thresholds to prevent\r\n * rapid toggling near the boundary.\r\n *\r\n * Default when omitted: `maxDistance + min(maxDistance × 0.5, 2.5)`.\r\n * Only used when `maxDistance` is set.\r\n */\r\n exitDistance?: number;\r\n /**\r\n * Minimum RSSI (dBm) for a beacon reading to be considered valid.\r\n * Readings below this threshold are discarded as unreliable, preventing\r\n * false detections from reflected or distant signals.\r\n *\r\n * Default: -85. Typical range: -100 (very permissive) to -70 (strict).\r\n */\r\n minRssi?: number;\r\n /**\r\n * Controls which event types are emitted, logged, and forwarded to the API.\r\n *\r\n * - `'all'` (default): distance + enter + exit + timeout events.\r\n * - `'events'`: enter + exit + timeout only (no distance events).\r\n */\r\n level?: 'all' | 'events';\r\n /**\r\n * Seconds after last beacon sighting before an exit event fires when the beacon\r\n * disappears without moving outside the exit distance threshold.\r\n *\r\n * Default: 300 (5 minutes). Minimum: 1.\r\n */\r\n exitTimeoutSeconds?: number;\r\n /** Notification configuration overrides to apply for this monitoring session. */\r\n notifications?: NotificationConfig;\r\n};\r\n\r\n/** Eddystone frame type. */\r\nexport type EddystoneFrameType = \"uid\" | \"url\";\r\n\r\n/** Raw Eddystone beacon discovered during a scan. */\r\nexport type EddystoneScanResult = {\r\n frameType: EddystoneFrameType;\r\n /** 10-byte namespace ID as hex string (20 chars). Present for UID frames. */\r\n namespace?: string;\r\n /** 6-byte instance ID as hex string (12 chars). Present for UID frames. */\r\n instance?: string;\r\n /** Decoded URL. Present for URL frames. */\r\n url?: string;\r\n rssi: number;\r\n distance: number;\r\n txPower: number;\r\n /** BLE advertising device name. */\r\n name?: string;\r\n};\r\n\r\n/**\r\n * An Eddystone-UID beacon that has been paired/registered for monitoring.\r\n *\r\n * Note: Paired beacon data is stored unencrypted in UserDefaults (iOS) /\r\n * SharedPreferences (Android) and may be included in device backups.\r\n */\r\nexport type PairedEddystone = {\r\n identifier: string;\r\n /** 10-byte namespace ID as hex string (20 chars). */\r\n namespace: string;\r\n /** 6-byte instance ID as hex string (12 chars). */\r\n instance: string;\r\n /** BLE advertising device name, if provided at pairing time. */\r\n name?: string;\r\n /**\r\n * Timeout in seconds. When set, the module fires `onEddystoneTimeout` once\r\n * after the beacon has been continuously in range for this duration.\r\n * The timer resets if the beacon exits and re-enters range.\r\n *\r\n * The timeout countdown also starts if no BLE readings are received\r\n * for 60 seconds (e.g. due to Doze mode or background throttling).\r\n */\r\n timeoutSeconds?: number;\r\n};\r\n\r\n/** Payload for Eddystone enter/exit region events. */\r\nexport type EddystoneRegionEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n event: \"enter\" | \"exit\";\r\n /** Measured distance in metres at the time of the event (–1 if unavailable). */\r\n distance: number;\r\n /** Signal strength in dBm at the time of the event (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for periodic Eddystone distance update events during monitoring. */\r\nexport type EddystoneDistanceEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n distance: number;\r\n /** Signal strength in dBm (0 if unavailable). */\r\n rssi?: number;\r\n};\r\n\r\n/** Payload for Eddystone timeout events (beacon in range for configured duration). */\r\nexport type EddystoneTimeoutEvent = {\r\n identifier: string;\r\n namespace: string;\r\n instance: string;\r\n /** Current distance in metres at the time the timeout fired. */\r\n distance: number;\r\n};\r\n\r\n/** Transport reported with CarPlay / Android Auto connection events. */\r\nexport type CarPlayTransport =\r\n | \"wired\" // iOS CarPlay over USB / Lightning\r\n | \"wireless\" // iOS CarPlay over Bluetooth + Wi-Fi\r\n | \"projection\" // Android Auto projection (phone projecting to head unit)\r\n | \"native\" // Android Automotive OS (running on the head unit)\r\n | \"unknown\";\r\n\r\n/** Payload fired when the device connects to a CarPlay or Android Auto session. */\r\nexport type CarPlayConnectedEvent = {\r\n transport: CarPlayTransport;\r\n /** Timestamp in milliseconds since epoch. */\r\n timestamp: number;\r\n /** ISO 8601 UTC representation of {@link timestamp} (e.g. \"2026-05-12T14:23:45.678Z\"). */\r\n timestampIso?: string;\r\n};\r\n\r\n/** Payload fired when the device disconnects from a CarPlay or Android Auto session. */\r\nexport type CarPlayDisconnectedEvent = {\r\n /** Timestamp in milliseconds since epoch. */\r\n timestamp: number;\r\n /** ISO 8601 UTC representation of {@link timestamp} (e.g. \"2026-05-12T14:23:45.678Z\"). */\r\n timestampIso?: string;\r\n /**\r\n * Reason this disconnect was emitted. Absent for normal real-time disconnects.\r\n * `\"reconciled\"` indicates the disconnect was synthesized after the module was\r\n * recreated in a new process and detected that the previously persisted CarPlay\r\n * state no longer matches the current connection — i.e. the disconnect happened\r\n * off-process (force-quit, OS reclaim, abrupt cable yank) and is being delivered\r\n * post-hoc. Emitted on both iOS and Android.\r\n */\r\n reason?: \"reconciled\";\r\n};\r\n\r\n/**\r\n * Snapshot of the current CarPlay / Android Auto connection state, returned by\r\n * {@link ExpoBeaconModule.getCarPlayConnectionStatus}.\r\n */\r\nexport type CarPlayConnectionStatus = {\r\n /** `true` if a CarPlay or Android Auto session is currently active. */\r\n connected: boolean;\r\n /**\r\n * Connection transport type. Present only when `connected` is `true`.\r\n * See {@link CarPlayTransport} for possible values.\r\n */\r\n transport?: CarPlayTransport;\r\n /** Unix-millisecond timestamp of last connect. Present only when `connected` is `true`. */\r\n timestamp?: number;\r\n /** ISO 8601 UTC timestamp of last connect. Present only when `connected` is `true`. */\r\n timestampIso?: string;\r\n};\r\n\r\n/**\r\n * Diagnostic snapshot for troubleshooting CarPlay / Android Auto detection.\r\n * Returned by {@link ExpoBeaconModule.getCarPlayDiagnostics}.\r\n *\r\n * The most common failure mode on Android is that the host app is not\r\n * registered as an Android Auto-aware app (missing\r\n * `com.google.android.gms.car.application` meta-data + `automotive_app_desc.xml`\r\n * resource). When that happens, Gearhead silently reports\r\n * `CONNECTION_TYPE_NOT_CONNECTED` to the app regardless of `<queries>`\r\n * declarations, so `onCarPlayConnected` events never fire.\r\n *\r\n * Inspect this object after calling `startCarPlayMonitoring()` and confirming\r\n * Android Auto is connected on the head unit. If `isCarAppMetadataPresent` or\r\n * `isCarProviderQueryable` is `false`, the consumer app needs to enable the\r\n * config plugin's `android.androidAuto.register` option (default in recent\r\n * versions) and re-run `expo prebuild`.\r\n *\r\n * On iOS the diagnostic is a best-effort stub — most fields are not applicable\r\n * because CarPlay detection uses `AVAudioSession` rather than a content\r\n * provider.\r\n */\r\nexport type CarPlayDiagnostics = {\r\n /**\r\n * Android: `true` if the host app's manifest declares the\r\n * `com.google.android.gms.car.application` meta-data tag (required for\r\n * Gearhead to expose connection state to the app). iOS: always `true`.\r\n */\r\n isCarAppMetadataPresent: boolean;\r\n /**\r\n * Android: `true` if the system can resolve at least one provider for the\r\n * `androidx.car.app.connection.action.CAR_PROVIDER` intent (requires the\r\n * `<queries>` declaration shipped by this library AND a compatible Gearhead\r\n * / AAOS install on the device). iOS: always `true`.\r\n */\r\n isCarProviderQueryable: boolean;\r\n /**\r\n * Android: most recent raw value read from `CarConnection.getType()`.\r\n * `0` = `NOT_CONNECTED`, `1` = `NATIVE` (AAOS), `2` = `PROJECTION`.\r\n * `null` if the observer has not yet received any value (or is not running).\r\n * iOS: `null`.\r\n */\r\n lastRawConnectionType: number | null;\r\n /**\r\n * `true` if the underlying connection observer is currently active.\r\n * On Android, equivalent to \"the foreground service is running AND\r\n * `CarPlayMonitor.start()` succeeded\". On iOS, the audio-session observer\r\n * is registered.\r\n */\r\n observerActive: boolean;\r\n /**\r\n * Android: `true` if the foreground service hosting the observer is alive.\r\n * iOS: always `true` (no background service involved).\r\n */\r\n serviceAlive: boolean;\r\n};\r\n\r\n/** Payload for native beacon error events (monitoring/ranging failures). */\r\nexport type BeaconErrorEvent = {\r\n /** Region or constraint identifier, empty string if unavailable. */\r\n identifier: string;\r\n /** Machine-readable error code (e.g. \"MONITORING_FAILED\", \"RANGING_FAILED\", \"SECURITY_EXCEPTION\"). */\r\n code: string;\r\n /** Human-readable error message from the native layer. */\r\n message: string;\r\n};\r\n\r\n/** Module event map. */\r\nexport type ExpoBeaconModuleEvents = {\r\n onBeaconEnter: (params: BeaconRegionEvent) => void;\r\n onBeaconExit: (params: BeaconRegionEvent) => void;\r\n onBeaconDistance: (params: BeaconDistanceEvent) => void;\r\n /** Fired once after a paired beacon has been continuously in range for its configured `timeoutSeconds`. */\r\n onBeaconTimeout: (params: BeaconTimeoutEvent) => void;\r\n /** Fired continuously during a live scan as each iBeacon is detected. */\r\n onBeaconFound: (params: BeaconScanResult) => void;\r\n /** Fired continuously during a live scan as each Eddystone beacon is detected. */\r\n onEddystoneFound: (params: EddystoneScanResult) => void;\r\n onEddystoneEnter: (params: EddystoneRegionEvent) => void;\r\n onEddystoneExit: (params: EddystoneRegionEvent) => void;\r\n onEddystoneDistance: (params: EddystoneDistanceEvent) => void;\r\n /** Fired once after a paired Eddystone has been continuously in range for its configured `timeoutSeconds`. */\r\n onEddystoneTimeout: (params: EddystoneTimeoutEvent) => void;\r\n /** Fired when a native monitoring or ranging failure occurs (logged to DB and forwarded to JS). */\r\n onBeaconError: (params: BeaconErrorEvent) => void;\r\n /** Fired when the device connects to a CarPlay (iOS) or Android Auto (Android) session. */\r\n onCarPlayConnected: (params: CarPlayConnectedEvent) => void;\r\n /** Fired when the device disconnects from a CarPlay (iOS) or Android Auto (Android) session. */\r\n onCarPlayDisconnected: (params: CarPlayDisconnectedEvent) => void;\r\n};\r\n\r\n/** Options for filtering event logs. */\r\nexport type EventLogQueryOptions = {\r\n /** Maximum number of log entries to return (default: 1000, max: 10000). */\r\n limit?: number;\r\n /** Filter by event type (e.g. \"onBeaconEnter\", \"onBeaconExit\"). */\r\n eventType?: string;\r\n /** Only return events with timestamp >= this value (ms since epoch). */\r\n sinceTimestamp?: number;\r\n};\r\n\r\n/** A single logged beacon event entry. */\r\nexport type EventLogEntry = {\r\n id: number;\r\n /** Timestamp in milliseconds since epoch. */\r\n timestamp: number;\r\n /** The event type that was logged (e.g. \"onBeaconEnter\"). */\r\n eventType: string;\r\n /** Beacon identifier, if available. */\r\n identifier?: string;\r\n /** The full event payload that was sent to JS. */\r\n data: Record<string, unknown>;\r\n};\r\n"]}
@@ -1,5 +1,5 @@
1
1
  import { NativeModule } from "expo";
2
- import { ExpoBeaconModuleEvents, BeaconScanResult, EddystoneScanResult, PairedBeacon, PairedEddystone, NotificationConfig, MonitoringOptions, MonitoringConfig, MonitoredDeviceState, EventLogQueryOptions, EventLogEntry, CarPlayConnectionStatus } from "./ExpoBeacon.types";
2
+ import { ExpoBeaconModuleEvents, BeaconScanResult, EddystoneScanResult, PairedBeacon, PairedEddystone, NotificationConfig, MonitoringOptions, MonitoringConfig, MonitoredDeviceState, EventLogQueryOptions, EventLogEntry, CarPlayConnectionStatus, CarPlayDiagnostics } from "./ExpoBeacon.types";
3
3
  declare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {
4
4
  /**
5
5
  * Start a one-shot iBeacon scan. Resolves with discovered beacons after scanDuration ms.
@@ -196,6 +196,16 @@ declare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {
196
196
  * back to the persisted last-known state otherwise.
197
197
  */
198
198
  getCarPlayConnectionStatus(): CarPlayConnectionStatus;
199
+ /**
200
+ * Returns diagnostic information about the CarPlay / Android Auto detection
201
+ * pipeline. Use this when `onCarPlayConnected` never fires despite the head
202
+ * unit being connected — it reveals whether the host app is correctly
203
+ * registered with Gearhead, whether the connection content provider is
204
+ * reachable, and the most recent raw value the observer received.
205
+ *
206
+ * See {@link CarPlayDiagnostics} for field-level guidance.
207
+ */
208
+ getCarPlayDiagnostics(): CarPlayDiagnostics;
199
209
  }
200
210
  declare const _default: ExpoBeaconModule;
201
211
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoBeaconModule.d.ts","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ExpoBeaconModule.d.ts","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoBeaconModule.js","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAoQzD,eAAe,mBAAmB,CAAmB,YAAY,CAAC,CAAC","sourcesContent":["import { NativeModule, requireNativeModule } from \"expo\";\r\n\r\nimport {\r\n ExpoBeaconModuleEvents,\r\n BeaconScanResult,\r\n EddystoneScanResult,\r\n PairedBeacon,\r\n PairedEddystone,\r\n NotificationConfig,\r\n MonitoringOptions,\r\n MonitoringConfig,\r\n MonitoredDeviceState,\r\n EventLogQueryOptions,\r\n EventLogEntry,\r\n CarPlayConnectionStatus,\r\n} from \"./ExpoBeacon.types\";\r\n\r\ndeclare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {\r\n /**\r\n * Start a one-shot iBeacon scan. Resolves with discovered beacons after scanDuration ms.\r\n *\r\n * Pass one or more UUIDs to scan for specific beacons (uses CoreLocation on iOS).\r\n * On iOS, at least one UUID is required — Apple strips iBeacon data from BLE\r\n * advertisements, making wildcard discovery impossible. When you pass an empty\r\n * array, the module automatically uses UUIDs from paired beacons.\r\n * On Android, pass an empty array to discover all nearby iBeacons.\r\n *\r\n * @param uuids Proximity UUIDs to filter by. Empty/omitted = use paired UUIDs (iOS) or wildcard (Android).\r\n * @param scanDuration Duration in ms (default 5000)\r\n */\r\n scanForBeaconsAsync(\r\n uuids?: string[],\r\n scanDuration?: number,\r\n ): Promise<BeaconScanResult[]>;\r\n\r\n /**\r\n * Start a one-shot Eddystone beacon scan using BLE.\r\n * Discovers Eddystone-UID and Eddystone-URL frames.\r\n *\r\n * @param scanDuration Duration in ms (default 5000)\r\n */\r\n scanForEddystonesAsync(\r\n scanDuration?: number,\r\n ): Promise<EddystoneScanResult[]>;\r\n\r\n /**\r\n * Register a beacon for persistent region monitoring.\r\n */\r\n pairBeacon(\r\n identifier: string,\r\n uuid: string,\r\n major: number,\r\n minor: number,\r\n name?: string,\r\n timeoutSeconds?: number,\r\n ): void;\r\n\r\n /**\r\n * Remove a previously paired beacon.\r\n */\r\n unpairBeacon(identifier: string): void;\r\n\r\n /**\r\n * Return all currently paired beacons.\r\n */\r\n getPairedBeacons(): PairedBeacon[];\r\n\r\n /**\r\n * Register an Eddystone-UID beacon for persistent monitoring.\r\n */\r\n pairEddystone(\r\n identifier: string,\r\n namespace: string,\r\n instance: string,\r\n name?: string,\r\n timeoutSeconds?: number,\r\n ): void;\r\n\r\n /**\r\n * Remove a previously paired Eddystone beacon.\r\n */\r\n unpairEddystone(identifier: string): void;\r\n\r\n /**\r\n * Return all currently paired Eddystone beacons.\r\n */\r\n getPairedEddystones(): PairedEddystone[];\r\n\r\n /**\r\n * Set persistent notification configuration. Settings are saved and applied to all\r\n * subsequent monitoring sessions until explicitly changed.\r\n */\r\n setNotificationConfig(config: NotificationConfig): void;\r\n\r\n /**\r\n * Start background region monitoring for all paired beacons.\r\n * On Android starts a foreground service.\r\n * On iOS starts CLLocationManager region monitoring.\r\n *\r\n * Accepts a plain number (backward-compatible maxDistance shorthand) or a\r\n * MonitoringOptions object with maxDistance and/or notification overrides.\r\n */\r\n startMonitoring(options?: MonitoringOptions | number): Promise<void>;\r\n\r\n /**\r\n * Stop background region monitoring.\r\n */\r\n stopMonitoring(): Promise<void>;\r\n\r\n /**\r\n * Start a continuous BLE scan. Fires `onBeaconFound` events as beacons are detected.\r\n * Call stopContinuousScan() to end the scan.\r\n */\r\n startContinuousScan(): void;\r\n\r\n /** Stop the continuous scan started by startContinuousScan(). */\r\n stopContinuousScan(): void;\r\n\r\n /**\r\n * Cancel any in-progress one-shot scan (iBeacon or Eddystone).\r\n * The pending promise will be rejected with code \"SCAN_CANCELLED\".\r\n */\r\n cancelScan(): void;\r\n\r\n /** Request Bluetooth + Location permissions. Returns true if granted. */\r\n requestPermissionsAsync(): Promise<boolean>;\r\n\r\n /**\r\n * Check whether the app is exempt from Android battery optimizations.\r\n * Always returns true on iOS and web (no equivalent concept).\r\n */\r\n isBatteryOptimizationExempt(): boolean;\r\n\r\n /**\r\n * Request exemption from Android battery optimizations.\r\n * Opens the system dialog asking the user to whitelist this app.\r\n * Returns true if the dialog was shown (or already exempt), false on failure.\r\n * Always resolves true on iOS and web.\r\n */\r\n requestBatteryOptimizationExemption(): Promise<boolean>;\r\n\r\n /** Enable SQLite event logging. All beacon events will be persisted to a local database. */\r\n enableEventLogging(): void;\r\n\r\n /** Disable event logging. Previously logged events are retained. */\r\n disableEventLogging(): void;\r\n\r\n /**\r\n * Returns whether SQLite event logging is currently enabled.\r\n * Reads the persisted flag, so this stays accurate across app cold-starts.\r\n */\r\n isEventLoggingEnabled(): boolean;\r\n\r\n /**\r\n * Retrieve logged beacon events from the SQLite database.\r\n * @param options Optional filters (limit, eventType, sinceTimestamp).\r\n */\r\n getEventLogs(options?: EventLogQueryOptions): EventLogEntry[];\r\n\r\n /** Delete all logged events from the database. */\r\n clearEventLogs(): void;\r\n\r\n /** Delete the entire event log database. Also disables logging. */\r\n destroyEventLogs(): void;\r\n\r\n /**\r\n * Configure a remote API endpoint for native event forwarding.\r\n * Once set, beacon events are POSTed directly from native code,\r\n * ensuring delivery even when the JS bridge is not active (app backgrounded).\r\n *\r\n * @param url The API endpoint URL to POST events to.\r\n * @param apiKey Optional API key sent as X-CSFR-Token header.\r\n * @param id Optional identifier appended to every forwarded event payload.\r\n */\r\n setApiEndpoint(url: string, apiKey?: string, id?: string): void;\r\n\r\n /**\r\n * Return the current monitoring configuration and active state.\r\n * Option fields are undefined if not explicitly set.\r\n */\r\n getMonitoringConfig(): MonitoringConfig;\r\n\r\n /**\r\n * Return the current state snapshot for a paired monitored device.\r\n * Returns null when no paired device matches the identifier.\r\n */\r\n getMonitoredDeviceState(identifier: string): MonitoredDeviceState | null;\r\n\r\n /**\r\n * Return the current state snapshot for all paired monitored devices.\r\n */\r\n getMonitoredDeviceStates(): MonitoredDeviceState[];\r\n\r\n /**\r\n * Return the current API forwarding configuration.\r\n * Each field is `null` if not set.\r\n */\r\n getApiEndpoint(): { url: string | null; apiKey: string | null; id: string | null };\r\n\r\n /**\r\n * Start observing CarPlay (iOS) / Android Auto (Android) connection state.\r\n *\r\n * Emits `onCarPlayConnected` and `onCarPlayDisconnected` JS events. Events are\r\n * also written to the SQLite event log and forwarded to the configured API\r\n * endpoint, and dispatched to native lifecycle plugins (used by the auto-\r\n * generated geolocation plugin to start/stop background-geolocation).\r\n *\r\n * **Persistent.** The enabled state is stored in native preferences and\r\n * survives app kill / device reboot. Call `stopCarPlayMonitoring()` to\r\n * disable. `startMonitoring()` also enables CarPlay observation\r\n * automatically — calling this method explicitly is only required if you\r\n * want CarPlay events without beacon monitoring.\r\n *\r\n * **Background behavior:**\r\n * - **Android**: the foreground service hosts the observer and continues to\r\n * receive `CarConnection` events even after the app process is killed and\r\n * restarted via `BootReceiver`. Guaranteed background detection.\r\n * - **iOS**: the observer auto-restarts in `OnCreate` whenever the module\r\n * is recreated, including background-launches triggered by beacon region\r\n * monitoring. **iOS cannot wake a terminated app on CarPlay alone** — for\r\n * guaranteed wake-from-suspension, also call `startMonitoring()` with at\r\n * least one paired beacon. Region wake events trigger a CarPlay state\r\n * resync to reconcile any route changes that occurred during suspension.\r\n *\r\n * - iOS: observes `AVAudioSession.routeChangeNotification` for `.carAudio` ports.\r\n * No CarPlay entitlement required.\r\n * - Android: observes `androidx.car.app.connection.CarConnection` LiveData.\r\n * No Android Auto certification required.\r\n * - Web: no-op (resolves immediately).\r\n */\r\n startCarPlayMonitoring(): Promise<void>;\r\n\r\n /**\r\n * Stop CarPlay / Android Auto connection monitoring and clear the persisted\r\n * \"enabled\" flag so the observer is not auto-restarted on next launch / boot.\r\n *\r\n * On Android, if no beacon monitoring is active, the foreground service\r\n * stops itself.\r\n */\r\n stopCarPlayMonitoring(): Promise<void>;\r\n\r\n /**\r\n * Returns whether CarPlay / Android Auto observation is currently enabled.\r\n * Reads the persisted flag, so the value survives app cold-starts and\r\n * reflects the native source of truth (foreground service on Android,\r\n * UserDefaults suite on iOS).\r\n */\r\n isCarPlayMonitoringEnabled(): boolean;\r\n\r\n /**\r\n * Returns a snapshot of the current CarPlay / Android Auto connection state\r\n * without waiting for an event. Useful on mount to immediately reflect\r\n * whether a car session is already active.\r\n *\r\n * Reads from the live observer if the foreground service is running, or falls\r\n * back to the persisted last-known state otherwise.\r\n */\r\n getCarPlayConnectionStatus(): CarPlayConnectionStatus;\r\n}\r\n\r\nexport default requireNativeModule<ExpoBeaconModule>(\"ExpoBeacon\");\r\n"]}
1
+ {"version":3,"file":"ExpoBeaconModule.js","sourceRoot":"","sources":["../src/ExpoBeaconModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAgRzD,eAAe,mBAAmB,CAAmB,YAAY,CAAC,CAAC","sourcesContent":["import { NativeModule, requireNativeModule } from \"expo\";\r\n\r\nimport {\r\n ExpoBeaconModuleEvents,\r\n BeaconScanResult,\r\n EddystoneScanResult,\r\n PairedBeacon,\r\n PairedEddystone,\r\n NotificationConfig,\r\n MonitoringOptions,\r\n MonitoringConfig,\r\n MonitoredDeviceState,\r\n EventLogQueryOptions,\r\n EventLogEntry,\r\n CarPlayConnectionStatus,\r\n CarPlayDiagnostics,\r\n} from \"./ExpoBeacon.types\";\r\n\r\ndeclare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {\r\n /**\r\n * Start a one-shot iBeacon scan. Resolves with discovered beacons after scanDuration ms.\r\n *\r\n * Pass one or more UUIDs to scan for specific beacons (uses CoreLocation on iOS).\r\n * On iOS, at least one UUID is required — Apple strips iBeacon data from BLE\r\n * advertisements, making wildcard discovery impossible. When you pass an empty\r\n * array, the module automatically uses UUIDs from paired beacons.\r\n * On Android, pass an empty array to discover all nearby iBeacons.\r\n *\r\n * @param uuids Proximity UUIDs to filter by. Empty/omitted = use paired UUIDs (iOS) or wildcard (Android).\r\n * @param scanDuration Duration in ms (default 5000)\r\n */\r\n scanForBeaconsAsync(\r\n uuids?: string[],\r\n scanDuration?: number,\r\n ): Promise<BeaconScanResult[]>;\r\n\r\n /**\r\n * Start a one-shot Eddystone beacon scan using BLE.\r\n * Discovers Eddystone-UID and Eddystone-URL frames.\r\n *\r\n * @param scanDuration Duration in ms (default 5000)\r\n */\r\n scanForEddystonesAsync(\r\n scanDuration?: number,\r\n ): Promise<EddystoneScanResult[]>;\r\n\r\n /**\r\n * Register a beacon for persistent region monitoring.\r\n */\r\n pairBeacon(\r\n identifier: string,\r\n uuid: string,\r\n major: number,\r\n minor: number,\r\n name?: string,\r\n timeoutSeconds?: number,\r\n ): void;\r\n\r\n /**\r\n * Remove a previously paired beacon.\r\n */\r\n unpairBeacon(identifier: string): void;\r\n\r\n /**\r\n * Return all currently paired beacons.\r\n */\r\n getPairedBeacons(): PairedBeacon[];\r\n\r\n /**\r\n * Register an Eddystone-UID beacon for persistent monitoring.\r\n */\r\n pairEddystone(\r\n identifier: string,\r\n namespace: string,\r\n instance: string,\r\n name?: string,\r\n timeoutSeconds?: number,\r\n ): void;\r\n\r\n /**\r\n * Remove a previously paired Eddystone beacon.\r\n */\r\n unpairEddystone(identifier: string): void;\r\n\r\n /**\r\n * Return all currently paired Eddystone beacons.\r\n */\r\n getPairedEddystones(): PairedEddystone[];\r\n\r\n /**\r\n * Set persistent notification configuration. Settings are saved and applied to all\r\n * subsequent monitoring sessions until explicitly changed.\r\n */\r\n setNotificationConfig(config: NotificationConfig): void;\r\n\r\n /**\r\n * Start background region monitoring for all paired beacons.\r\n * On Android starts a foreground service.\r\n * On iOS starts CLLocationManager region monitoring.\r\n *\r\n * Accepts a plain number (backward-compatible maxDistance shorthand) or a\r\n * MonitoringOptions object with maxDistance and/or notification overrides.\r\n */\r\n startMonitoring(options?: MonitoringOptions | number): Promise<void>;\r\n\r\n /**\r\n * Stop background region monitoring.\r\n */\r\n stopMonitoring(): Promise<void>;\r\n\r\n /**\r\n * Start a continuous BLE scan. Fires `onBeaconFound` events as beacons are detected.\r\n * Call stopContinuousScan() to end the scan.\r\n */\r\n startContinuousScan(): void;\r\n\r\n /** Stop the continuous scan started by startContinuousScan(). */\r\n stopContinuousScan(): void;\r\n\r\n /**\r\n * Cancel any in-progress one-shot scan (iBeacon or Eddystone).\r\n * The pending promise will be rejected with code \"SCAN_CANCELLED\".\r\n */\r\n cancelScan(): void;\r\n\r\n /** Request Bluetooth + Location permissions. Returns true if granted. */\r\n requestPermissionsAsync(): Promise<boolean>;\r\n\r\n /**\r\n * Check whether the app is exempt from Android battery optimizations.\r\n * Always returns true on iOS and web (no equivalent concept).\r\n */\r\n isBatteryOptimizationExempt(): boolean;\r\n\r\n /**\r\n * Request exemption from Android battery optimizations.\r\n * Opens the system dialog asking the user to whitelist this app.\r\n * Returns true if the dialog was shown (or already exempt), false on failure.\r\n * Always resolves true on iOS and web.\r\n */\r\n requestBatteryOptimizationExemption(): Promise<boolean>;\r\n\r\n /** Enable SQLite event logging. All beacon events will be persisted to a local database. */\r\n enableEventLogging(): void;\r\n\r\n /** Disable event logging. Previously logged events are retained. */\r\n disableEventLogging(): void;\r\n\r\n /**\r\n * Returns whether SQLite event logging is currently enabled.\r\n * Reads the persisted flag, so this stays accurate across app cold-starts.\r\n */\r\n isEventLoggingEnabled(): boolean;\r\n\r\n /**\r\n * Retrieve logged beacon events from the SQLite database.\r\n * @param options Optional filters (limit, eventType, sinceTimestamp).\r\n */\r\n getEventLogs(options?: EventLogQueryOptions): EventLogEntry[];\r\n\r\n /** Delete all logged events from the database. */\r\n clearEventLogs(): void;\r\n\r\n /** Delete the entire event log database. Also disables logging. */\r\n destroyEventLogs(): void;\r\n\r\n /**\r\n * Configure a remote API endpoint for native event forwarding.\r\n * Once set, beacon events are POSTed directly from native code,\r\n * ensuring delivery even when the JS bridge is not active (app backgrounded).\r\n *\r\n * @param url The API endpoint URL to POST events to.\r\n * @param apiKey Optional API key sent as X-CSFR-Token header.\r\n * @param id Optional identifier appended to every forwarded event payload.\r\n */\r\n setApiEndpoint(url: string, apiKey?: string, id?: string): void;\r\n\r\n /**\r\n * Return the current monitoring configuration and active state.\r\n * Option fields are undefined if not explicitly set.\r\n */\r\n getMonitoringConfig(): MonitoringConfig;\r\n\r\n /**\r\n * Return the current state snapshot for a paired monitored device.\r\n * Returns null when no paired device matches the identifier.\r\n */\r\n getMonitoredDeviceState(identifier: string): MonitoredDeviceState | null;\r\n\r\n /**\r\n * Return the current state snapshot for all paired monitored devices.\r\n */\r\n getMonitoredDeviceStates(): MonitoredDeviceState[];\r\n\r\n /**\r\n * Return the current API forwarding configuration.\r\n * Each field is `null` if not set.\r\n */\r\n getApiEndpoint(): { url: string | null; apiKey: string | null; id: string | null };\r\n\r\n /**\r\n * Start observing CarPlay (iOS) / Android Auto (Android) connection state.\r\n *\r\n * Emits `onCarPlayConnected` and `onCarPlayDisconnected` JS events. Events are\r\n * also written to the SQLite event log and forwarded to the configured API\r\n * endpoint, and dispatched to native lifecycle plugins (used by the auto-\r\n * generated geolocation plugin to start/stop background-geolocation).\r\n *\r\n * **Persistent.** The enabled state is stored in native preferences and\r\n * survives app kill / device reboot. Call `stopCarPlayMonitoring()` to\r\n * disable. `startMonitoring()` also enables CarPlay observation\r\n * automatically — calling this method explicitly is only required if you\r\n * want CarPlay events without beacon monitoring.\r\n *\r\n * **Background behavior:**\r\n * - **Android**: the foreground service hosts the observer and continues to\r\n * receive `CarConnection` events even after the app process is killed and\r\n * restarted via `BootReceiver`. Guaranteed background detection.\r\n * - **iOS**: the observer auto-restarts in `OnCreate` whenever the module\r\n * is recreated, including background-launches triggered by beacon region\r\n * monitoring. **iOS cannot wake a terminated app on CarPlay alone** — for\r\n * guaranteed wake-from-suspension, also call `startMonitoring()` with at\r\n * least one paired beacon. Region wake events trigger a CarPlay state\r\n * resync to reconcile any route changes that occurred during suspension.\r\n *\r\n * - iOS: observes `AVAudioSession.routeChangeNotification` for `.carAudio` ports.\r\n * No CarPlay entitlement required.\r\n * - Android: observes `androidx.car.app.connection.CarConnection` LiveData.\r\n * No Android Auto certification required.\r\n * - Web: no-op (resolves immediately).\r\n */\r\n startCarPlayMonitoring(): Promise<void>;\r\n\r\n /**\r\n * Stop CarPlay / Android Auto connection monitoring and clear the persisted\r\n * \"enabled\" flag so the observer is not auto-restarted on next launch / boot.\r\n *\r\n * On Android, if no beacon monitoring is active, the foreground service\r\n * stops itself.\r\n */\r\n stopCarPlayMonitoring(): Promise<void>;\r\n\r\n /**\r\n * Returns whether CarPlay / Android Auto observation is currently enabled.\r\n * Reads the persisted flag, so the value survives app cold-starts and\r\n * reflects the native source of truth (foreground service on Android,\r\n * UserDefaults suite on iOS).\r\n */\r\n isCarPlayMonitoringEnabled(): boolean;\r\n\r\n /**\r\n * Returns a snapshot of the current CarPlay / Android Auto connection state\r\n * without waiting for an event. Useful on mount to immediately reflect\r\n * whether a car session is already active.\r\n *\r\n * Reads from the live observer if the foreground service is running, or falls\r\n * back to the persisted last-known state otherwise.\r\n */\r\n getCarPlayConnectionStatus(): CarPlayConnectionStatus;\r\n\r\n /**\r\n * Returns diagnostic information about the CarPlay / Android Auto detection\r\n * pipeline. Use this when `onCarPlayConnected` never fires despite the head\r\n * unit being connected — it reveals whether the host app is correctly\r\n * registered with Gearhead, whether the connection content provider is\r\n * reachable, and the most recent raw value the observer received.\r\n *\r\n * See {@link CarPlayDiagnostics} for field-level guidance.\r\n */\r\n getCarPlayDiagnostics(): CarPlayDiagnostics;\r\n}\r\n\r\nexport default requireNativeModule<ExpoBeaconModule>(\"ExpoBeacon\");\r\n"]}
package/build/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { default } from "./ExpoBeaconModule.js";
2
- export type { BeaconScanResult, PairedBeacon, BeaconRegionEvent, BeaconDistanceEvent, BeaconTimeoutEvent, ExpoBeaconModuleEvents, NotificationConfig, MonitoringOptions, MonitoringConfig, MonitoredDeviceState, BeaconNotificationConfig, CarPlayNotificationConfig, CarPlayChannelConfig, ForegroundServiceConfig, NotificationChannelConfig, EddystoneFrameType, EddystoneScanResult, PairedEddystone, EddystoneRegionEvent, EddystoneDistanceEvent, EddystoneTimeoutEvent, EventLogQueryOptions, EventLogEntry, CarPlayTransport, CarPlayConnectedEvent, CarPlayDisconnectedEvent, CarPlayConnectionStatus, } from "./ExpoBeacon.types";
2
+ export type { BeaconScanResult, PairedBeacon, BeaconRegionEvent, BeaconDistanceEvent, BeaconTimeoutEvent, ExpoBeaconModuleEvents, NotificationConfig, MonitoringOptions, MonitoringConfig, MonitoredDeviceState, BeaconNotificationConfig, CarPlayNotificationConfig, CarPlayChannelConfig, ForegroundServiceConfig, NotificationChannelConfig, EddystoneFrameType, EddystoneScanResult, PairedEddystone, EddystoneRegionEvent, EddystoneDistanceEvent, EddystoneTimeoutEvent, EventLogQueryOptions, EventLogEntry, CarPlayTransport, CarPlayConnectedEvent, CarPlayDisconnectedEvent, CarPlayConnectionStatus, CarPlayDiagnostics, } from "./ExpoBeacon.types";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGhD,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGhD,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["// Native module (default export)\r\nexport { default } from \"./ExpoBeaconModule.js\";\r\n\r\n// All public types\r\nexport type {\r\n BeaconScanResult,\r\n PairedBeacon,\r\n BeaconRegionEvent,\r\n BeaconDistanceEvent,\r\n BeaconTimeoutEvent,\r\n ExpoBeaconModuleEvents,\r\n NotificationConfig,\r\n MonitoringOptions,\r\n MonitoringConfig,\r\n MonitoredDeviceState,\r\n BeaconNotificationConfig,\r\n CarPlayNotificationConfig,\r\n CarPlayChannelConfig,\r\n ForegroundServiceConfig,\r\n NotificationChannelConfig,\r\n EddystoneFrameType,\r\n EddystoneScanResult,\r\n PairedEddystone,\r\n EddystoneRegionEvent,\r\n EddystoneDistanceEvent,\r\n EddystoneTimeoutEvent,\r\n EventLogQueryOptions,\r\n EventLogEntry,\r\n CarPlayTransport,\r\n CarPlayConnectedEvent,\r\n CarPlayDisconnectedEvent,\r\n CarPlayConnectionStatus,\r\n} from \"./ExpoBeacon.types\";\r\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["// Native module (default export)\r\nexport { default } from \"./ExpoBeaconModule.js\";\r\n\r\n// All public types\r\nexport type {\r\n BeaconScanResult,\r\n PairedBeacon,\r\n BeaconRegionEvent,\r\n BeaconDistanceEvent,\r\n BeaconTimeoutEvent,\r\n ExpoBeaconModuleEvents,\r\n NotificationConfig,\r\n MonitoringOptions,\r\n MonitoringConfig,\r\n MonitoredDeviceState,\r\n BeaconNotificationConfig,\r\n CarPlayNotificationConfig,\r\n CarPlayChannelConfig,\r\n ForegroundServiceConfig,\r\n NotificationChannelConfig,\r\n EddystoneFrameType,\r\n EddystoneScanResult,\r\n PairedEddystone,\r\n EddystoneRegionEvent,\r\n EddystoneDistanceEvent,\r\n EddystoneTimeoutEvent,\r\n EventLogQueryOptions,\r\n EventLogEntry,\r\n CarPlayTransport,\r\n CarPlayConnectedEvent,\r\n CarPlayDisconnectedEvent,\r\n CarPlayConnectionStatus,\r\n CarPlayDiagnostics,\r\n} from \"./ExpoBeacon.types\";\r\n"]}
@@ -501,6 +501,31 @@ public class ExpoBeaconModule: Module {
501
501
  return self.defaults.bool(forKey: CARPLAY_MONITORING_ENABLED_KEY)
502
502
  }
503
503
 
504
+ Function("getCarPlayConnectionStatus") { () -> [String: Any] in
505
+ // Always read the live audio-route state — cheaper than persisted
506
+ // and accurate even when the monitor isn't running.
507
+ let connected = self.defaults.bool(forKey: CARPLAY_LAST_CONNECTED_KEY)
508
+ var out: [String: Any] = ["connected": connected]
509
+ if connected {
510
+ let now = Date()
511
+ out["timestamp"] = now.timeIntervalSince1970 * 1000.0
512
+ }
513
+ return out
514
+ }
515
+
516
+ Function("getCarPlayDiagnostics") { () -> [String: Any] in
517
+ // iOS detection is via AVAudioSession, not a content provider —
518
+ // most diagnostic fields aren't applicable. Returning constants
519
+ // keeps the cross-platform JS surface uniform.
520
+ return [
521
+ "isCarAppMetadataPresent": true,
522
+ "isCarProviderQueryable": true,
523
+ "lastRawConnectionType": NSNull(),
524
+ "observerActive": self.defaults.bool(forKey: CARPLAY_MONITORING_ENABLED_KEY),
525
+ "serviceAlive": true,
526
+ ]
527
+ }
528
+
504
529
  // MARK: - Continuous Scan
505
530
 
506
531
  Function("startContinuousScan") { () -> Void in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-beacon",
3
- "version": "0.8.9",
3
+ "version": "0.9.0",
4
4
  "description": "Expo module for scanning, pairing, and monitoring iBeacons on Android and iOS",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -1,7 +1,9 @@
1
1
  import { ConfigPlugin } from '@expo/config-plugins';
2
+ import { BeaconAndroidPluginProps } from './withBeaconAndroid';
2
3
  import { BeaconIOSPluginProps } from './withBeaconIOS';
3
4
  export type BeaconPluginProps = {
4
5
  ios?: BeaconIOSPluginProps;
6
+ android?: BeaconAndroidPluginProps;
5
7
  };
6
8
  declare const _default: ConfigPlugin<void | BeaconPluginProps>;
7
9
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,sBAAsB,CAAC;AAEzE,OAAsB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEtE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,CAAC,EAAE,oBAAoB,CAAC;CAC5B,CAAC;;AAqBF,wBAIE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,sBAAsB,CAAC;AACzE,OAA0B,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAsB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEtE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,CAAC,EAAE,oBAAoB,CAAC;IAC3B,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACpC,CAAC;;AAqBF,wBAIE"}
@@ -15,7 +15,7 @@ const withBeaconBGLocation = (config, props) => {
15
15
  config = (0, withBeaconIOS_1.default)(config, opts.ios);
16
16
  }
17
17
  if (platform !== 'ios') {
18
- config = (0, withBeaconAndroid_1.default)(config);
18
+ config = (0, withBeaconAndroid_1.default)(config, opts.android);
19
19
  }
20
20
  return config;
21
21
  };
@@ -1,5 +1,39 @@
1
1
  import { ConfigPlugin } from '@expo/config-plugins';
2
+ /**
3
+ * Categories advertised in the generated `automotive_app_desc.xml` resource.
4
+ * - `template` — declares the app as a Car-App-Library template provider. This
5
+ * is the value most commonly required by Gearhead to flag the package as
6
+ * Android-Auto-aware and start reporting `CONNECTION_TYPE_PROJECTION` via
7
+ * `CarConnection.getType()`. Side effect: the app may appear in the AA
8
+ * launcher drawer.
9
+ * - `media` — media-app category (audio playback in AA).
10
+ * - `notification` — silent registration; no AA UI surface but still flags the
11
+ * package as AA-aware for connection detection. Use this when the consumer
12
+ * app shouldn't appear in the AA drawer at all.
13
+ */
14
+ export type AndroidAutoUsesName = 'template' | 'media' | 'notification';
15
+ export type BeaconAndroidPluginProps = {
16
+ /**
17
+ * Android Auto registration. When enabled (the default), the plugin injects
18
+ * the `com.google.android.gms.car.application` meta-data into the consumer
19
+ * app's `AndroidManifest.xml` and emits a matching
20
+ * `res/xml/automotive_app_desc.xml` resource. This makes Gearhead recognise
21
+ * the app, which is a prerequisite for `CarConnection.getType()` to ever
22
+ * report `PROJECTION` — without it the LiveData silently stays at
23
+ * `NOT_CONNECTED` and `onCarPlayConnected` never fires.
24
+ *
25
+ * Defaults: `{ register: true, usesName: 'template' }`.
26
+ */
27
+ androidAuto?: {
28
+ /** Set to `false` to suppress the registration entirely (e.g. when you
29
+ * manage `automotive_app_desc.xml` yourself). Default: `true`. */
30
+ register?: boolean;
31
+ /** Category written into the generated XML. See {@link AndroidAutoUsesName}.
32
+ * Default: `'template'`. */
33
+ usesName?: AndroidAutoUsesName;
34
+ };
35
+ };
2
36
  export declare function getAndroidPluginKotlin(packageName: string): string;
3
- declare const withBeaconAndroid: ConfigPlugin;
37
+ declare const withBeaconAndroid: ConfigPlugin<BeaconAndroidPluginProps | void>;
4
38
  export default withBeaconAndroid;
5
39
  //# sourceMappingURL=withBeaconAndroid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"withBeaconAndroid.d.ts","sourceRoot":"","sources":["../src/withBeaconAndroid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoB,MAAM,sBAAsB,CAAC;AAMtE,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAqClE;AAqCD,QAAA,MAAM,iBAAiB,EAAE,YA0DxB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"withBeaconAndroid.d.ts","sourceRoot":"","sources":["../src/withBeaconAndroid.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,YAAY,EAGb,MAAM,sBAAsB,CAAC;AAM9B;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,OAAO,GAAG,cAAc,CAAC;AAExE,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE;QACZ;2EACmE;QACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB;qCAC6B;QAC7B,QAAQ,CAAC,EAAE,mBAAmB,CAAC;KAChC,CAAC;CACH,CAAC;AAIF,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAqClE;AAqHD,QAAA,MAAM,iBAAiB,EAAE,YAAY,CAAC,wBAAwB,GAAG,IAAI,CA0EpE,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -67,7 +67,72 @@ function modifyMainApplication(contents) {
67
67
  return contents;
68
68
  }
69
69
  // ─── Plugin ───────────────────────────────────────────────────────────────────
70
- const withBeaconAndroid = (config) => {
70
+ const AA_META_DATA_NAME = 'com.google.android.gms.car.application';
71
+ const AA_META_DATA_RESOURCE = '@xml/automotive_app_desc';
72
+ const AA_RES_FILE = 'automotive_app_desc.xml';
73
+ function getAutomotiveAppDescXml(usesName) {
74
+ return `<?xml version="1.0" encoding="utf-8"?>
75
+ <!--
76
+ Generated by the expo-beacon config plugin. Marks this app as
77
+ Android-Auto-aware so Gearhead reports CarConnection.PROJECTION to the
78
+ process. Disable via the plugin's android.androidAuto.register: false
79
+ option if you want to manage this resource yourself.
80
+ -->
81
+ <automotiveApp>
82
+ <uses name="${usesName}"/>
83
+ </automotiveApp>
84
+ `;
85
+ }
86
+ /**
87
+ * Inject the `com.google.android.gms.car.application` meta-data into the
88
+ * consumer app's `<application>` element. Idempotent — `addMetaDataItemToMainApplication`
89
+ * replaces an existing entry with the same name rather than duplicating it,
90
+ * so re-runs of `expo prebuild` are safe. Skipped when the manifest already
91
+ * declares the meta-data (presence implies the user is managing it manually).
92
+ */
93
+ const withAndroidAutoMetaData = (config) => {
94
+ return (0, config_plugins_1.withAndroidManifest)(config, (config) => {
95
+ const app = config_plugins_1.AndroidConfig.Manifest.getMainApplicationOrThrow(config.modResults);
96
+ const existing = config_plugins_1.AndroidConfig.Manifest.getMainApplicationMetaDataValue(config.modResults, AA_META_DATA_NAME);
97
+ if (existing != null) {
98
+ // User-managed entry; leave it alone.
99
+ return config;
100
+ }
101
+ config_plugins_1.AndroidConfig.Manifest.addMetaDataItemToMainApplication(app, AA_META_DATA_NAME, AA_META_DATA_RESOURCE, 'resource');
102
+ return config;
103
+ });
104
+ };
105
+ /**
106
+ * Emit `android/app/src/main/res/xml/automotive_app_desc.xml`. Never
107
+ * overwrites an existing file — if the consumer hand-authored the resource
108
+ * (e.g. with multiple `<uses>` children), we respect it and log a notice.
109
+ */
110
+ function withAndroidAutoDescriptor(usesName) {
111
+ return (config) => (0, config_plugins_1.withDangerousMod)(config, [
112
+ 'android',
113
+ (config) => {
114
+ const xmlDir = path.join(config.modRequest.platformProjectRoot, 'app/src/main/res/xml');
115
+ const xmlPath = path.join(xmlDir, AA_RES_FILE);
116
+ if (fs.existsSync(xmlPath)) {
117
+ // Don't clobber a user-managed resource.
118
+ return config;
119
+ }
120
+ try {
121
+ fs.mkdirSync(xmlDir, { recursive: true });
122
+ fs.writeFileSync(xmlPath, getAutomotiveAppDescXml(usesName));
123
+ }
124
+ catch (err) {
125
+ console.warn(`[expo-beacon] Failed to write ${AA_RES_FILE}: ${String(err)}`);
126
+ }
127
+ return config;
128
+ },
129
+ ]);
130
+ }
131
+ const withBeaconAndroid = (config, props) => {
132
+ var _a, _b, _c, _d;
133
+ const opts = props !== null && props !== void 0 ? props : {};
134
+ const aaRegister = (_b = (_a = opts.androidAuto) === null || _a === void 0 ? void 0 : _a.register) !== null && _b !== void 0 ? _b : true;
135
+ const aaUsesName = (_d = (_c = opts.androidAuto) === null || _c === void 0 ? void 0 : _c.usesName) !== null && _d !== void 0 ? _d : 'template';
71
136
  // Step 1 – write BeaconGeoPlugin.kt into the app source tree.
72
137
  config = (0, config_plugins_1.withDangerousMod)(config, [
73
138
  'android',
@@ -108,6 +173,14 @@ const withBeaconAndroid = (config) => {
108
173
  return config;
109
174
  },
110
175
  ]);
176
+ // Step 3 – register the consumer app as Android-Auto-aware so Gearhead
177
+ // surfaces CarConnection.PROJECTION to our CarPlayMonitor. Opt-out via
178
+ // `androidAuto.register: false` for advanced consumers managing this
179
+ // themselves.
180
+ if (aaRegister) {
181
+ config = withAndroidAutoMetaData(config);
182
+ config = withAndroidAutoDescriptor(aaUsesName)(config);
183
+ }
111
184
  return config;
112
185
  };
113
186
  exports.default = withBeaconAndroid;
@@ -364,6 +364,62 @@ export type CarPlayConnectionStatus = {
364
364
  timestampIso?: string;
365
365
  };
366
366
 
367
+ /**
368
+ * Diagnostic snapshot for troubleshooting CarPlay / Android Auto detection.
369
+ * Returned by {@link ExpoBeaconModule.getCarPlayDiagnostics}.
370
+ *
371
+ * The most common failure mode on Android is that the host app is not
372
+ * registered as an Android Auto-aware app (missing
373
+ * `com.google.android.gms.car.application` meta-data + `automotive_app_desc.xml`
374
+ * resource). When that happens, Gearhead silently reports
375
+ * `CONNECTION_TYPE_NOT_CONNECTED` to the app regardless of `<queries>`
376
+ * declarations, so `onCarPlayConnected` events never fire.
377
+ *
378
+ * Inspect this object after calling `startCarPlayMonitoring()` and confirming
379
+ * Android Auto is connected on the head unit. If `isCarAppMetadataPresent` or
380
+ * `isCarProviderQueryable` is `false`, the consumer app needs to enable the
381
+ * config plugin's `android.androidAuto.register` option (default in recent
382
+ * versions) and re-run `expo prebuild`.
383
+ *
384
+ * On iOS the diagnostic is a best-effort stub — most fields are not applicable
385
+ * because CarPlay detection uses `AVAudioSession` rather than a content
386
+ * provider.
387
+ */
388
+ export type CarPlayDiagnostics = {
389
+ /**
390
+ * Android: `true` if the host app's manifest declares the
391
+ * `com.google.android.gms.car.application` meta-data tag (required for
392
+ * Gearhead to expose connection state to the app). iOS: always `true`.
393
+ */
394
+ isCarAppMetadataPresent: boolean;
395
+ /**
396
+ * Android: `true` if the system can resolve at least one provider for the
397
+ * `androidx.car.app.connection.action.CAR_PROVIDER` intent (requires the
398
+ * `<queries>` declaration shipped by this library AND a compatible Gearhead
399
+ * / AAOS install on the device). iOS: always `true`.
400
+ */
401
+ isCarProviderQueryable: boolean;
402
+ /**
403
+ * Android: most recent raw value read from `CarConnection.getType()`.
404
+ * `0` = `NOT_CONNECTED`, `1` = `NATIVE` (AAOS), `2` = `PROJECTION`.
405
+ * `null` if the observer has not yet received any value (or is not running).
406
+ * iOS: `null`.
407
+ */
408
+ lastRawConnectionType: number | null;
409
+ /**
410
+ * `true` if the underlying connection observer is currently active.
411
+ * On Android, equivalent to "the foreground service is running AND
412
+ * `CarPlayMonitor.start()` succeeded". On iOS, the audio-session observer
413
+ * is registered.
414
+ */
415
+ observerActive: boolean;
416
+ /**
417
+ * Android: `true` if the foreground service hosting the observer is alive.
418
+ * iOS: always `true` (no background service involved).
419
+ */
420
+ serviceAlive: boolean;
421
+ };
422
+
367
423
  /** Payload for native beacon error events (monitoring/ranging failures). */
368
424
  export type BeaconErrorEvent = {
369
425
  /** Region or constraint identifier, empty string if unavailable. */
@@ -13,6 +13,7 @@ import {
13
13
  EventLogQueryOptions,
14
14
  EventLogEntry,
15
15
  CarPlayConnectionStatus,
16
+ CarPlayDiagnostics,
16
17
  } from "./ExpoBeacon.types";
17
18
 
18
19
  declare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {
@@ -256,6 +257,17 @@ declare class ExpoBeaconModule extends NativeModule<ExpoBeaconModuleEvents> {
256
257
  * back to the persisted last-known state otherwise.
257
258
  */
258
259
  getCarPlayConnectionStatus(): CarPlayConnectionStatus;
260
+
261
+ /**
262
+ * Returns diagnostic information about the CarPlay / Android Auto detection
263
+ * pipeline. Use this when `onCarPlayConnected` never fires despite the head
264
+ * unit being connected — it reveals whether the host app is correctly
265
+ * registered with Gearhead, whether the connection content provider is
266
+ * reachable, and the most recent raw value the observer received.
267
+ *
268
+ * See {@link CarPlayDiagnostics} for field-level guidance.
269
+ */
270
+ getCarPlayDiagnostics(): CarPlayDiagnostics;
259
271
  }
260
272
 
261
273
  export default requireNativeModule<ExpoBeaconModule>("ExpoBeacon");
package/src/index.ts CHANGED
@@ -30,4 +30,5 @@ export type {
30
30
  CarPlayConnectedEvent,
31
31
  CarPlayDisconnectedEvent,
32
32
  CarPlayConnectionStatus,
33
+ CarPlayDiagnostics,
33
34
  } from "./ExpoBeacon.types";