Created
March 27, 2020 13:06
-
-
Save exelban/67020d6f1de0dc9edb93056bec83e493 to your computer and use it in GitHub Desktop.
Fused Location Provider for Capacitor
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 com.getcapacitor.plugin; | |
import android.Manifest; | |
import android.content.pm.PackageManager; | |
import android.location.Location; | |
import android.os.Looper; | |
import com.getcapacitor.JSObject; | |
import com.getcapacitor.NativePlugin; | |
import com.getcapacitor.Plugin; | |
import com.getcapacitor.PluginCall; | |
import com.getcapacitor.PluginMethod; | |
import com.getcapacitor.PluginRequestCodes; | |
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 java.util.HashMap; | |
import java.util.Map; | |
/** | |
* Geolocation plugin that uses the native location service instead of the browser API. | |
* | |
* https://developer.android.com/guide/topics/location/strategies.html | |
*/ | |
@NativePlugin( | |
permissions={ | |
Manifest.permission.ACCESS_COARSE_LOCATION, | |
Manifest.permission.ACCESS_FINE_LOCATION | |
}, | |
permissionRequestCode = PluginRequestCodes.GEOLOCATION_REQUEST_PERMISSIONS | |
) | |
public class Geolocation extends Plugin { | |
Map<String, PluginCall> watchingCalls = new HashMap<>(); | |
private FusedLocationProviderClient mFusedLocationClient; | |
private LocationRequest mLocationRequest; | |
protected Location mLastLocation; | |
LocationCallback locationCallback; | |
@PluginMethod() | |
public void getCurrentPosition(PluginCall call) { | |
if (!hasRequiredPermissions()) { | |
saveCall(call); | |
pluginRequestAllPermissions(); | |
} else { | |
requestLocationUpdates(call); | |
clearLocationUpdates(); | |
} | |
} | |
@PluginMethod(returnType=PluginMethod.RETURN_CALLBACK) | |
public void watchPosition(PluginCall call) { | |
call.save(); | |
if (!hasRequiredPermissions()) { | |
saveCall(call); | |
pluginRequestAllPermissions(); | |
} else { | |
startWatch(call); | |
} | |
} | |
@SuppressWarnings("MissingPermission") | |
private void startWatch(PluginCall call) { | |
requestLocationUpdates(call); | |
watchingCalls.put(call.getCallbackId(), call); | |
} | |
@SuppressWarnings("MissingPermission") | |
@PluginMethod() | |
public void clearWatch(PluginCall call) { | |
String callbackId = call.getString("id"); | |
if (callbackId != null) { | |
PluginCall removed = watchingCalls.remove(callbackId); | |
if (removed != null) { | |
removed.release(bridge); | |
} | |
} | |
if (watchingCalls.size() == 0) { | |
clearLocationUpdates(); | |
} | |
call.success(); | |
} | |
private void requestLocationUpdates(final PluginCall call) { | |
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(getContext()); | |
mLocationRequest = new LocationRequest(); | |
mLocationRequest.setInterval(7500); | |
mLocationRequest.setFastestInterval(5000); | |
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); | |
locationCallback = new LocationCallback(){ | |
@Override | |
public void onLocationResult(LocationResult locationResult) { | |
for (Location location : locationResult.getLocations()) { | |
if (location == null) { | |
call.success(); | |
} else { | |
call.success(getJSObjectForLocation(location)); | |
} | |
} | |
} | |
}; | |
mFusedLocationClient.requestLocationUpdates(mLocationRequest, locationCallback, Looper.myLooper()); | |
} | |
private void clearLocationUpdates() { | |
mFusedLocationClient.removeLocationUpdates(locationCallback); | |
} | |
@Override | |
protected void handleRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { | |
super.handleRequestPermissionsResult(requestCode, permissions, grantResults); | |
PluginCall savedCall = getSavedCall(); | |
if (savedCall == null) { | |
return; | |
} | |
for(int result : grantResults) { | |
if (result == PackageManager.PERMISSION_DENIED) { | |
savedCall.error("User denied location permission"); | |
return; | |
} | |
} | |
if (savedCall.getMethodName().equals("getCurrentPosition")) { | |
requestLocationUpdates(savedCall); | |
clearLocationUpdates(); | |
} else { | |
startWatch(savedCall); | |
} | |
} | |
private JSObject getJSObjectForLocation(Location location) { | |
JSObject ret = new JSObject(); | |
JSObject coords = new JSObject(); | |
ret.put("coords", coords); | |
coords.put("latitude", location.getLatitude()); | |
coords.put("longitude", location.getLongitude()); | |
coords.put("altitude", location.getAltitude()); | |
coords.put("speed", location.getSpeed()); | |
coords.put("heading", location.getBearing()); | |
return ret; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To use fuse location plugin as geolocation service with a capacitor you need to do 2 steps:
implementation 'com.google.android.gms:play-services-location:16.0.0'
to capacitor-androidbuild.grande
in section dependencies