-
-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow using google location engine on Android (#586)
- Loading branch information
1 parent
3a4c038
commit 92ffdb7
Showing
10 changed files
with
273 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,12 @@ | ||
MapLibreReactNative_kotlinVersion=1.7.0 | ||
MapLibreReactNative_minSdkVersion=21 | ||
MapLibreReactNative_targetSdkVersion=31 | ||
MapLibreReactNative_compileSdkVersion=31 | ||
MapLibreReactNative_ndkversion=21.4.7075529 | ||
org.maplibre.reactnative.kotlinVersion=1.7.0 | ||
org.maplibre.reactnative.minSdkVersion=21 | ||
org.maplibre.reactnative.targetSdkVersion=31 | ||
org.maplibre.reactnative.compileSdkVersion=31 | ||
org.maplibre.reactnative.ndkVersion=21.4.7075529 | ||
|
||
MapLibreReactNative_okhttpVersion=4.9.0 | ||
# MapLibre React Native Customizations | ||
|
||
org.maplibre.reactnative.okhttpVersion=4.9.0 | ||
|
||
# Available values: default, google | ||
org.maplibre.reactnative.locationEngine=default |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
...src/main/java/org/maplibre/reactnative/location/engine/DefaultLocationEngineProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.maplibre.reactnative.location.engine; | ||
|
||
import android.content.Context; | ||
import android.util.Log; | ||
|
||
import org.maplibre.android.location.engine.LocationEngine; | ||
import org.maplibre.android.location.engine.LocationEngineDefault; | ||
|
||
public class DefaultLocationEngineProvider implements LocationEngineProvidable { | ||
private static final String LOG_TAG = "DefaultLocationEngineProvider"; | ||
|
||
@Override | ||
public LocationEngine getLocationEngine(Context context) { | ||
LocationEngine locationEngine = LocationEngineDefault.INSTANCE.getDefaultLocationEngine(context.getApplicationContext()); | ||
Log.d(LOG_TAG, "DefaultLocationEngine will be used."); | ||
return locationEngine; | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
android/src/main/java/org/maplibre/reactnative/location/engine/LocationEngineProvidable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.maplibre.reactnative.location.engine; | ||
|
||
import android.content.Context; | ||
|
||
import org.maplibre.android.location.engine.LocationEngine; | ||
|
||
public interface LocationEngineProvidable { | ||
LocationEngine getLocationEngine(Context context); | ||
} |
12 changes: 12 additions & 0 deletions
12
...ation-engine-default/org/maplibre/reactnative/location/engine/LocationEngineProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.maplibre.reactnative.location.engine; | ||
|
||
import android.content.Context; | ||
|
||
import org.maplibre.android.location.engine.LocationEngine; | ||
|
||
public class LocationEngineProvider implements LocationEngineProvidable { | ||
@Override | ||
public LocationEngine getLocationEngine(Context context) { | ||
return new DefaultLocationEngineProvider().getLocationEngine(context); | ||
} | ||
} |
151 changes: 151 additions & 0 deletions
151
...tion-engine-google/org/maplibre/reactnative/location/engine/GoogleLocationEngineImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package org.maplibre.reactnative.location.engine; | ||
|
||
import android.annotation.SuppressLint; | ||
import android.app.PendingIntent; | ||
import android.content.Context; | ||
import android.location.Location; | ||
import android.os.Looper; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.annotation.VisibleForTesting; | ||
|
||
import com.google.android.gms.location.FusedLocationProviderClient; | ||
import com.google.android.gms.location.LocationCallback; | ||
import com.google.android.gms.location.LocationRequest; | ||
import com.google.android.gms.location.LocationResult; | ||
import com.google.android.gms.location.LocationServices; | ||
import com.google.android.gms.location.Priority; | ||
import com.google.android.gms.tasks.OnFailureListener; | ||
import com.google.android.gms.tasks.OnSuccessListener; | ||
|
||
import org.maplibre.android.location.engine.LocationEngineCallback; | ||
import org.maplibre.android.location.engine.LocationEngineImpl; | ||
import org.maplibre.android.location.engine.LocationEngineRequest; | ||
import org.maplibre.android.location.engine.LocationEngineResult; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
/** | ||
* Wraps implementation of Fused Location Provider | ||
*/ | ||
public class GoogleLocationEngineImpl implements LocationEngineImpl<LocationCallback> { | ||
private final FusedLocationProviderClient fusedLocationProviderClient; | ||
|
||
@VisibleForTesting | ||
GoogleLocationEngineImpl(FusedLocationProviderClient fusedLocationProviderClient) { | ||
this.fusedLocationProviderClient = fusedLocationProviderClient; | ||
} | ||
|
||
public GoogleLocationEngineImpl(@NonNull Context context) { | ||
this.fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context); | ||
} | ||
|
||
@NonNull | ||
@Override | ||
public LocationCallback createListener(LocationEngineCallback<LocationEngineResult> callback) { | ||
return new GoogleLocationEngineCallbackTransport(callback); | ||
} | ||
|
||
@SuppressLint("MissingPermission") | ||
@Override | ||
public void getLastLocation(@NonNull LocationEngineCallback<LocationEngineResult> callback) | ||
throws SecurityException { | ||
GoogleLastLocationEngineCallbackTransport transport = | ||
new GoogleLastLocationEngineCallbackTransport(callback); | ||
fusedLocationProviderClient.getLastLocation().addOnSuccessListener(transport).addOnFailureListener(transport); | ||
} | ||
|
||
@SuppressLint("MissingPermission") | ||
@Override | ||
public void requestLocationUpdates(@NonNull LocationEngineRequest request, | ||
@NonNull LocationCallback listener, | ||
@Nullable Looper looper) throws SecurityException { | ||
fusedLocationProviderClient.requestLocationUpdates(toGMSLocationRequest(request), listener, looper); | ||
} | ||
|
||
@SuppressLint("MissingPermission") | ||
@Override | ||
public void requestLocationUpdates(@NonNull LocationEngineRequest request, | ||
@NonNull PendingIntent pendingIntent) throws SecurityException { | ||
fusedLocationProviderClient.requestLocationUpdates(toGMSLocationRequest(request), pendingIntent); | ||
} | ||
|
||
@Override | ||
public void removeLocationUpdates(@NonNull LocationCallback listener) { | ||
if (listener != null) { | ||
fusedLocationProviderClient.removeLocationUpdates(listener); | ||
} | ||
} | ||
|
||
@Override | ||
public void removeLocationUpdates(PendingIntent pendingIntent) { | ||
if (pendingIntent != null) { | ||
fusedLocationProviderClient.removeLocationUpdates(pendingIntent); | ||
} | ||
} | ||
|
||
private static LocationRequest toGMSLocationRequest(LocationEngineRequest request) { | ||
LocationRequest.Builder builder = new LocationRequest.Builder(request.getInterval()); | ||
builder.setMinUpdateIntervalMillis(request.getFastestInterval()); | ||
builder.setMinUpdateDistanceMeters(request.getDisplacement()); | ||
builder.setMaxUpdateDelayMillis(request.getMaxWaitTime()); | ||
builder.setPriority(toGMSLocationPriority(request.getPriority())); | ||
return builder.build(); | ||
} | ||
|
||
private static int toGMSLocationPriority(int enginePriority) { | ||
switch (enginePriority) { | ||
case LocationEngineRequest.PRIORITY_HIGH_ACCURACY: | ||
return Priority.PRIORITY_HIGH_ACCURACY; | ||
case LocationEngineRequest.PRIORITY_BALANCED_POWER_ACCURACY: | ||
return Priority.PRIORITY_BALANCED_POWER_ACCURACY; | ||
case LocationEngineRequest.PRIORITY_LOW_POWER: | ||
return Priority.PRIORITY_LOW_POWER; | ||
case LocationEngineRequest.PRIORITY_NO_POWER: | ||
default: | ||
return Priority.PRIORITY_PASSIVE; | ||
} | ||
} | ||
|
||
private static final class GoogleLocationEngineCallbackTransport extends LocationCallback { | ||
private final LocationEngineCallback<LocationEngineResult> callback; | ||
|
||
GoogleLocationEngineCallbackTransport(LocationEngineCallback<LocationEngineResult> callback) { | ||
this.callback = callback; | ||
} | ||
|
||
@Override | ||
public void onLocationResult(LocationResult locationResult) { | ||
super.onLocationResult(locationResult); | ||
List<Location> locations = locationResult.getLocations(); | ||
if (!locations.isEmpty()) { | ||
callback.onSuccess(LocationEngineResult.create(locations)); | ||
} else { | ||
callback.onFailure(new Exception("Unavailable location")); | ||
} | ||
} | ||
} | ||
|
||
@VisibleForTesting | ||
static final class GoogleLastLocationEngineCallbackTransport | ||
implements OnSuccessListener<Location>, OnFailureListener { | ||
private final LocationEngineCallback<LocationEngineResult> callback; | ||
|
||
GoogleLastLocationEngineCallbackTransport(LocationEngineCallback<LocationEngineResult> callback) { | ||
this.callback = callback; | ||
} | ||
|
||
@Override | ||
public void onSuccess(Location location) { | ||
callback.onSuccess(location != null ? LocationEngineResult.create(location) : | ||
LocationEngineResult.create(Collections.<Location>emptyList())); | ||
} | ||
|
||
@Override | ||
public void onFailure(@NonNull Exception e) { | ||
callback.onFailure(e); | ||
} | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
...-engine-google/org/maplibre/reactnative/location/engine/GoogleLocationEngineProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package org.maplibre.reactnative.location.engine; | ||
|
||
import android.content.Context; | ||
import android.util.Log; | ||
|
||
import com.google.android.gms.common.ConnectionResult; | ||
import com.google.android.gms.common.GoogleApiAvailability; | ||
|
||
import org.maplibre.android.location.engine.LocationEngine; | ||
import org.maplibre.android.location.engine.LocationEngineProxy; | ||
|
||
public class GoogleLocationEngineProvider implements LocationEngineProvidable { | ||
private static final String LOG_TAG = "GoogleLocationEngineProvider"; | ||
|
||
public LocationEngine getLocationEngine(Context context) { | ||
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS) { | ||
LocationEngine locationEngine = new LocationEngineProxy<>(new GoogleLocationEngineImpl(context.getApplicationContext())); | ||
Log.d(LOG_TAG, "GoogleLocationEngine will be used."); | ||
return locationEngine; | ||
} else { | ||
return new DefaultLocationEngineProvider().getLocationEngine(context); | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
...cation-engine-google/org/maplibre/reactnative/location/engine/LocationEngineProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.maplibre.reactnative.location.engine; | ||
|
||
import android.content.Context; | ||
|
||
import org.maplibre.android.location.engine.LocationEngine; | ||
|
||
public class LocationEngineProvider implements LocationEngineProvidable { | ||
@Override | ||
public LocationEngine getLocationEngine(Context context) { | ||
return new GoogleLocationEngineProvider().getLocationEngine(context); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters