Skip to content

Commit ed18a93

Browse files
authored
fix(andorid): implement turbomodule for location manager so events works (#3789)
1 parent e8179a4 commit ed18a93

File tree

5 files changed

+141
-19
lines changed

5 files changed

+141
-19
lines changed

android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class RNMBXPackage : TurboReactPackage() {
184184
false, // needsEagerInit
185185
true, // hasConstants
186186
false, // isCxxModule
187-
false // isTurboModule
187+
isTurboModule // isTurboModule
188188
)
189189
moduleInfos[RNMBXOfflineModule.REACT_CLASS] = ReactModuleInfo(
190190
RNMBXOfflineModule.REACT_CLASS,

android/src/main/java/com/rnmapbox/rnmbx/modules/RNMBXLocationModule.kt

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.rnmapbox.rnmbx.modules
33
import com.facebook.react.bridge.*
44
import com.rnmapbox.rnmbx.location.LocationManager
55
import com.facebook.react.module.annotations.ReactModule
6+
import com.rnmapbox.rnmbx.NativeRNMBXLocationModuleSpec
67
import com.rnmapbox.rnmbx.location.LocationManager.OnUserLocationChange
78
import com.rnmapbox.rnmbx.events.LocationEvent
89
import com.rnmapbox.rnmbx.events.EventEmitter
@@ -16,7 +17,7 @@ data class LocationEventThrottle(var waitBetweenEvents: Double? = null, var last
1617

1718
@ReactModule(name = RNMBXLocationModule.REACT_CLASS)
1819
class RNMBXLocationModule(reactContext: ReactApplicationContext) :
19-
ReactContextBaseJavaModule(reactContext) {
20+
NativeRNMBXLocationModuleSpec(reactContext) {
2021
private var isEnabled = false
2122
private var mMinDisplacement = 0f
2223
private val locationManager: LocationManager? = getInstance(reactContext)
@@ -57,8 +58,12 @@ class RNMBXLocationModule(reactContext: ReactApplicationContext) :
5758
mLastLocation = location
5859
if (changed && (location != null) && shouldSendLocationEvent()) {
5960
val locationEvent = LocationEvent(location)
61+
62+
emitOnLocationUpdate(locationEvent.toJSON())
63+
/*
6064
val emitter = EventEmitter.getModuleEmitter(reactApplicationContext)
6165
emitter?.emit(LOCATION_UPDATE, locationEvent.payload)
66+
*/
6267
}
6368
}
6469
}
@@ -72,15 +77,16 @@ class RNMBXLocationModule(reactContext: ReactApplicationContext) :
7277
}
7378

7479
@ReactMethod
75-
fun start(minDisplacement: Float) {
80+
override fun start(minDisplacement: Double) {
7681
isEnabled = true
77-
mMinDisplacement = minDisplacement
82+
mMinDisplacement = minDisplacement.toFloat()
7883
locationManager?.startCounted()
7984
startLocationManager()
8085
}
8186

8287
@ReactMethod
83-
fun setMinDisplacement(minDisplacement: Float) {
88+
override fun setMinDisplacement(value: Double) {
89+
val minDisplacement = value.toFloat()
8490
if (mMinDisplacement == minDisplacement) return
8591
mMinDisplacement = minDisplacement
8692
if (isEnabled) {
@@ -91,17 +97,17 @@ class RNMBXLocationModule(reactContext: ReactApplicationContext) :
9197
}
9298

9399
@ReactMethod
94-
fun setRequestsAlwaysUse(requestsAlwaysUse: Boolean) {
100+
override fun setRequestsAlwaysUse(requestsAlwaysUse: Boolean) {
95101
// IOS only. Ignored on Android.
96102
}
97103

98104
@ReactMethod
99-
fun stop() {
105+
override fun stop() {
100106
stopLocationManager()
101107
}
102108

103109
@ReactMethod
104-
fun getLastKnownLocation(promise: Promise) {
110+
override fun getLastKnownLocation(promise: Promise) {
105111
locationManager!!.getLastKnownLocation(
106112
object : LocationEngineCallback {
107113
override fun onSuccess(result: LocationEngineResult) {
@@ -121,6 +127,10 @@ class RNMBXLocationModule(reactContext: ReactApplicationContext) :
121127
)
122128
}
123129

130+
override fun simulateHeading(changesPerSecond: Double, increment: Double) {
131+
// ios only
132+
}
133+
124134
@ReactMethod
125135
fun addListener(eventName: String?) {
126136
// Required for rn built in EventEmitter Calls.
@@ -150,10 +160,11 @@ class RNMBXLocationModule(reactContext: ReactApplicationContext) :
150160

151161
// region Location event throttle
152162
@ReactMethod
153-
fun setLocationEventThrottle(throttleValue: Double) {
163+
override fun setLocationEventThrottle(throttleValue: Double) {
154164
if (throttleValue > 0) {
155165
locationEventThrottle.waitBetweenEvents = throttleValue;
156166
} else {
167+
157168
locationEventThrottle.waitBetweenEvents = null
158169
}
159170
}
@@ -183,4 +194,4 @@ class RNMBXLocationModule(reactContext: ReactApplicationContext) :
183194
const val REACT_CLASS = "RNMBXLocationModule"
184195
const val LOCATION_UPDATE = "MapboxUserLocationUpdate"
185196
}
186-
}
197+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
2+
/**
3+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
4+
*
5+
* Do not edit this file as changes may cause incorrect behavior and will be lost
6+
* once the code is regenerated.
7+
*
8+
* @generated by codegen project: GenerateModuleJavaSpec.js
9+
*
10+
* @nolint
11+
*/
12+
13+
package com.rnmapbox.rnmbx;
14+
15+
import com.facebook.proguard.annotations.DoNotStrip;
16+
import com.facebook.react.bridge.Promise;
17+
import com.facebook.react.bridge.ReactApplicationContext;
18+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
19+
import com.facebook.react.bridge.ReactMethod;
20+
import com.facebook.react.bridge.ReactModuleWithSpec;
21+
import com.facebook.react.bridge.ReadableMap;
22+
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
23+
import javax.annotation.Nonnull;
24+
25+
public abstract class NativeRNMBXLocationModuleSpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule {
26+
public static final String NAME = "RNMBXLocationModule";
27+
28+
public NativeRNMBXLocationModuleSpec(ReactApplicationContext reactContext) {
29+
super(reactContext);
30+
}
31+
32+
@Override
33+
public @Nonnull String getName() {
34+
return NAME;
35+
}
36+
37+
protected final void emitOnLocationUpdate(ReadableMap value) {
38+
mEventEmitterCallback.invoke("onLocationUpdate", value);
39+
}
40+
41+
@ReactMethod
42+
@DoNotStrip
43+
public abstract void start(double minDisplacement);
44+
45+
@ReactMethod
46+
@DoNotStrip
47+
public abstract void stop();
48+
49+
@ReactMethod
50+
@DoNotStrip
51+
public abstract void setRequestsAlwaysUse(boolean requestsAlwaysUse);
52+
53+
@ReactMethod
54+
@DoNotStrip
55+
public abstract void setMinDisplacement(double minDisplacement);
56+
57+
@ReactMethod
58+
@DoNotStrip
59+
public abstract void getLastKnownLocation(Promise promise);
60+
61+
@ReactMethod
62+
@DoNotStrip
63+
public abstract void simulateHeading(double changesPerSecond, double increment);
64+
65+
@ReactMethod
66+
@DoNotStrip
67+
public abstract void setLocationEventThrottle(double throttle);
68+
}

src/modules/location/locationManager.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@ import {
55
NativeEventSubscription,
66
EmitterSubscription,
77
type AppStateStatus,
8-
} from 'react-native';
8+
Platform,
9+
EventSubscription,
10+
} from 'react-native'
911

10-
const MapboxGL = NativeModules.RNMBXModule;
11-
const MapboxGLLocationManager = NativeModules.RNMBXLocationModule;
12+
import NativeRNMBXLocationModule from '../../specs/NativeRNMBXLocationModule'
13+
14+
const MapboxGL = NativeModules.RNMBXModule
15+
const MapboxGLLocationManager: typeof NativeRNMBXLocationModule = Platform.select({ios: NativeModules.RNMBXLocationModule, android: NativeRNMBXLocationModule})
1216

1317
export const LocationModuleEventEmitter = new NativeEventEmitter(
14-
MapboxGLLocationManager,
18+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
19+
MapboxGLLocationManager as any,
1520
);
1621

1722
/**
@@ -74,7 +79,7 @@ export class LocationManager {
7479
_lastKnownLocation: Location | null;
7580
_isListening: boolean;
7681
_requestsAlwaysUse: boolean;
77-
subscription: EmitterSubscription | null;
82+
subscription: EmitterSubscription | EventSubscription | null;
7883
_appStateListener: NativeEventSubscription;
7984
_minDisplacement?: number;
8085

@@ -167,10 +172,16 @@ export class LocationManager {
167172
if (!this._isListening) {
168173
MapboxGLLocationManager.start(validDisplacement);
169174

170-
this.subscription = LocationModuleEventEmitter.addListener(
171-
MapboxGL.LocationCallbackName.Update,
172-
this._onUpdate,
173-
);
175+
if (Platform.OS === 'ios') {
176+
this.subscription = LocationModuleEventEmitter.addListener(
177+
MapboxGL.LocationCallbackName.Update,
178+
this._onUpdate,
179+
);
180+
} else {
181+
this.subscription = MapboxGLLocationManager.onLocationUpdate((location) => {
182+
this._onUpdate(location.payload);
183+
});
184+
}
174185

175186
this._isListening = true;
176187
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { TurboModule, TurboModuleRegistry} from "react-native";
2+
import type { EventEmitter } from 'react-native/Libraries/Types/CodegenTypes';
3+
4+
type LocationEvent = {
5+
type: string //"userlocationdupdated"
6+
payload: {
7+
coords: {
8+
latitude: number
9+
longitude: number
10+
altitude: number
11+
accuracy: number
12+
speed: number
13+
heading: number
14+
}
15+
timestamp: number
16+
}
17+
}
18+
19+
export interface Spec extends TurboModule {
20+
start(minDisplacement: number): void
21+
stop(): void
22+
setRequestsAlwaysUse(requestsAlwaysUse: boolean): void
23+
setMinDisplacement(minDisplacement: number): void
24+
getLastKnownLocation(): Promise<LocationEvent['payload']>
25+
simulateHeading(changesPerSecond: number, increment: number): void
26+
setLocationEventThrottle(throttle: number): void
27+
28+
readonly onLocationUpdate: EventEmitter<LocationEvent>
29+
}
30+
31+
export default TurboModuleRegistry.getEnforcing<Spec>('RNMBXLocationModule');
32+

0 commit comments

Comments
 (0)