1
+ package org .maplibre .maplibregl ;
2
+
3
+ import android .annotation .SuppressLint ;
4
+ import android .app .PendingIntent ;
5
+ import android .content .Context ;
6
+ import android .location .Location ;
7
+ import android .location .LocationListener ;
8
+ import android .location .LocationManager ;
9
+ import android .os .Bundle ;
10
+ import android .os .Looper ;
11
+ import android .util .Log ;
12
+
13
+ import androidx .annotation .NonNull ;
14
+ import androidx .annotation .Nullable ;
15
+ import androidx .annotation .VisibleForTesting ;
16
+
17
+ import org .maplibre .android .location .engine .LocationEngineCallback ;
18
+ import org .maplibre .android .location .engine .LocationEngineRequest ;
19
+ import org .maplibre .android .location .engine .LocationEngineResult ;
20
+ import org .maplibre .android .location .engine .LocationEngineImpl ;
21
+
22
+
23
+ public class MapLibreGPSLocationEngine implements LocationEngineImpl <LocationListener > {
24
+ private static final String TAG = "GPSLocationEngine" ;
25
+ final LocationManager locationManager ;
26
+
27
+ String currentProvider = LocationManager .PASSIVE_PROVIDER ;
28
+
29
+ public MapLibreGPSLocationEngine (@ NonNull Context context ) {
30
+ locationManager = (LocationManager ) context .getSystemService (Context .LOCATION_SERVICE );
31
+ }
32
+
33
+ @ NonNull
34
+ @ Override
35
+ public LocationListener createListener (LocationEngineCallback <LocationEngineResult > callback ) {
36
+ return new AndroidLocationEngineCallbackTransport (callback );
37
+ }
38
+
39
+ @ Override
40
+ public void getLastLocation (@ NonNull LocationEngineCallback <LocationEngineResult > callback )
41
+ throws SecurityException {
42
+ Location lastLocation = getLastLocationFor (currentProvider );
43
+ if (lastLocation != null ) {
44
+ callback .onSuccess (LocationEngineResult .create (lastLocation ));
45
+ return ;
46
+ }
47
+
48
+ for (String provider : locationManager .getAllProviders ()) {
49
+ lastLocation = getLastLocationFor (provider );
50
+ if (lastLocation != null ) {
51
+ callback .onSuccess (LocationEngineResult .create (lastLocation ));
52
+ return ;
53
+ }
54
+ }
55
+ callback .onFailure (new Exception ("Last location unavailable" ));
56
+ }
57
+
58
+ @ SuppressLint ("MissingPermission" )
59
+ Location getLastLocationFor (String provider ) throws SecurityException {
60
+ Location location = null ;
61
+ try {
62
+ location = locationManager .getLastKnownLocation (provider );
63
+ } catch (IllegalArgumentException iae ) {
64
+ Log .e (TAG , iae .toString ());
65
+ }
66
+ return location ;
67
+ }
68
+
69
+ @ SuppressLint ("MissingPermission" )
70
+ @ Override
71
+ public void requestLocationUpdates (@ NonNull LocationEngineRequest request ,
72
+ @ NonNull LocationListener listener ,
73
+ @ Nullable Looper looper ) throws SecurityException {
74
+ currentProvider = getBestProvider (request .getPriority ());
75
+ locationManager .requestLocationUpdates (currentProvider , request .getInterval (), request .getDisplacement (),
76
+ listener , looper );
77
+ }
78
+
79
+ @ SuppressLint ("MissingPermission" )
80
+ @ Override
81
+ public void requestLocationUpdates (@ NonNull LocationEngineRequest request ,
82
+ @ NonNull PendingIntent pendingIntent ) throws SecurityException {
83
+ currentProvider = getBestProvider (request .getPriority ());
84
+ locationManager .requestLocationUpdates (currentProvider , request .getInterval (),
85
+ request .getDisplacement (), pendingIntent );
86
+ }
87
+
88
+ @ SuppressLint ("MissingPermission" )
89
+ @ Override
90
+ public void removeLocationUpdates (@ NonNull LocationListener listener ) {
91
+ if (listener != null ) {
92
+ locationManager .removeUpdates (listener );
93
+ }
94
+ }
95
+
96
+ @ Override
97
+ public void removeLocationUpdates (PendingIntent pendingIntent ) {
98
+ if (pendingIntent != null ) {
99
+ locationManager .removeUpdates (pendingIntent );
100
+ }
101
+ }
102
+
103
+ private String getBestProvider (int priority ) {
104
+ String provider = null ;
105
+ if (priority != LocationEngineRequest .PRIORITY_NO_POWER ) {
106
+ provider = LocationManager .GPS_PROVIDER ;
107
+ }
108
+ return provider != null ? provider : LocationManager .PASSIVE_PROVIDER ;
109
+ }
110
+
111
+
112
+ @ VisibleForTesting
113
+ static final class AndroidLocationEngineCallbackTransport implements LocationListener {
114
+ private final LocationEngineCallback <LocationEngineResult > callback ;
115
+
116
+ AndroidLocationEngineCallbackTransport (LocationEngineCallback <LocationEngineResult > callback ) {
117
+ this .callback = callback ;
118
+ }
119
+
120
+ @ Override
121
+ public void onLocationChanged (Location location ) {
122
+ callback .onSuccess (LocationEngineResult .create (location ));
123
+ }
124
+
125
+ @ Override
126
+ public void onStatusChanged (String s , int i , Bundle bundle ) {
127
+ // noop
128
+ }
129
+
130
+ @ Override
131
+ public void onProviderEnabled (String s ) {
132
+ // noop
133
+ }
134
+
135
+ @ Override
136
+ public void onProviderDisabled (String s ) {
137
+ callback .onFailure (new Exception ("Current provider disabled" ));
138
+ }
139
+ }
140
+ }
0 commit comments