react-native-geofence-manager 0.1.0-beta.12 → 0.1.0-beta.14

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
@@ -115,6 +115,22 @@ Para geofences confiáveis é necessário **localização** (fina ou aproximada)
115
115
 
116
116
  ---
117
117
 
118
+ ## Depuração (logs)
119
+
120
+ A lib emite logs em cada etapa para localizar falhas (SDK nativo + JS).
121
+
122
+ **Android (Logcat)** — filtre pela tag:
123
+
124
+ ```text
125
+ adb logcat -s GeofenceManager
126
+ ```
127
+
128
+ Você verá, entre outros: inicialização do módulo, `addGeofences` (sucesso/falha do Play Services), `BroadcastReceiver` (transição, foreground vs headless), `HeadlessTaskService` e erros de reflexão.
129
+
130
+ **JavaScript** — mensagens com prefixo `[GeofenceManager]` no console (Metro) e também no Logcat como `ReactNativeJS` ao rodar no dispositivo.
131
+
132
+ ---
133
+
118
134
  ## App de exemplo
119
135
 
120
136
  Na raiz do repositório:
@@ -4,6 +4,7 @@ import android.content.BroadcastReceiver
4
4
  import android.content.Context
5
5
  import android.content.Intent
6
6
  import android.os.Build
7
+ import android.util.Log
7
8
  import android.os.Handler
8
9
  import android.os.Looper
9
10
  import com.facebook.react.HeadlessJsTaskService
@@ -16,36 +17,71 @@ import com.google.android.gms.location.GeofencingEvent
16
17
 
17
18
  class GeofenceBroadcastReceiver : BroadcastReceiver() {
18
19
 
20
+ companion object {
21
+ private const val TAG = "GeofenceManager"
22
+ }
23
+
19
24
  override fun onReceive(context: Context?, intent: Intent?) {
20
- if (context == null || intent == null) return
21
- if (intent.action != GeofenceManagerModule.GEOFENCE_ACTION) return
25
+ Log.i(TAG, "BroadcastReceiver.onReceive: invoked action=${intent?.action}")
26
+ if (context == null || intent == null) {
27
+ Log.w(TAG, "BroadcastReceiver.onReceive: abort — null context or intent")
28
+ return
29
+ }
30
+ if (intent.action != GeofenceManagerModule.GEOFENCE_ACTION) {
31
+ Log.w(TAG, "BroadcastReceiver.onReceive: wrong action, expected ${GeofenceManagerModule.GEOFENCE_ACTION}")
32
+ return
33
+ }
22
34
 
23
- val geofencingEvent = GeofencingEvent.fromIntent(intent) ?: return
24
- if (geofencingEvent.hasError()) return
35
+ val geofencingEvent = GeofencingEvent.fromIntent(intent)
36
+ if (geofencingEvent == null) {
37
+ Log.e(TAG, "BroadcastReceiver.onReceive: GeofencingEvent.fromIntent returned null")
38
+ return
39
+ }
40
+ if (geofencingEvent.hasError()) {
41
+ Log.e(TAG, "BroadcastReceiver.onReceive: Geofencing error code=${geofencingEvent.errorCode}")
42
+ return
43
+ }
25
44
 
26
- if (GeofenceManagerModule.isWithinGracePeriod(context)) return
45
+ if (GeofenceManagerModule.isWithinGracePeriod(context)) {
46
+ Log.i(TAG, "BroadcastReceiver.onReceive: skipped — within grace period after addGeofences")
47
+ return
48
+ }
27
49
 
28
50
  val transition = geofencingEvent.geofenceTransition
29
51
  val eventName = when (transition) {
30
52
  Geofence.GEOFENCE_TRANSITION_ENTER -> "enter"
31
53
  Geofence.GEOFENCE_TRANSITION_EXIT -> "exit"
32
54
  Geofence.GEOFENCE_TRANSITION_DWELL -> "dwell"
33
- else -> return
55
+ else -> {
56
+ Log.w(TAG, "BroadcastReceiver.onReceive: unknown transition=$transition")
57
+ return
58
+ }
34
59
  }
60
+ Log.i(TAG, "BroadcastReceiver.onReceive: transition=$eventName")
35
61
 
36
- val triggeringGeofences = geofencingEvent.triggeringGeofences ?: return
37
- if (triggeringGeofences.isEmpty()) return
62
+ val triggeringGeofences = geofencingEvent.triggeringGeofences
63
+ if (triggeringGeofences == null || triggeringGeofences.isEmpty()) {
64
+ Log.w(TAG, "BroadcastReceiver.onReceive: no triggering geofences")
65
+ return
66
+ }
38
67
 
39
68
  val reactContext = GeofenceManagerModule.reactContextRef
40
69
  val timestamp = System.currentTimeMillis().toDouble()
41
70
  val isForeground = reactContext != null && reactContext.hasActiveReactInstance()
71
+ Log.i(
72
+ TAG,
73
+ "BroadcastReceiver.onReceive: ids=${triggeringGeofences.map { it.requestId }} isForeground=$isForeground hasReactContextRef=${reactContext != null}"
74
+ )
42
75
 
43
76
  if (isForeground) {
44
77
  val ctx = reactContext!!
45
78
  val geofenceIds = triggeringGeofences.map { it.requestId }
46
79
  val eventNameForRunnable = eventName
47
80
  Handler(Looper.getMainLooper()).postDelayed({
48
- if (!ctx.hasActiveReactInstance()) return@postDelayed
81
+ if (!ctx.hasActiveReactInstance()) {
82
+ Log.w(TAG, "BroadcastReceiver: foreground path — React instance gone after delay, skipping emit")
83
+ return@postDelayed
84
+ }
49
85
  try {
50
86
  val emitter = ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
51
87
  for (geofenceId in geofenceIds) {
@@ -61,13 +97,17 @@ class GeofenceBroadcastReceiver : BroadcastReceiver() {
61
97
  putDouble("radius", it.radius.toDouble())
62
98
  }
63
99
  }
100
+ Log.i(TAG, "BroadcastReceiver: emitting onGeofenceTransition id=$geofenceId event=$eventNameForRunnable")
64
101
  emitter.emit("onGeofenceTransition", params)
65
102
  }
66
- } catch (_: Exception) { }
103
+ } catch (e: Exception) {
104
+ Log.e(TAG, "BroadcastReceiver: emit to JS failed", e)
105
+ }
67
106
  }, 50)
68
107
  return
69
108
  }
70
109
 
110
+ Log.i(TAG, "BroadcastReceiver: background/headless path — starting GeofenceHeadlessTaskService")
71
111
  val appContext = context.applicationContext
72
112
  HeadlessJsTaskService.acquireWakeLockNow(appContext)
73
113
  for (geofence in triggeringGeofences) {
@@ -76,10 +116,16 @@ class GeofenceBroadcastReceiver : BroadcastReceiver() {
76
116
  putExtra(GeofenceHeadlessTaskService.EXTRA_EVENT, eventName)
77
117
  putExtra(GeofenceHeadlessTaskService.EXTRA_TIMESTAMP, timestamp)
78
118
  }
79
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
80
- appContext.startForegroundService(serviceIntent)
81
- } else {
82
- appContext.startService(serviceIntent)
119
+ try {
120
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
121
+ appContext.startForegroundService(serviceIntent)
122
+ Log.i(TAG, "BroadcastReceiver: startForegroundService for id=${geofence.requestId}")
123
+ } else {
124
+ appContext.startService(serviceIntent)
125
+ Log.i(TAG, "BroadcastReceiver: startService for id=${geofence.requestId}")
126
+ }
127
+ } catch (e: Exception) {
128
+ Log.e(TAG, "BroadcastReceiver: failed to start headless service", e)
83
129
  }
84
130
  }
85
131
  }
@@ -5,6 +5,7 @@ import android.app.NotificationChannel
5
5
  import android.app.NotificationManager
6
6
  import android.content.Intent
7
7
  import android.os.Build
8
+ import android.util.Log
8
9
  import com.facebook.react.HeadlessJsTaskService
9
10
  import com.facebook.react.bridge.Arguments
10
11
  import com.facebook.react.jstasks.HeadlessJsTaskConfig
@@ -18,13 +19,21 @@ class GeofenceHeadlessTaskService : HeadlessJsTaskService() {
18
19
  * startForeground() é chamado para que o sistema inicie o serviço mesmo em background (dwell/exit).
19
20
  */
20
21
  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
22
+ Log.i(TAG, "HeadlessTaskService.onStartCommand extras=${intent?.extras}")
21
23
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
22
24
  ensureNotificationChannel()
23
25
  val notification = buildNotification(intent)
24
26
  startForeground(NOTIFICATION_ID, notification)
27
+ Log.d(TAG, "HeadlessTaskService: startForeground done")
28
+ }
29
+ val taskConfig = getTaskConfig(intent)
30
+ if (taskConfig == null) {
31
+ Log.e(TAG, "HeadlessTaskService: getTaskConfig returned null — check EXTRA_GEOFENCE_ID / EXTRA_EVENT")
32
+ return START_NOT_STICKY
25
33
  }
26
- val taskConfig = getTaskConfig(intent) ?: return START_NOT_STICKY
27
34
  val ctx = reactContext
35
+ val hasInstance = ctx?.hasActiveReactInstance() == true
36
+ Log.i(TAG, "HeadlessTaskService: hasActiveReactInstance=$hasInstance")
28
37
  if (ctx != null && !ctx.hasActiveReactInstance()) {
29
38
  HeadlessJsTaskService.acquireWakeLockNow(this)
30
39
  try {
@@ -34,21 +43,32 @@ class GeofenceHeadlessTaskService : HeadlessJsTaskService() {
34
43
  )
35
44
  method.isAccessible = true
36
45
  method.invoke(this, taskConfig)
37
- } catch (_: Exception) {
46
+ Log.i(TAG, "HeadlessTaskService: createReactContextAndScheduleTask invoked OK")
47
+ } catch (e: Exception) {
48
+ Log.e(TAG, "HeadlessTaskService: reflection createReactContextAndScheduleTask failed", e)
38
49
  return super.onStartCommand(intent, flags, startId)
39
50
  }
40
51
  return START_REDELIVER_INTENT
41
52
  }
53
+ Log.i(TAG, "HeadlessTaskService: delegating to super.onStartCommand")
42
54
  return super.onStartCommand(intent, flags, startId)
43
55
  }
44
56
 
45
57
  override fun getTaskConfig(intent: Intent?): HeadlessJsTaskConfig? {
46
- if (intent == null) return null
47
- val geofenceId = intent.getStringExtra(EXTRA_GEOFENCE_ID) ?: return null
48
- val event = intent.getStringExtra(EXTRA_EVENT) ?: return null
58
+ if (intent == null) {
59
+ Log.w(TAG, "getTaskConfig: null intent")
60
+ return null
61
+ }
62
+ val geofenceId = intent.getStringExtra(EXTRA_GEOFENCE_ID)
63
+ val event = intent.getStringExtra(EXTRA_EVENT)
64
+ if (geofenceId == null || event == null) {
65
+ Log.e(TAG, "getTaskConfig: missing geofenceId or event (id=$geofenceId event=$event)")
66
+ return null
67
+ }
49
68
  val timestamp = intent.getDoubleExtra(EXTRA_TIMESTAMP, 0.0)
50
69
 
51
70
  val details = GeofenceManagerModule.getGeofenceDetails(this, geofenceId)
71
+ Log.i(TAG, "getTaskConfig: task=${GeofenceManagerModule.GEOFENCE_HEADLESS_TASK_NAME} id=$geofenceId event=$event")
52
72
  val data = Arguments.createMap().apply {
53
73
  putString("geofenceId", geofenceId)
54
74
  putString("event", event)
@@ -90,6 +110,7 @@ class GeofenceHeadlessTaskService : HeadlessJsTaskService() {
90
110
  }
91
111
 
92
112
  companion object {
113
+ private const val TAG = "GeofenceManager"
93
114
  private const val CHANNEL_ID = "geofence_manager_channel"
94
115
  private const val NOTIFICATION_ID = 9001
95
116
  const val EXTRA_GEOFENCE_ID = "geofenceId"
@@ -5,6 +5,7 @@ import android.content.ComponentName
5
5
  import android.content.Context
6
6
  import android.content.Intent
7
7
  import android.content.SharedPreferences
8
+ import android.util.Log
8
9
  import com.facebook.react.bridge.Promise
9
10
  import com.facebook.react.bridge.ReactApplicationContext
10
11
  import com.facebook.react.bridge.ReadableArray
@@ -20,6 +21,7 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
20
21
  NativeGeofenceManagerSpec(reactContext) {
21
22
 
22
23
  companion object {
24
+ private const val TAG = "GeofenceManager"
23
25
  const val NAME = "GeofenceManager"
24
26
  const val GEOFENCE_ACTION = "com.geofencemanager.GEOFENCE_TRANSITION"
25
27
  const val GEOFENCE_HEADLESS_TASK_NAME = "GeofenceManagerTransition"
@@ -70,7 +72,9 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
70
72
  geofenceDetailsMap[d.id] = d
71
73
  d.name?.let { geofenceNames[d.id] = it }
72
74
  }
73
- } catch (_: Exception) { }
75
+ } catch (e: Exception) {
76
+ Log.w(TAG, "loadDetailsFromPrefs failed", e)
77
+ }
74
78
  }
75
79
  }
76
80
 
@@ -84,11 +88,15 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
84
88
  }
85
89
 
86
90
  init {
91
+ Log.i(TAG, "Module init: package=${reactContext.packageName} hasActivity=${reactContext.currentActivity != null}")
87
92
  // Só guardar o contexto que tem Activity (tela principal). O contexto da headless task
88
93
  // não tem currentActivity; se o armazenarmos, os eventos em foreground (dwell/exit)
89
94
  // seriam emitidos para ele e o listener registrado na tela nunca receberia.
90
95
  if (reactContext.currentActivity != null) {
91
96
  GeofenceManagerModule.reactContextRef = reactContext
97
+ Log.i(TAG, "Module init: reactContextRef set (foreground JS will receive DeviceEventEmitter events)")
98
+ } else {
99
+ Log.w(TAG, "Module init: no currentActivity — reactContextRef NOT updated (normal for some init paths)")
92
100
  }
93
101
  }
94
102
 
@@ -98,7 +106,11 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
98
106
  private var geofencePendingIntent: PendingIntent? = null
99
107
 
100
108
  private fun getPendingIntent(): PendingIntent {
101
- geofencePendingIntent?.let { return it }
109
+ geofencePendingIntent?.let {
110
+ Log.d(TAG, "getPendingIntent: reusing existing PendingIntent")
111
+ return it
112
+ }
113
+ Log.i(TAG, "getPendingIntent: creating new PendingIntent -> GeofenceBroadcastReceiver action=$GEOFENCE_ACTION")
102
114
  val intent = Intent(applicationContext, GeofenceBroadcastReceiver::class.java).apply {
103
115
  action = GEOFENCE_ACTION
104
116
  setPackage(applicationContext.packageName)
@@ -116,11 +128,20 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
116
128
  override fun getName(): String = NAME
117
129
 
118
130
  override fun addGeofences(geofences: ReadableArray, promise: Promise) {
131
+ Log.i(TAG, "addGeofences: start, arraySize=${geofences.size()}")
119
132
  try {
120
133
  val list = mutableListOf<Geofence>()
121
134
  for (i in 0 until geofences.size()) {
122
- val item: ReadableMap = geofences.getMap(i) ?: continue
123
- val id = item.getString("id") ?: continue
135
+ val item = geofences.getMap(i)
136
+ if (item == null) {
137
+ Log.w(TAG, "addGeofences: index $i skipped (null map)")
138
+ continue
139
+ }
140
+ val id = item.getString("id")
141
+ if (id == null) {
142
+ Log.w(TAG, "addGeofences: index $i skipped (missing id)")
143
+ continue
144
+ }
124
145
  val name = if (item.hasKey("name")) item.getString("name") else null
125
146
  val lat = item.getDouble("latitude")
126
147
  val lng = item.getDouble("longitude")
@@ -140,8 +161,10 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
140
161
  )
141
162
  .build()
142
163
  )
164
+ Log.i(TAG, "addGeofences: parsed geofence id=$id lat=$lat lng=$lng radius=$radius")
143
165
  }
144
166
  if (list.isEmpty()) {
167
+ Log.e(TAG, "addGeofences: no valid geofences — resolving false (check id/latitude/longitude)")
145
168
  promise.resolve(false)
146
169
  return
147
170
  }
@@ -150,15 +173,21 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
150
173
  .setInitialTrigger(0)
151
174
  .addGeofences(list)
152
175
  .build()
176
+ Log.i(TAG, "addGeofences: calling GeofencingClient.addGeofences count=${list.size}")
153
177
  geofencingClient.addGeofences(request, getPendingIntent())
154
178
  .addOnSuccessListener {
155
179
  getPrefs(applicationContext).edit()
156
180
  .putLong(PREFS_KEY_LAST_ADD_AT, System.currentTimeMillis())
157
181
  .apply()
182
+ Log.i(TAG, "addGeofences: SUCCESS — geofences registered with Play Services")
158
183
  promise.resolve(true)
159
184
  }
160
- .addOnFailureListener { promise.resolve(false) }
185
+ .addOnFailureListener { e ->
186
+ Log.e(TAG, "addGeofences: FAILURE — ${e.message}", e)
187
+ promise.resolve(false)
188
+ }
161
189
  } catch (e: Exception) {
190
+ Log.e(TAG, "addGeofences: exception", e)
162
191
  promise.reject(e)
163
192
  }
164
193
  }
@@ -180,13 +209,20 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
180
209
  }
181
210
 
182
211
  override fun removeAllGeofences(promise: Promise) {
212
+ Log.i(TAG, "removeAllGeofences: start")
183
213
  synchronized(GeofenceManagerModule.geofenceNames) {
184
214
  GeofenceManagerModule.geofenceNames.clear()
185
215
  GeofenceManagerModule.geofenceDetailsMap.clear()
186
216
  }
187
217
  getPrefs(applicationContext).edit().remove(PREFS_KEY_DETAILS).apply()
188
218
  geofencingClient.removeGeofences(getPendingIntent())
189
- .addOnSuccessListener { promise.resolve(true) }
190
- .addOnFailureListener { promise.resolve(false) }
219
+ .addOnSuccessListener {
220
+ Log.i(TAG, "removeAllGeofences: SUCCESS")
221
+ promise.resolve(true)
222
+ }
223
+ .addOnFailureListener { e ->
224
+ Log.e(TAG, "removeAllGeofences: FAILURE — ${e.message}", e)
225
+ promise.resolve(false)
226
+ }
191
227
  }
192
228
  }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Logs de diagnóstico da lib. Aparecem no Metro e no Logcat (Android) com filtro "GeofenceManager".
5
+ */
6
+ const TAG = '[GeofenceManager]';
7
+ function safeStringify(data) {
8
+ try {
9
+ return JSON.stringify(data);
10
+ } catch {
11
+ return String(data);
12
+ }
13
+ }
14
+ export function geofenceDebugLog(step, data) {
15
+ const line = data !== undefined ? `${TAG} ${step} ${safeStringify(data)}` : `${TAG} ${step}`;
16
+ console.log(line);
17
+ }
18
+ export function geofenceDebugWarn(step, data) {
19
+ const line = data !== undefined ? `${TAG} ${step} ${safeStringify(data)}` : `${TAG} ${step}`;
20
+ console.warn(line);
21
+ }
22
+ //# sourceMappingURL=geofenceDebugLog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TAG","safeStringify","data","JSON","stringify","String","geofenceDebugLog","step","line","undefined","console","log","geofenceDebugWarn","warn"],"sourceRoot":"..\\..\\src","sources":["geofenceDebugLog.ts"],"mappings":";;AAAA;AACA;AACA;AACA,MAAMA,GAAG,GAAG,mBAAmB;AAE/B,SAASC,aAAaA,CAACC,IAAa,EAAU;EAC5C,IAAI;IACF,OAAOC,IAAI,CAACC,SAAS,CAACF,IAAI,CAAC;EAC7B,CAAC,CAAC,MAAM;IACN,OAAOG,MAAM,CAACH,IAAI,CAAC;EACrB;AACF;AAEA,OAAO,SAASI,gBAAgBA,CAACC,IAAY,EAAEL,IAAc,EAAQ;EACnE,MAAMM,IAAI,GACRN,IAAI,KAAKO,SAAS,GACd,GAAGT,GAAG,IAAIO,IAAI,IAAIN,aAAa,CAACC,IAAI,CAAC,EAAE,GACvC,GAAGF,GAAG,IAAIO,IAAI,EAAE;EACtBG,OAAO,CAACC,GAAG,CAACH,IAAI,CAAC;AACnB;AAEA,OAAO,SAASI,iBAAiBA,CAACL,IAAY,EAAEL,IAAc,EAAQ;EACpE,MAAMM,IAAI,GACRN,IAAI,KAAKO,SAAS,GACd,GAAGT,GAAG,IAAIO,IAAI,IAAIN,aAAa,CAACC,IAAI,CAAC,EAAE,GACvC,GAAGF,GAAG,IAAIO,IAAI,EAAE;EACtBG,OAAO,CAACG,IAAI,CAACL,IAAI,CAAC;AACpB","ignoreList":[]}
@@ -2,13 +2,23 @@
2
2
 
3
3
  import { AppRegistry, DeviceEventEmitter } from 'react-native';
4
4
  import NativeGeofenceManager from "./NativeGeofenceManager.js";
5
+ import { geofenceDebugLog, geofenceDebugWarn } from "./geofenceDebugLog.js";
5
6
  const EVENT_NAME = 'onGeofenceTransition';
6
7
 
7
8
  /** Nome da headless task para eventos de geofence (app morto/background). Deve ser usado com registerGeofenceHeadlessTask no index do app. */
8
9
  export const GEOFENCE_HEADLESS_TASK_NAME = 'GeofenceManagerTransition';
9
10
  export function addGeofenceEventListener(callback) {
10
- const subscription = DeviceEventEmitter.addListener(EVENT_NAME, payload => callback(payload));
11
- return () => subscription.remove();
11
+ geofenceDebugLog('JS: addGeofenceEventListener registering listener', {
12
+ eventName: EVENT_NAME
13
+ });
14
+ const subscription = DeviceEventEmitter.addListener(EVENT_NAME, payload => {
15
+ geofenceDebugLog('JS: addGeofenceEventListener — event received', payload);
16
+ callback(payload);
17
+ });
18
+ return () => {
19
+ geofenceDebugLog('JS: addGeofenceEventListener — unsubscribed');
20
+ subscription.remove();
21
+ };
12
22
  }
