react-native-geo-activity-kit 1.2.0 → 1.2.1

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.
Files changed (2) hide show
  1. package/README.md +118 -123
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,126 +1,158 @@
1
- # react-native-geo-activity-kit 📍
1
+ # react-native-geo-activity-kit 📍 (Android Only)
2
2
 
3
- A battery-efficient background location tracker for React Native.
4
- Most GPS libraries drain your battery in 3 hours. This library lasts 24+ hours.
3
+ Battery-efficient **background location & motion tracker** for React Native.
4
+
5
+ Unlike standard GPS libraries that drain battery in hours, this library uses the **Accelerometer (Low Power)** to intelligently toggle the **GPS (High Power)**. It includes a robust **Foreground Service** implementation to ensure background execution on modern Android versions (12/13/14+).
5
6
 
6
7
  ---
7
8
 
8
- ## 🧠 How it Works (The "Smart Switch")
9
+ ## 🧠 The "Smart Switch" Logic
10
+
11
+ ### Stationary Mode (Zero/Low Drain)
12
+
13
+ - When the user is sitting still, the accelerometer detects no movement.
14
+ - GPS is switched to _Balanced Power Mode_ (low frequency) or effectively paused.
15
+ - Battery drain is negligible.
9
16
 
10
- Standard location libraries keep the GPS chip (High Power) active 100% of the time.
11
- This library uses the **Accelerometer (Low Power)** to act as a smart GPS switch:
17
+ ### Moving Mode (High Accuracy)
12
18
 
13
- - **User Sits Still:** Accelerometer detects no movement **GPS OFF 🔴** (Zero Battery Drain)
14
- - **User Walks/Drives:** Accelerometer detects force → **GPS ON 🟢** (High Accuracy)
19
+ - When movement is detected (walking, driving), the library wakes up.
20
+ - GPS switches to _High Accuracy Mode_.
21
+ - Locations are logged at your configured interval.
15
22
 
16
23
  ---
17
24
 
18
25
  ## 📦 Installation
19
26
 
20
- ```
27
+ ```bash
21
28
  npm install react-native-geo-activity-kit
22
- ```
23
-
24
- or
25
-
26
- ```
29
+ # or
27
30
  yarn add react-native-geo-activity-kit
28
31
  ```
29
32
 
30
33
  ---
31
34
 
32
- ## 🤖 Android Setup (Required)
35
+ ## 🤖 Android Setup
36
+
37
+ ### 1. Update `AndroidManifest.xml`
33
38
 
34
- File: `android/app/src/main/AndroidManifest.xml`
35
- Add this inside `<manifest>`:
39
+ Open `android/app/src/main/AndroidManifest.xml` and add the following permissions inside the `<manifest>` tag:
36
40
 
37
41
  ```xml
38
42
  <manifest xmlns:android="http://schemas.android.com/apk/res/android">
39
43
 
40
- <!-- 1. Location Permissions -->
44
+ <!-- Location -->
41
45
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
42
46
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
47
+ <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
43
48
 
44
- <!-- 2. Service Permissions -->
49
+ <!-- Foreground Service (Crucial for Background Tasks) -->
45
50
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
46
51
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
47
52
 
48
- <!-- 3. Notification Permissions -->
53
+ <!-- Notifications (Android 13+) -->
49
54
  <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
50
55
 
51
- <!-- 4. System Permissions -->
56
+ <!-- System -->
52
57
  <uses-permission android:name="android.permission.WAKE_LOCK" />
53
58
 
54
59
  </manifest>
55
60
  ```
56
61
 
57
- ---
58
-
59
- ## 🚀 Quick Start Guide
62
+ > 💡 You may not strictly need `ACCESS_BACKGROUND_LOCATION` if you always run as a Foreground Service, but it's included here for maximum compatibility. Adjust based on your Play Store policy needs.
60
63
 
61
- ### **Step 1: Ask for Permissions**
62
-
63
- ```js
64
- import { PermissionsAndroid, Platform } from 'react-native';
64
+ ---
65
65
 
