Created
December 25, 2017 06:18
-
-
Save pewh/1fd64c8f0b3797ef2b7a7046b5a5f974 to your computer and use it in GitHub Desktop.
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
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)); | |
} | |
} |
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
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