13
23
  export function onGeofenceEvent(callback) {
14
24
  return addGeofenceEventListener(callback);
@@ -32,13 +42,45 @@ export function onGeofenceEvent(callback) {
32
42
  * AppRegistry.registerComponent(appName, () => App);
33
43
  */
34
44
  export function registerGeofenceHeadlessTask(callback) {
35
- AppRegistry.registerHeadlessTask(GEOFENCE_HEADLESS_TASK_NAME, () => data => Promise.resolve(callback(data)));
45
+ geofenceDebugLog('JS: registerGeofenceHeadlessTask registering', {
46
+ taskName: GEOFENCE_HEADLESS_TASK_NAME
47
+ });
48
+ AppRegistry.registerHeadlessTask(GEOFENCE_HEADLESS_TASK_NAME, () => data => {
49
+ geofenceDebugLog('JS: headless task invoked', data);
50
+ return Promise.resolve(callback(data));
51
+ });
36
52
  }
37
- const addGeofences = geofences => {
38
- return NativeGeofenceManager.addGeofences(geofences);
53
+ const addGeofences = async geofences => {
54
+ geofenceDebugLog('JS: addGeofences — calling native', {
55
+ count: geofences.length,
56
+ ids: geofences.map(g => g.id)
57
+ });
58
+ try {
59
+ const ok = await NativeGeofenceManager.addGeofences(geofences);
60
+ geofenceDebugLog('JS: addGeofences — native result', {
61
+ success: ok
62
+ });
63
+ if (!ok) {
64
+ geofenceDebugWarn('JS: addGeofences — native returned false (empty list, Geofencing API failure, or permissions)');
65
+ }
66
+ return ok;
67
+ } catch (e) {
68
+ geofenceDebugWarn('JS: addGeofences — threw (TurboModule missing or bridge error)', e);
69
+ throw e;
70
+ }
39
71
  };
40
- const removeAllGeofences = () => {
41
- return NativeGeofenceManager.removeAllGeofences();
72
+ const removeAllGeofences = async () => {
73
+ geofenceDebugLog('JS: removeAllGeofences — calling native');
74
+ try {
75
+ const ok = await NativeGeofenceManager.removeAllGeofences();
76
+ geofenceDebugLog('JS: removeAllGeofences — native result', {
77
+ success: ok
78
+ });
79
+ return ok;
80
+ } catch (e) {
81
+ geofenceDebugWarn('JS: removeAllGeofences — threw', e);
82
+ throw e;
83
+ }
42
84
  };
43
85
  export { addGeofences, removeAllGeofences };
44
86
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["AppRegistry","DeviceEventEmitter","NativeGeofenceManager","EVENT_NAME","GEOFENCE_HEADLESS_TASK_NAME","addGeofenceEventListener","callback","subscription","addListener","payload","remove","onGeofenceEvent","registerGeofenceHeadlessTask","registerHeadlessTask","data","Promise","resolve","addGeofences","geofences","removeAllGeofences"],"sourceRoot":"..\\..\\src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,WAAW,EACXC,kBAAkB,QAEb,cAAc;AACrB,OAAOC,qBAAqB,MAAM,4BAAyB;AAS3D,MAAMC,UAAU,GAAG,sBAAsB;;AAEzC;AACA,OAAO,MAAMC,2BAA2B,GAAG,2BAA2B;AAEtE,OAAO,SAASC,wBAAwBA,CACtCC,QAAwC,EAC5B;EACZ,MAAMC,YAA+B,GAAGN,kBAAkB,CAACO,WAAW,CACpEL,UAAU,EACTM,OAAgB,IAAKH,QAAQ,CAACG,OAAwB,CACzD,CAAC;EACD,OAAO,MAAMF,YAAY,CAACG,MAAM,CAAC,CAAC;AACpC;AAEA,OAAO,SAASC,eAAeA,CAC7BL,QAAwC,EAC5B;EACZ,OAAOD,wBAAwB,CAACC,QAAQ,CAAC;AAC3C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASM,4BAA4BA,CAC1CN,QAAwC,EAClC;EACNN,WAAW,CAACa,oBAAoB,CAC9BT,2BAA2B,EAC3B,MAAOU,IAAa,IAAKC,OAAO,CAACC,OAAO,CAACV,QAAQ,CAACQ,IAAqB,CAAC,CAC1E,CAAC;AACH;AAEA,MAAMG,YAAY,GAAIC,SAA0B,IAAuB;EACrE,OAAOhB,qBAAqB,CAACe,YAAY,CAACC,SAAS,CAAC;AACtD,CAAC;AAED,MAAMC,kBAAkB,GAAGA,CAAA,KAAwB;EACjD,OAAOjB,qBAAqB,CAACiB,kBAAkB,CAAC,CAAC;AACnD,CAAC;AAED,SAASF,YAAY,EAAEE,kBAAkB","ignoreList":[]}
1
+ {"version":3,"names":["AppRegistry","DeviceEventEmitter","NativeGeofenceManager","geofenceDebugLog","geofenceDebugWarn","EVENT_NAME","GEOFENCE_HEADLESS_TASK_NAME","addGeofenceEventListener","callback","eventName","subscription","addListener","payload","remove","onGeofenceEvent","registerGeofenceHeadlessTask","taskName","registerHeadlessTask","data","Promise","resolve","addGeofences","geofences","count","length","ids","map","g","id","ok","success","e","removeAllGeofences"],"sourceRoot":"..\\..\\src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,WAAW,EACXC,kBAAkB,QAEb,cAAc;AACrB,OAAOC,qBAAqB,MAAM,4BAAyB;AAC3D,SAASC,gBAAgB,EAAEC,iBAAiB,QAAQ,uBAAoB;AASxE,MAAMC,UAAU,GAAG,sBAAsB;;AAEzC;AACA,OAAO,MAAMC,2BAA2B,GAAG,2BAA2B;AAEtE,OAAO,SAASC,wBAAwBA,CACtCC,QAAwC,EAC5B;EACZL,gBAAgB,CAAC,qDAAqD,EAAE;IACtEM,SAAS,EAAEJ;EACb,CAAC,CAAC;EACF,MAAMK,YAA+B,GAAGT,kBAAkB,CAACU,WAAW,CACpEN,UAAU,EACTO,OAAgB,IAAK;IACpBT,gBAAgB,CAAC,+CAA+C,EAAES,OAAO,CAAC;IAC1EJ,QAAQ,CAACI,OAAwB,CAAC;EACpC,CACF,CAAC;EACD,OAAO,MAAM;IACXT,gBAAgB,CAAC,6CAA6C,CAAC;IAC/DO,YAAY,CAACG,MAAM,CAAC,CAAC;EACvB,CAAC;AACH;AAEA,OAAO,SAASC,eAAeA,CAC7BN,QAAwC,EAC5B;EACZ,OAAOD,wBAAwB,CAACC,QAAQ,CAAC;AAC3C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASO,4BAA4BA,CAC1CP,QAAwC,EAClC;EACNL,gBAAgB,CAAC,gDAAgD,EAAE;IACjEa,QAAQ,EAAEV;EACZ,CAAC,CAAC;EACFN,WAAW,CAACiB,oBAAoB,CAC9BX,2BAA2B,EAC3B,MAAOY,IAAa,IAAK;IACvBf,gBAAgB,CAAC,2BAA2B,EAAEe,IAAI,CAAC;IACnD,OAAOC,OAAO,CAACC,OAAO,CAACZ,QAAQ,CAACU,IAAqB,CAAC,CAAC;EACzD,CACF,CAAC;AACH;AAEA,MAAMG,YAAY,GAAG,MACnBC,SAA0B,IACL;EACrBnB,gBAAgB,CAAC,mCAAmC,EAAE;IACpDoB,KAAK,EAAED,SAAS,CAACE,MAAM;IACvBC,GAAG,EAAEH,SAAS,CAACI,GAAG,CAAEC,CAAC,IAAKA,CAAC,CAACC,EAAE;EAChC,CAAC,CAAC;EACF,IAAI;IACF,MAAMC,EAAE,GAAG,MAAM3B,qBAAqB,CAACmB,YAAY,CAACC,SAAS,CAAC;IAC9DnB,gBAAgB,CAAC,kCAAkC,EAAE;MAAE2B,OAAO,EAAED;IAAG,CAAC,CAAC;IACrE,IAAI,CAACA,EAAE,EAAE;MACPzB,iBAAiB,CACf,+FACF,CAAC;IACH;IACA,OAAOyB,EAAE;EACX,CAAC,CAAC,OAAOE,CAAC,EAAE;IACV3B,iBAAiB,CAAC,gEAAgE,EAAE2B,CAAC,CAAC;IACtF,MAAMA,CAAC;EACT;AACF,CAAC;AAED,MAAMC,kBAAkB,GAAG,MAAAA,CAAA,KAA8B;EACvD7B,gBAAgB,CAAC,yCAAyC,CAAC;EAC3D,IAAI;IACF,MAAM0B,EAAE,GAAG,MAAM3B,qBAAqB,CAAC8B,kBAAkB,CAAC,CAAC;IAC3D7B,gBAAgB,CAAC,wCAAwC,EAAE;MAAE2B,OAAO,EAAED;IAAG,CAAC,CAAC;IAC3E,OAAOA,EAAE;EACX,CAAC,CAAC,OAAOE,CAAC,EAAE;IACV3B,iBAAiB,CAAC,gCAAgC,EAAE2B,CAAC,CAAC;IACtD,MAAMA,CAAC;EACT;AACF,CAAC;AAED,SAASV,YAAY,EAAEW,kBAAkB","ignoreList":[]}
@@ -0,0 +1,3 @@
1
+ export declare function geofenceDebugLog(step: string, data?: unknown): void;
2
+ export declare function geofenceDebugWarn(step: string, data?: unknown): void;
3
+ //# sourceMappingURL=geofenceDebugLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geofenceDebugLog.d.ts","sourceRoot":"","sources":["../../../src/geofenceDebugLog.ts"],"names":[],"mappings":"AAaA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAMnE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAMpE"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEnE,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,GACd,MAAM,gBAAgB,CAAC;AAIxB,8IAA8I;AAC9I,eAAO,MAAM,2BAA2B,8BAA8B,CAAC;AAEvE,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GACvC,MAAM,IAAI,CAMZ;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GACvC,MAAM,IAAI,CAEZ;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GACvC,IAAI,CAKN;AAED,QAAA,MAAM,YAAY,GAAI,WAAW,aAAa,EAAE,KAAG,OAAO,CAAC,OAAO,CAEjE,CAAC;AAEF,QAAA,MAAM,kBAAkB,QAAO,OAAO,CAAC,OAAO,CAE7C,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEnE,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,GACd,MAAM,gBAAgB,CAAC;AAIxB,8IAA8I;AAC9I,eAAO,MAAM,2BAA2B,8BAA8B,CAAC;AAEvE,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GACvC,MAAM,IAAI,CAeZ;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GACvC,MAAM,IAAI,CAEZ;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GACvC,IAAI,CAWN;AAED,QAAA,MAAM,YAAY,GAChB,WAAW,aAAa,EAAE,KACzB,OAAO,CAAC,OAAO,CAkBjB,CAAC;AAEF,QAAA,MAAM,kBAAkB,QAAa,OAAO,CAAC,OAAO,CAUnD,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-geofence-manager",
3
- "version": "0.1.0-beta.12",
3
+ "version": "0.1.0-beta.14",
4
4
  "description": "React Native library.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Logs de diagnóstico da lib. Aparecem no Metro e no Logcat (Android) com filtro "GeofenceManager".
3
+ */
4
+ const TAG = '[GeofenceManager]';
5
+
6
+ function safeStringify(data: unknown): string {
7
+ try {
8
+ return JSON.stringify(data);
9
+ } catch {
10
+ return String(data);
11
+ }
12
+ }
13
+
14
+ export function geofenceDebugLog(step: string, data?: unknown): void {
15
+ const line =
16
+ data !== undefined
17
+ ? `${TAG} ${step} ${safeStringify(data)}`
18
+ : `${TAG} ${step}`;
19
+ console.log(line);
20
+ }
21
+
22
+ export function geofenceDebugWarn(step: string, data?: unknown): void {
23
+ const line =
24
+ data !== undefined
25
+ ? `${TAG} ${step} ${safeStringify(data)}`
26
+ : `${TAG} ${step}`;
27
+ console.warn(line);
28
+ }
package/src/index.tsx CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  type EventSubscription,
5
5
  } from 'react-native';
6
6
  import NativeGeofenceManager from './NativeGeofenceManager';
7
+ import { geofenceDebugLog, geofenceDebugWarn } from './geofenceDebugLog';
7
8
  import type { GeofenceEvent, GeofenceModel } from './models/index';
8
9
 
9
10
  export type {
@@ -20,11 +21,20 @@ export const GEOFENCE_HEADLESS_TASK_NAME = 'GeofenceManagerTransition';
20
21
  export function addGeofenceEventListener(
21
22
  callback: (event: GeofenceEvent) => void
22
23
  ): () => void {
24
+ geofenceDebugLog('JS: addGeofenceEventListener — registering listener', {
25
+ eventName: EVENT_NAME,
26
+ });
23
27
  const subscription: EventSubscription = DeviceEventEmitter.addListener(
24
28
  EVENT_NAME,
25
- (payload: unknown) => callback(payload as GeofenceEvent)
29
+ (payload: unknown) => {
30
+ geofenceDebugLog('JS: addGeofenceEventListener — event received', payload);
31
+ callback(payload as GeofenceEvent);
32
+ }
26
33
  );
27
- return () => subscription.remove();
34
+ return () => {
35
+ geofenceDebugLog('JS: addGeofenceEventListener — unsubscribed');
36
+ subscription.remove();
37
+ };
28
38
  }
29
39
 
30
40
  export function onGeofenceEvent(
@@ -53,18 +63,50 @@ export function onGeofenceEvent(
53
63
  export function registerGeofenceHeadlessTask(
54
64
  callback: (event: GeofenceEvent) => void
55
65
  ): void {
66
+ geofenceDebugLog('JS: registerGeofenceHeadlessTask — registering', {
67
+ taskName: GEOFENCE_HEADLESS_TASK_NAME,
68
+ });
56
69
  AppRegistry.registerHeadlessTask(
57
70
  GEOFENCE_HEADLESS_TASK_NAME,
58
- () => (data: unknown) => Promise.resolve(callback(data as GeofenceEvent))
71
+ () => (data: unknown) => {
72
+ geofenceDebugLog('JS: headless task invoked', data);
73
+ return Promise.resolve(callback(data as GeofenceEvent));
74
+ }
59
75
  );
60
76
  }
61
77
 
62
- const addGeofences = (geofences: GeofenceModel[]): Promise<boolean> => {
63
- return NativeGeofenceManager.addGeofences(geofences);
78
+ const addGeofences = async (
79
+ geofences: GeofenceModel[]
80
+ ): Promise<boolean> => {
81
+ geofenceDebugLog('JS: addGeofences — calling native', {
82
+ count: geofences.length,
83
+ ids: geofences.map((g) => g.id),
84
+ });
85
+ try {
86
+ const ok = await NativeGeofenceManager.addGeofences(geofences);
87
+ geofenceDebugLog('JS: addGeofences — native result', { success: ok });
88
+ if (!ok) {
89
+ geofenceDebugWarn(
90
+ 'JS: addGeofences — native returned false (empty list, Geofencing API failure, or permissions)'
91
+ );
92
+ }
93
+ return ok;
94
+ } catch (e) {
95
+ geofenceDebugWarn('JS: addGeofences — threw (TurboModule missing or bridge error)', e);
96
+ throw e;
97
+ }
64
98
  };
65
99
 
66
- const removeAllGeofences = (): Promise<boolean> => {
67
- return NativeGeofenceManager.removeAllGeofences();
100
+ const removeAllGeofences = async (): Promise<boolean> => {
101
+ geofenceDebugLog('JS: removeAllGeofences — calling native');
102
+ try {
103
+ const ok = await NativeGeofenceManager.removeAllGeofences();
104
+ geofenceDebugLog('JS: removeAllGeofences — native result', { success: ok });
105
+ return ok;
106
+ } catch (e) {
107
+ geofenceDebugWarn('JS: removeAllGeofences — threw', e);
108
+ throw e;
109
+ }
68
110
  };
69
111
 
70
112
  export { addGeofences, removeAllGeofences };