Skip to content

Instantly share code, notes, and snippets.

@darwin-morocho
Created June 26, 2018 03:41
Show Gist options
  • Save darwin-morocho/6cc5adae482a7125d5a8710016f026dd to your computer and use it in GitHub Desktop.
Save darwin-morocho/6cc5adae482a7125d5a8710016f026dd to your computer and use it in GitHub Desktop.
Modulo Nativo React Native para usar el GPS en Android
package ec.dina.nearbyfind.gpsmodule;
import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
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.LocationListener;
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;
/**
* Created by DARWIN MOROCHO on 7/11/2017.
*/
public class GPSModule extends ReactContextBaseJavaModule implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ActivityEventListener {
private GoogleApiClient mGoogleApiClient;
private final int REQUEST_CHECK_SETTINGS = 10121;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 11220;
final ReactApplicationContext reactContext;
private Activity activity;
private Callback successCallBack, locationCallback;
public GPSModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
this.reactContext.addActivityEventListener(this);
//Toast.makeText(activity, "encendiendo gps", Toast.LENGTH_SHORT).show();
mGoogleApiClient = new GoogleApiClient.Builder(reactContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
@Override
public String getName() {
return "GPSAndroid";
}
@ReactMethod
public void init(final Callback successCallBack) {
activity = getCurrentActivity();
this.successCallBack = successCallBack;
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
checkGPS(successCallBack);
}
});
}
private void checkGPS(final Callback callback) {
activity = getCurrentActivity();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(10 * 60 * 1000) // every 10 minutes
.setExpirationDuration(10 * 1000) // After 10 seconds
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
// Then check whether current location settings are satisfied:
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(@NonNull LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates locationSettingsStates = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
callback.invoke("exito");
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
activity,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
callback.invoke(e.getMessage());
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
callback.invoke("error");
break;
}
}
});
}
@ReactMethod
public void getMyPosition(Callback callBack) {
this.locationCallback = callBack;
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
locationCallback.invoke("{ \"status\": \"OK\", \"location\": { \"lat\": " + latitude + ", \"lng\": " + longitude + "} }");
} else {
locationCallback.invoke("{\"status\":\"ERROR\",\"msg\":\"Couldn't get the location. Make sure location is enabled on the device\"}");
}
}
});
}
/**
* Method to verify google play services on the device
*/
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(reactContext);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, getCurrentActivity(),
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Toast.makeText(reactContext,
"This device is not supported.", Toast.LENGTH_LONG)
.show();
}
return false;
}
return true;
}
private LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
// Receive Longitude / Latitude from (updated) Last Location
double longitude = location.getLongitude();
double latitude = location.getLatitude();
double speed = location.getSpeed();
double altitude = location.getAltitude();
double accuracy = location.getAccuracy();
double course = location.getBearing();
WritableMap params = Arguments.createMap();
params.putInt("status", 200);
WritableMap responseLocation = Arguments.createMap();
responseLocation.putDouble("longitude", longitude);
responseLocation.putDouble("latitude", latitude);
responseLocation.putDouble("speed", speed);
responseLocation.putDouble("altitude", altitude);
responseLocation.putDouble("accuracy", accuracy);
responseLocation.putDouble("course", course);
params.putMap("location", responseLocation);
// Send Event to JS to update Location
sendEvent(reactContext, "locationUpdated", params);
}
};
@Override
public void onConnected(@Nullable Bundle bundle) {
}
@ReactMethod
public void startUpdatingLocation() {
if (checkPlayServices()) {
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(2000); // Update location every second
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, locationListener);
} else {
WritableMap params = Arguments.createMap();
params.putInt("status", 500);
params.putString("msg", "Google Play Service is not installed.");
}
}
@ReactMethod
public void stopUpdatingLocation() {
try {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, locationListener);
} catch (Exception e) {
Toast.makeText(reactContext, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
/**
* desconecta el ApiClient
*/
@ReactMethod
public void disconnect() {
try {
mGoogleApiClient.disconnect();
} catch (Exception e) {
Toast.makeText(reactContext, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CHECK_SETTINGS) {
if (resultCode == Activity.RESULT_OK) {
this.successCallBack.invoke("result_exito");
} else {
this.successCallBack.invoke("error");
}
}
}
@Override
public void onNewIntent(Intent intent) {
}
private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
if (reactContext.hasActiveCatalystInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment