Skip to content

Instantly share code, notes, and snippets.

@pewh
Created December 25, 2017 06:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pewh/1fd64c8f0b3797ef2b7a7046b5a5f974 to your computer and use it in GitHub Desktop.
Save pewh/1fd64c8f0b3797ef2b7a7046b5a5f974 to your computer and use it in GitHub Desktop.
package id.xyz.libraries;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
import com.facebook.react.bridge.Promise;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import android.location.Criteria;
import android.location.LocationManager;
import android.location.Location;
import java.util.List;
import android.content.Context;
public class RNAndroidLocationHelperModule extends ReactContextBaseJavaModule implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private final ReactApplicationContext reactContext;
public RNAndroidLocationHelperModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
public GoogleApiClient googleApiClient;
@Override
public String getName() {
return "RNAndroidLocationHelper";
}
// getCurrentPosition()
@ReactMethod
public void getCurrentPosition(Callback successCallback, Callback errorCallback){
Location l = RNAndroidLocationListener.getBestLastKnownPosition(this.getReactApplicationContext());
if (l == null){
errorCallback.invoke("Failed to retrieve current location");
return;
}
successCallback.invoke(locationToMap(l));
}
private static WritableMap locationToMap(Location location) {
WritableMap map = Arguments.createMap();
WritableMap coords = Arguments.createMap();
coords.putDouble("latitude", location.getLatitude());
coords.putDouble("longitude", location.getLongitude());
coords.putDouble("altitude", location.getAltitude());
coords.putDouble("accuracy", location.getAccuracy());
coords.putDouble("heading", location.getBearing());
coords.putDouble("speed", location.getSpeed());
map.putMap("coords", coords);
map.putDouble("timestamp", location.getTime());
map.putString("provider", location.getProvider());
if (android.os.Build.VERSION.SDK_INT >= 18) {
map.putBoolean("mocked", location.isFromMockProvider());
}
return map;
}
private static class LocationOptions {
private final long timeout;
private final double maximumAge;
private final boolean highAccuracy;
private final float distanceFilter;
private LocationOptions(
long timeout,
double maximumAge,
boolean highAccuracy,
float distanceFilter) {
this.timeout = timeout;
this.maximumAge = maximumAge;
this.highAccuracy = highAccuracy;
this.distanceFilter = distanceFilter;
}
private static LocationOptions fromReactMap(ReadableMap map) {
// precision might be dropped on timeout (double -> int conversion), but that's OK
long timeout =
map.hasKey("timeout") ? (long) map.getDouble("timeout") : Long.MAX_VALUE;
double maximumAge =
map.hasKey("maximumAge") ? map.getDouble("maximumAge") : Double.POSITIVE_INFINITY;
boolean highAccuracy =
map.hasKey("enableHighAccuracy") && map.getBoolean("enableHighAccuracy");
float distanceFilter = map.hasKey("distanceFilter") ?
(float) map.getDouble("distanceFilter") :
10;
return new LocationOptions(timeout, maximumAge, highAccuracy, distanceFilter);
}
}
@ReactMethod
public void watchPosition(ReadableMap options, Callback successCallback, Callback errorCallback){
LocationOptions opts = LocationOptions.fromReactMap(options);
LocationManager locationManager = (LocationManager)this.getReactApplicationContext().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
if (opts.highAccuracy) {
criteria.setAccuracy(Criteria.ACCURACY_FINE);
}
String bestProvider = locationManager.getBestProvider(criteria, true);
locationManager.requestLocationUpdates(bestProvider, 1000, opts.distanceFilter, this);
}
@Override
public void onLocationChanged(Location location) {
if (location == null) return;
this.getReactApplicationContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("locationChanged", locationToMap(location));
}
}
package id.xyz.libraries;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
import com.facebook.react.bridge.Promise;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import android.location.Criteria;
import android.location.LocationManager;
import android.location.Location;
import java.util.List;
import android.content.Context;
import android.location.LocationListener;
public class RNAndroidLocationListener implements LocationListener {
// private final ReactApplicationContext reactContext;
// public RNAndroidLocationHelperModule(ReactApplicationContext reactContext) {
// super(reactContext);
// this.reactContext = reactContext;
// }
// getCurrentPosition()
public Location getBestLastKnownPosition(Context context) {
LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
List<String> providers = locationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
Location l = locationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
// Found best last known location: %s", l);
bestLocation = l;
}
}
if (bestLocation == null) {
locationManager.requestSingleUpdate(new Criteria(), this, null);
}
return bestLocation;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment