diff --git a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl index 92115f873b..0b0466ff21 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl +++ b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl @@ -2,6 +2,7 @@ package net.osmand.aidlapi; import net.osmand.aidlapi.map.ALatLon; import net.osmand.aidlapi.map.SetMapLocationParams; +import net.osmand.aidlapi.map.SetLocationParams; import net.osmand.aidlapi.favorite.group.AFavoriteGroup; import net.osmand.aidlapi.favorite.group.AddFavoriteGroupParams; @@ -901,4 +902,6 @@ interface IOsmAndAidlInterface { boolean addRoadBlock(in AddBlockedRoadParams params); boolean removeRoadBlock(in RemoveBlockedRoadParams params); + + boolean setLocation(in SetLocationParams params); } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/map/SetLocationParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/map/SetLocationParams.aidl new file mode 100644 index 0000000000..e39726efd0 --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/map/SetLocationParams.aidl @@ -0,0 +1,3 @@ +package net.osmand.aidlapi.map; + +parcelable SetLocationParams; \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/map/SetLocationParams.java b/OsmAnd-api/src/net/osmand/aidlapi/map/SetLocationParams.java new file mode 100644 index 0000000000..167ae1d3a4 --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/map/SetLocationParams.java @@ -0,0 +1,61 @@ +package net.osmand.aidlapi.map; + +import android.os.Bundle; +import android.os.Parcel; + +import net.osmand.aidlapi.AidlParams; + +public class SetLocationParams extends AidlParams { + + private double latitude; + private double longitude; + private long timeToNotUseOtherGPS; + + public SetLocationParams(double latitude, double longitude, long timeToNotUseOtherGPS) { + this.latitude = latitude; + this.longitude = longitude; + this.timeToNotUseOtherGPS = timeToNotUseOtherGPS; + } + + public SetLocationParams(Parcel in) { + readFromParcel(in); + } + + public static final Creator CREATOR = new Creator() { + @Override + public SetLocationParams createFromParcel(Parcel in) { + return new SetLocationParams(in); + } + + @Override + public SetLocationParams[] newArray(int size) { + return new SetLocationParams[size]; + } + }; + + public double getLatitude() { + return latitude; + } + + public double getLongitude() { + return longitude; + } + + public long getTimeToNotUseOtherGPS() { + return timeToNotUseOtherGPS; + } + + @Override + public void writeToBundle(Bundle bundle) { + bundle.putDouble("latitude", latitude); + bundle.putDouble("longitude", longitude); + bundle.putLong("aidl_time_to_not_use_other_gps", timeToNotUseOtherGPS); + } + + @Override + protected void readFromBundle(Bundle bundle) { + latitude = bundle.getDouble("latitude"); + longitude = bundle.getDouble("longitude"); + timeToNotUseOtherGPS = bundle.getLong("aidl_time_to_not_use_other_gps"); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 88307a259e..3a480856fe 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -57,6 +57,7 @@ import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; +import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.SQLiteTileSource; @@ -122,6 +123,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; @@ -167,11 +170,13 @@ public class OsmandAidlApi { private static final String AIDL_REFRESH_MAP = "aidl_refresh_map"; private static final String AIDL_SET_MAP_LOCATION = "aidl_set_map_location"; + private static final String AIDL_SET_LOCATION = "aidl_set_location"; private static final String AIDL_LATITUDE = "aidl_latitude"; private static final String AIDL_LONGITUDE = "aidl_longitude"; private static final String AIDL_ZOOM = "aidl_zoom"; private static final String AIDL_ROTATION = "aidl_rotation"; private static final String AIDL_ANIMATED = "aidl_animated"; + private static final String AIDL_TIME_TO_NOT_USE_OTHER_GPS = "aidl_time_to_not_use_other_gps"; private static final String AIDL_START_NAME = "aidl_start_name"; private static final String AIDL_START_LAT = "aidl_start_lat"; @@ -232,6 +237,7 @@ public class OsmandAidlApi { private MapActivity mapActivity; private boolean mapActivityActive = false; + private boolean hasCustomLocation = false; public OsmandAidlApi(OsmandApplication app) { this.app = app; @@ -263,6 +269,7 @@ public class OsmandAidlApi { registerHideSqliteDbFileReceiver(mapActivity); registerExecuteQuickActionReceiver(mapActivity); registerLockStateReceiver(mapActivity); + registerSetLocationReceiver(mapActivity); initOsmandTelegram(); app.getAppCustomization().addListener(mapActivity); this.mapActivity = mapActivity; @@ -903,6 +910,50 @@ public class OsmandAidlApi { registerReceiver(lockStateReceiver, mapActivity, AIDL_LOCK_STATE); } + private void registerSetLocationReceiver(MapActivity mapActivity) { + final WeakReference mapActivityRef = new WeakReference<>(mapActivity); + BroadcastReceiver setLocationReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final MapActivity mapActivity = mapActivityRef.get(); + if (mapActivity == null) { + return; + } + + double lat = intent.getDoubleExtra(AIDL_LATITUDE, Double.NaN); + double lon = intent.getDoubleExtra(AIDL_LONGITUDE, Double.NaN); + long timeToNotUseOtherGPS = intent.getLongExtra(AIDL_TIME_TO_NOT_USE_OTHER_GPS, 0); + + if (!Double.isNaN(lat) && !Double.isNaN(lon)) { + mapActivity.setMapLocation(lat, lon); + mapActivity.refreshMap(); + hasCustomLocation = true; + net.osmand.Location location = new net.osmand.Location("OsmAnd", lat, lon); + app.getLocationProvider().setCustomLocation(location); + } + + final OsmAndLocationProvider.OsmAndLocationListener listener = new OsmAndLocationProvider.OsmAndLocationListener() { + @Override + public void updateLocation(Location location) { + mapActivity.setMapLocation(location.getLatitude(), location.getLongitude()); + mapActivity.refreshMap(); + } + }; + + new Timer().schedule(new TimerTask() { + @Override + public void run() { + if (app.getLocationProvider() != null) { + hasCustomLocation = false; + app.getLocationProvider().addLocationListener(listener); + } + } + }, timeToNotUseOtherGPS); + } + }; + registerReceiver(setLocationReceiver, mapActivity, AIDL_SET_LOCATION); + } + public void registerMapLayers(@NonNull MapActivity mapActivity) { for (ConnectedApp connectedApp : connectedApps.values()) { connectedApp.registerMapLayers(mapActivity); @@ -2405,6 +2456,20 @@ public class OsmandAidlApi { return true; } + public boolean setLocation(double latitude, double longitude, long timeToNotUseOtherGPS) { + Intent intent = new Intent(); + intent.setAction(AIDL_SET_LOCATION); + intent.putExtra(AIDL_LATITUDE, latitude); + intent.putExtra(AIDL_LONGITUDE, longitude); + intent.putExtra(AIDL_TIME_TO_NOT_USE_OTHER_GPS, timeToNotUseOtherGPS); + app.sendBroadcast(intent); + return true; + } + + public boolean hasCustomLocation() { + return hasCustomLocation; + } + private static class FileCopyInfo { long startTime; long lastAccessTime; diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java index 5fa2f75421..4384a8ac85 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java @@ -53,6 +53,7 @@ import net.osmand.aidlapi.gpx.StopGpxRecordingParams; import net.osmand.aidlapi.info.AppInfoParams; import net.osmand.aidlapi.lock.SetLockStateParams; import net.osmand.aidlapi.map.ALatLon; +import net.osmand.aidlapi.map.SetLocationParams; import net.osmand.aidlapi.map.SetMapLocationParams; import net.osmand.aidlapi.maplayer.AddMapLayerParams; import net.osmand.aidlapi.maplayer.RemoveMapLayerParams; @@ -1443,6 +1444,20 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener } return false; } + + @Override + public boolean setLocation(SetLocationParams params) { + try { + if (params != null) { + OsmandAidlApi api = getApi("setLocation"); + return api != null && api.setLocation(params.getLatitude(), + params.getLongitude(), params.getTimeToNotUseOtherGPS()); + } + } catch (Exception e) { + handleException(e); + } + return false; + } }; private void setCustomization(OsmandAidlApi api, CustomizationInfoParams params) { diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java index a19ebd3023..32f2b4ee8b 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java @@ -796,6 +796,9 @@ public class OsmAndLocationProvider implements SensorEventListener { if (locationSimulation.isRouteAnimating()) { return; } + if (app.getAidlApi().hasCustomLocation() && isNotSimulatedLocation(location)) { + return; + } if (location != null) { notifyGpsLocationRecovered(); } @@ -812,10 +815,13 @@ public class OsmAndLocationProvider implements SensorEventListener { setLocation(location); } - private void setLocation(net.osmand.Location location) { if (location == null) { + private void setLocation(net.osmand.Location location) { + if (location == null) { updateGPSInfo(null); } - + if (app.getAidlApi().hasCustomLocation() && isNotSimulatedLocation(location)) { + return; + } if (location != null) { // // use because there is a bug on some devices with location.getTime() lastTimeLocationFixed = System.currentTimeMillis(); @@ -850,6 +856,22 @@ public class OsmAndLocationProvider implements SensorEventListener { updateLocation(this.location); } + public void setCustomLocation(net.osmand.Location location) { + if (locationSimulation.isRouteAnimating()) { + return; + } + if (location != null) { + notifyGpsLocationRecovered(); + } + // notify about lost location + scheduleCheckIfGpsLost(location); + + app.getSavingTrackHelper().updateLocation(location, heading); + OsmandPlugin.updateLocationPlugins(location); + app.getRoutingHelper().updateLocation(location); + app.getWaypointHelper().locationChanged(location); + } + private void notifyGpsLocationRecovered() { if (gpsSignalLost) { gpsSignalLost = false;