From c08bc7ccfecb362ecc694ead7673eb223e2c4237 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 7 Mar 2019 00:48:44 +0100 Subject: [PATCH] show own location icon on a map, tweak location update filtering --- .../LocationBackgroundService.java | 36 +++--- .../securesms/map/MapActivity.java | 117 +++++++++++++----- 2 files changed, 109 insertions(+), 44 deletions(-) diff --git a/src/org/thoughtcrime/securesms/geolocation/LocationBackgroundService.java b/src/org/thoughtcrime/securesms/geolocation/LocationBackgroundService.java index 8ff367679..ac1668205 100644 --- a/src/org/thoughtcrime/securesms/geolocation/LocationBackgroundService.java +++ b/src/org/thoughtcrime/securesms/geolocation/LocationBackgroundService.java @@ -11,7 +11,6 @@ import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.util.Log; -import android.widget.Toast; /** * Created by cyberta on 06.03.19. @@ -19,7 +18,7 @@ import android.widget.Toast; public class LocationBackgroundService extends Service { - private static final int TIMEOUT = 1000 * 30; + private static final int TIMEOUT = 1000 * 15; private static final String TAG = LocationBackgroundService.class.getSimpleName(); private LocationManager locationManager = null; private static final int LOCATION_INTERVAL = 1000; @@ -71,11 +70,8 @@ public class LocationBackgroundService extends Service { } catch (Exception ex) { Log.i(TAG, "fail to remove location listners, ignore", ex); } - - } - private void requestLocationUpdate(String provider) { try { locationManager.requestLocationUpdates( @@ -132,7 +128,7 @@ public class LocationBackgroundService extends Service { @Override public void onStatusChanged(String provider, int status, Bundle extras) { - Log.e(TAG, "onStatusChanged: " + provider); + Log.e(TAG, "onStatusChanged: " + provider + " status: " + status); } @@ -157,24 +153,35 @@ public class LocationBackgroundService extends Service { // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); - boolean isSignificantlyMoreAccurate = accuracyDelta < -50; + Log.d(TAG, "accuracyDelta: " + accuracyDelta); + boolean isSignificantlyMoreAccurate = accuracyDelta > 50; boolean isSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); if (isSignificantlyMoreAccurate && isSameProvider) { return true; } - boolean isSignificantlyLessAccurate = accuracyDelta > 50; - boolean hasLocationChanged = hasLocationDistanceChanged(location, currentBestLocation); - return hasLocationChanged && !isSignificantlyLessAccurate; + boolean isMoreAccurate = accuracyDelta > 0; + double distance = distance(location, currentBestLocation); + return hasLocationChanged(distance) && isMoreAccurate || + hasLocationSignificantlyChanged(distance); + } - private boolean hasLocationDistanceChanged(Location location, Location currentBestLocation) { - return distance(location.getLatitude(), location.getLongitude(), currentBestLocation.getLatitude(), currentBestLocation.getLongitude()) > LOCATION_DISTANCE; + private boolean hasLocationSignificantlyChanged(double distance) { + return distance > 30D; } - private double distance(double startLat, double startLong, - double endLat, double endLong) { + private boolean hasLocationChanged(double distance) { + return distance > 10D; + } + + private double distance(Location location, Location currentBestLocation) { + + double startLat = location.getLatitude(); + double startLong = location.getLongitude(); + double endLat = currentBestLocation.getLatitude(); + double endLong = currentBestLocation.getLongitude(); double dLat = Math.toRadians(endLat - startLat); double dLong = Math.toRadians(endLong - startLong); @@ -187,7 +194,6 @@ public class LocationBackgroundService extends Service { double distance = EARTH_RADIUS * c * 1000; Log.d(TAG, "Distance between location updates: " + distance); - Toast.makeText(LocationBackgroundService.this, "Distance in m between location updates: " + distance , Toast.LENGTH_LONG).show(); return distance; } diff --git a/src/org/thoughtcrime/securesms/map/MapActivity.java b/src/org/thoughtcrime/securesms/map/MapActivity.java index e38487a01..907f58db1 100644 --- a/src/org/thoughtcrime/securesms/map/MapActivity.java +++ b/src/org/thoughtcrime/securesms/map/MapActivity.java @@ -1,31 +1,45 @@ package org.thoughtcrime.securesms.map; +import android.graphics.BitmapFactory; +import android.graphics.Color; import android.os.Bundle; import android.support.annotation.NonNull; import android.util.Log; -import android.widget.Toast; import org.thoughtcrime.securesms.geolocation.DcLocation; -import org.thoughtcrime.securesms.geolocation.DcLocationManager; -import com.mapbox.android.core.permissions.PermissionsListener; + import com.mapbox.android.core.permissions.PermissionsManager; +import com.mapbox.geojson.Feature; +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.geojson.Point; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.style.layers.LineLayer; +import com.mapbox.mapboxsdk.style.layers.Property; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapbox.mapboxsdk.style.layers.SymbolLayer; +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; -import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.BaseActivity; import org.thoughtcrime.securesms.R; -import java.util.List; import java.util.Observable; import java.util.Observer; -public class MapActivity extends BaseActivity implements PermissionsListener, Observer { +public class MapActivity extends BaseActivity implements Observer { + + public static final String LINE_LAYER = "line_layer"; + public static final String LINE_SOURCE = "line_source"; + public static final String MARKER_LAYER = "symbol_layer"; + public static final String MARKER_ICON = "marker_icon_id"; + public static final String MARKER_POSITION_SOURCE = "marker_position"; private static final String TAG = MapActivity.class.getSimpleName(); private MapView mapView; + private MapboxMap mapboxMap; private PermissionsManager permissionsManager; private DcLocation dcLocation; @@ -38,27 +52,20 @@ public class MapActivity extends BaseActivity implements PermissionsListener, Ob mapView = findViewById(R.id.mapView); mapView.onCreate(savedInstanceState); mapView.getMapAsync(mapboxMap -> mapboxMap.setStyle(Style.MAPBOX_STREETS, style -> { + this.mapboxMap = mapboxMap; mapboxMap.setCameraPosition(new CameraPosition.Builder() - .target(new LatLng(53.5505D, 10.001D)) + .target(new LatLng(dcLocation.getLastLocation().getLatitude(), dcLocation.getLastLocation().getLongitude())) .zoom(12) .build()); mapboxMap.getUiSettings().setLogoEnabled(false); mapboxMap.getUiSettings().setAttributionEnabled(false); - permissionsManager = new PermissionsManager(this); - - if (PermissionsManager.areLocationPermissionsGranted(this)) { - showDeviceLocation(); - } else { - permissionsManager = new PermissionsManager(this); - permissionsManager.requestLocationPermissions(this); - } - + initMapDrawings(); + showDeviceLocation(); })); dcLocation = DcLocation.getInstance(); - } @@ -106,24 +113,73 @@ public class MapActivity extends BaseActivity implements PermissionsListener, Ob permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults); } - //map sdk callbacks for the result from requesting permissions - @Override - public void onPermissionResult(boolean granted) { - if (granted) { - showDeviceLocation(); - } else { - Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show(); + private void initMapDrawings() { + if (mapboxMap == null || mapboxMap.getStyle() == null) { + return; } + Style style = mapboxMap.getStyle(); + initGeoJsonSources(style); + initLayers(style); } - @Override - public void onExplanationNeeded(List permissionsToExplain) { - // no explanation text before the permission pop up is shown + private void initGeoJsonSources(Style style) { + GeoJsonSource markerPositionSource = new GeoJsonSource(MARKER_POSITION_SOURCE); + GeoJsonSource linePositionSource = new GeoJsonSource(LINE_SOURCE); + style.addSource(markerPositionSource); + style.addSource(linePositionSource); + } + + private void initLayers(Style style) { + style.addImage(MARKER_ICON, + BitmapFactory.decodeResource( + MapActivity.this.getResources(), R.drawable.mapbox_marker_icon_default)); + style.addLayer(new SymbolLayer(MARKER_LAYER, MARKER_POSITION_SOURCE) + .withProperties(PropertyFactory.iconImage(MARKER_ICON))); + + style.addLayer(new LineLayer(LINE_LAYER, LINE_SOURCE) + .withProperties(PropertyFactory.lineCap(Property.LINE_CAP_ROUND), + PropertyFactory.lineJoin(Property.LINE_JOIN_MITER), + PropertyFactory.lineOpacity(.7f), + PropertyFactory.lineWidth(7f), + PropertyFactory.lineColor(Color.parseColor("#3bb2d0")))); } private void showDeviceLocation() { - // TODO: draw own position on map + if (this.dcLocation.getLastLocation().getProvider().equals("?")) { + return; + } + FeatureCollection featureCollection = FeatureCollection.fromFeature(Feature.fromGeometry( + Point.fromLngLat(dcLocation.getLastLocation().getLongitude(), + dcLocation.getLastLocation().getLatitude()))); + + drawPoints(featureCollection); + } + + private void drawPoints(@NonNull FeatureCollection featureCollection) { + if (mapboxMap == null || + mapboxMap.getStyle() == null || + featureCollection.features() == null || + featureCollection.features().size() == 0) { + return; + } + + Style style = mapboxMap.getStyle(); + GeoJsonSource source = (GeoJsonSource) style.getSource(MARKER_POSITION_SOURCE); + source.setGeoJson(featureCollection); + } + + private void drawLines(@NonNull FeatureCollection featureCollection) { + if (mapboxMap == null || + mapboxMap.getStyle() == null || + featureCollection.features() == null || + featureCollection.features().size() == 0) { + return; + } + + Style style = mapboxMap.getStyle(); + GeoJsonSource source = (GeoJsonSource) style.getSource(LINE_SOURCE); + source.setGeoJson(featureCollection); } @@ -131,7 +187,10 @@ public class MapActivity extends BaseActivity implements PermissionsListener, Ob public void update(Observable o, Object arg) { if (o instanceof DcLocation) { this.dcLocation = (DcLocation) o; - Log.d(TAG, "show marker on map: " + dcLocation.getLastLocation().getLatitude() + ", " + dcLocation.getLastLocation().getLongitude()); + Log.d(TAG, "show marker on map: " + + dcLocation.getLastLocation().getLatitude() + ", " + + dcLocation.getLastLocation().getLongitude()); + showDeviceLocation(); } }