66
- const requestPermissions = async () => {
67
- if (Platform.OS === 'android') {
68
- await PermissionsAndroid.requestMultiple([
69
- PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
70
- PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
71
- PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS,
72
- ]);
73
- }
74
- };
75
- ```
66
+ ## 🚀 Usage Guide
76
67
 
77
- ---
68
+ ### 1. Request Permissions
78
69
 
79
- ### **Step 2: Start the Tracker**
70
+ Before starting, ensure you request the necessary runtime permissions (Location & Notifications).
80
71
 
81
- `App.js` Example:
72
+ ### 2. Implementation Example
82
73
 
83
- ```js
74
+ ```tsx
84
75
  import React, { useEffect, useState } from 'react';
85
- import { View, Text, Button } from 'react-native';
76
+ import { View, Text, Button, PermissionsAndroid, Platform } from 'react-native';
86
77
  import GeoKit from 'react-native-geo-activity-kit';
87
78
 
88
79
  const App = () => {
89
- const [status, setStatus] = useState("Unknown");
90
- const [logs, setLogs] = useState([]);
80
+ const [status, setStatus] = useState('Off');
81
+ const [logs, setLogs] = useState<string[]>([]);
91
82
 
92
83
  useEffect(() => {
93
- const motionListener = GeoKit.addMotionListener((event) => {
94
- console.log("Motion State:", event.state);
84
+ // 1. Motion State Listener (STATIONARY vs MOVING)
85
+ const motionSub = GeoKit.addMotionListener((event) => {
86
+ console.log('Motion State:', event.state);
95
87
  setStatus(event.state);
96
88
  });
97
89
 
98
- const locListener = GeoKit.addLocationLogListener((loc) => {
99
- console.log("New Location:", loc.latitude, loc.longitude);
100
- setLogs(prev => [`${loc.latitude}, ${loc.longitude}`, ...prev]);
90
+ // 2. Location Listener
91
+ const locationSub = GeoKit.addLocationLogListener((loc) => {
92
+ console.log('Location:', loc.latitude, loc.longitude);
93
+ setLogs((prev) => [
94
+ `${loc.timestamp}: ${loc.latitude}, ${loc.longitude}`,
95
+ ...prev,
96
+ ]);
97
+ });
98
+
99
+ // 3. Error Listener
100
+ const errorSub = GeoKit.addLocationErrorListener((err) => {
101
+ console.error('GeoKit Error:', err.message);
101
102
  });
102
103
 
103
104
  return () => {
104
- motionListener.remove();
105
- locListener.remove();
105
+ motionSub.remove();
106
+ locationSub.remove();
107
+ errorSub.remove();
106
108
  };
107
109
  }, []);
108
110
 
109
- const startTracking = async () => {
110
- await GeoKit.startMotionDetector(0.8);
111
+ const startService = async () => {
112
+ try {
113
+ // 1. Ask for permissions first (Standard Android Code)
114
+ if (Platform.OS === 'android') {
115
+ await PermissionsAndroid.requestMultiple([
116
+ PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
117
+ PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS,
118
+ ]);
119
+ }
120
+
121
+ // 2. Start the Foreground Service (REQUIRED for background persistence)
122
+ await GeoKit.startForegroundService(
123
+ 'Location Tracker',
124
+ 'Tracking your trips in the background...'
125
+ );
126
+
127
+ // 3. Start the Motion Detector (This activates the Smart Switch)
128
+ // Threshold 0.8 is recommended for walking/driving detection.
129
+ await GeoKit.startMotionDetector(0.8);
130
+
131
+ setStatus('Started');
132
+ } catch (e) {
133
+ console.error(e);
134
+ }
111
135
  };
112
136
 
113
- const stopTracking = () => {
114
- GeoKit.stopMotionDetector();
115
- setStatus("Stopped");
137
+ const stopService = async () => {
138
+ await GeoKit.stopMotionDetector();
139
+ await GeoKit.stopForegroundService();
140
+ setStatus('Stopped');
116
141
  };
117
142
 
118
143
  return (
119
- <View style={{ padding: 50 }}>
120
- <Text style={{ fontSize: 20 }}>Status: {status}</Text>
121
- <Button title="Start Tracking" onPress={startTracking} />
122
- <Button title="Stop Tracking" color="red" onPress={stopTracking} />
123
- {logs.map((l, i) => <Text key={i}>{l}</Text>)}
144
+ <View style={{ padding: 20 }}>
145
+ <Text style={{ fontSize: 18, marginBottom: 10 }}>Status: {status}</Text>
146
+ <Button title="Start Tracking" onPress={startService} />
147
+ <View style={{ height: 10 }} />
148
+ <Button title="Stop Tracking" color="red" onPress={stopService} />
149
+
150
+ <Text style={{ marginTop: 20, fontWeight: 'bold' }}>Logs:</Text>
151
+ {logs.map((l, i) => (
152
+ <Text key={i} style={{ fontSize: 10 }}>
153
+ {l}
154
+ </Text>
155
+ ))}
124
156
  </View>
125
157
  );
126
158
  };
@@ -130,81 +162,44 @@ export default App;
130
162
 
131
163
  ---
132
164
 
133
- ## 🎛️ Configuration Guide
134
-
135
- ### **1. Motion Sensitivity (threshold)**
136
- - Controls how much force is needed to detect MOVING.
137
- - Range: **0.1 (very sensitive) → 2.0 (hard to trigger)**
138
- - Recommended: **0.8**
139
-
140
- ### **2. Motion Check Speed (setUpdateInterval)**
141
- - How often accelerometer checks movement.
142
- - Default: **100ms**
143
-
144
- ### **3. False Positive Protection (setStabilityThresholds)**
145
- - Prevents accidental GPS ON/OFF triggers.
146
-
147
- Defaults:
148
- - **Start: 20 checks**
149
- - **Stop: 3000 checks**
150
-
151
- ### **4. GPS Frequency (setLocationUpdateInterval)**
152
- - How often GPS logs when MOVING.
153
- - Default: **90000 ms (90s)**
154
-
155
- ---
156
-
157
- ## 🔔 Native Notifications
165
+ ## 📚 API Reference
158
166
 
159
- ```js
160
- await GeoKit.fireGenericAlert(
161
- "Shift Ended",
162
- "Please mark your attendance out.",
163
- 101
164
- );
167
+ ### Service Control
165
168
 
166
- await GeoKit.fireGeofenceAlert("IN", "John Doe");
167
- await GeoKit.fireGeofenceAlert("OUT", "John Doe");
169
+ These methods control the sticky notification that keeps your app alive in the background.
168
170
 
169
- await GeoKit.cancelGenericAlert(101);
170
- ```
171
+ | Method | Description |
172
+ | ----------------------------------- | ------------------------------------------------------------------- |
173
+ | `startForegroundService(title, body)` | Starts the Android Foreground Service. Required for background tracking. |
174
+ | `stopForegroundService()` | Stops the service and removes the notification. |
175
+ | `updateServiceNotification(title, body)` | Updates the text of the running notification without restarting the service. |
171
176
 
172
177
  ---
173
178
 
174
- ## 📚 API Reference
179
+ ### Configuration & Sensors
175
180
 
176
- | Method | Description |
177
- |--------|-------------|
178
- | startMotionDetector(threshold) | Starts sensors. |
179
- | stopMotionDetector() | Stops sensors + GPS. |
180
- | setUpdateInterval(ms) | Accelerometer interval. |
181
- | setStabilityThresholds(start, stop) | Samples required to switch states. |
182
- | setLocationUpdateInterval(ms) | GPS log interval while moving. |
183
- | fireGenericAlert(title, body, id) | Push notification. |
184
- | fireGeofenceAlert(type, name) | Enter/Exit notification. |
185
- | isAvailable() | Check accelerometer availability. |
181
+ | Method | Default | Description |
182
+ | --------------------------------- | ------- | --------------------------------------------------------------------------- |
183
+ | `startMotionDetector(threshold)` | `0.8` | Starts the accelerometer and GPS logic. `threshold` = force (G) to mark MOVING. |
184
+ | `stopMotionDetector()` | - | Stops the sensors and GPS updates. |
185
+ | `setUpdateInterval(ms)` | `100` | How often the accelerometer checks for force, in milliseconds. |
186
+ | `setLocationUpdateInterval(ms)` | `90000` | How often GPS logs are captured when MOVING (90 seconds default). |
187
+ | `setStabilityThresholds(start, stop)` | `20, 3000` | `start`: consecutive checks > threshold to become MOVING; `stop`: consecutive checks < threshold to become STATIONARY. |
186
188
 
187
189
  ---
188
190
 
189
- ## Troubleshooting
190
-
191
- ### **1. Walking but no location logs?**
192
- - If Motion State = **STATIONARY**, GPS is OFF.
193
- - Shake the device to trigger MOVING.
191
+ ### 🔔 Native Notifications
194
192
 
195
- ### **2. Android 14 Crash?**
196
- Add:
193
+ These methods trigger local notifications directly from the native module, ensuring they fire even if the JS thread is busy or backgrounded.
197
194
 
198
- ```xml
199
- <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
200
- ```
201
-
202
- ### **3. Need Physical Activity permission?**
203
- ❌ **No.**
204
- Accelerometer does not require the ACTIVITY_RECOGNITION permission.
195
+ | Method | Description |
196
+ | ------------------------------ | --------------------------------------------------------------------------- |
197
+ | `fireGenericAlert(title, body, id)` | Triggers a standard push notification immediately. `id` is a unique number. |
198
+ | `fireGeofenceAlert(type, userName)` | Triggers a pre-formatted Geofence alert. `type` must be `"IN"` or `"OUT"`. |
199
+ | `cancelGenericAlert(id)` | Cancels a specific notification by its ID. |
205
200
 
206
201
  ---
207
202
 
208
203
  ## 📄 License
209
-
204
+ a
210
205
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-geo-activity-kit",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Battery-efficient location tracking with motion detection and native notifications.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",