Created
June 26, 2018 03:41
-
-
Save darwin-morocho/6cc5adae482a7125d5a8710016f026dd to your computer and use it in GitHub Desktop.
Modulo Nativo React Native para usar el GPS en Android
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 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