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

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,18 @@ 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: ReadableMap = geofences.getMap(i) ?: run {
136
+ Log.w(TAG, "addGeofences: index $i skipped (null map)")
137
+ continue
138
+ }
139
+ val id = item.getString("id") ?: run {
140
+ Log.w(TAG, "addGeofences: index $i skipped (missing id)")
141
+ continue
142
+ }
124
143
  val name = if (item.hasKey("name")) item.getString("name") else null
125
144
  val lat = item.getDouble("latitude")
126
145
  val lng = item.getDouble("longitude")
@@ -140,8 +159,10 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
140
159
  )
141
160
  .build()
142
161
  )
162
+ Log.i(TAG, "addGeofences: parsed geofence id=$id lat=$lat lng=$lng radius=$radius")
143
163
  }
144
164
  if (list.isEmpty()) {
165
+ Log.e(TAG, "addGeofences: no valid geofences — resolving false (check id/latitude/longitude)")
145
166
  promise.resolve(false)
146
167
  return
147
168
  }
@@ -150,15 +171,21 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
150
171
  .setInitialTrigger(0)
151
172
  .addGeofences(list)
152
173
  .build()
174
+ Log.i(TAG, "addGeofences: calling GeofencingClient.addGeofences count=${list.size}")
153
175
  geofencingClient.addGeofences(request, getPendingIntent())
154
176
  .addOnSuccessListener {
155
177
  getPrefs(applicationContext).edit()
156
178
  .putLong(PREFS_KEY_LAST_ADD_AT, System.currentTimeMillis())
157
179
  .apply()
180
+ Log.i(TAG, "addGeofences: SUCCESS — geofences registered with Play Services")
158
181
  promise.resolve(true)
159
182
  }
160
- .addOnFailureListener { promise.resolve(false) }
183
+ .addOnFailureListener { e ->
184
+ Log.e(TAG, "addGeofences: FAILURE — ${e.message}", e)
185
+ promise.resolve(false)
186
+ }
161
187
  } catch (e: Exception) {
188
+ Log.e(TAG, "addGeofences: exception", e)
162
189
  promise.reject(e)
163
190
  }
164
191
  }
@@ -180,13 +207,20 @@ class GeofenceManagerModule(reactContext: ReactApplicationContext) :
180
207
  }
181
208
 
182
209
  override fun removeAllGeofences(promise: Promise) {
210
+ Log.i(TAG, "removeAllGeofences: start")
183
211
  synchronized(GeofenceManagerModule.geofenceNames) {
184
212
  GeofenceManagerModule.geofenceNames.clear()
185
213
  GeofenceManagerModule.geofenceDetailsMap.clear()
186
214
  }
187
215
  getPrefs(applicationContext).edit().remove(PREFS_KEY_DETAILS).apply()
188
216
  geofencingClient.removeGeofences(getPendingIntent())
189
- .addOnSuccessListener { promise.resolve(true) }
190
- .addOnFailureListener { promise.resolve(false) }
217
+ .addOnSuccessListener {
218
+ Log.i(TAG, "removeAllGeofences: SUCCESS")
219
+ promise.resolve(true)
220
+ }
221
+ .addOnFailureListener { e ->
222
+ Log.e(TAG, "removeAllGeofences: FAILURE — ${e.message}", e)
223
+ promise.resolve(false)
224
+ }
191
225
  }
192
226
  }
@@ -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.13",
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 };