diff --git a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/mappicker/MapPickerActivity.java b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/mappicker/MapPickerActivity.java
index 4073757..46aa7c3 100644
--- a/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/mappicker/MapPickerActivity.java
+++ b/app/src/main/java/it/danieleverducci/nextcloudmaps/activity/mappicker/MapPickerActivity.java
@@ -1,19 +1,25 @@
package it.danieleverducci.nextcloudmaps.activity.mappicker;
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.Location;
+import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.app.ActivityCompat;
import androidx.preference.PreferenceManager;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.api.IMapController;
import org.osmdroid.config.Configuration;
import org.osmdroid.config.IConfigurationProvider;
-import org.osmdroid.events.MapEventsReceiver;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
import org.osmdroid.events.ZoomEvent;
@@ -21,7 +27,8 @@ import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.CustomZoomButtonsController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.Projection;
-import org.osmdroid.views.overlay.MapEventsOverlay;
+
+import java.util.Locale;
import it.danieleverducci.nextcloudmaps.BuildConfig;
import it.danieleverducci.nextcloudmaps.R;
@@ -29,8 +36,11 @@ import it.danieleverducci.nextcloudmaps.databinding.ActivityMapPickerBinding;
public class MapPickerActivity extends AppCompatActivity {
public static final String TAG = "MapPickerActivity";
+ private static final int PERMISSION_REQUEST_CODE = 8888;
+
private ViewHolder mViewHolder;
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -42,12 +52,35 @@ public class MapPickerActivity extends AppCompatActivity {
osmdroidConfig.setUserAgentValue(BuildConfig.APPLICATION_ID);
mViewHolder = new MapPickerActivity.ViewHolder(getLayoutInflater());
+ Location l = getLastKnownPosition();
+ if (l != null)
+ mViewHolder.centerMapOn(l.getLatitude(), l.getLongitude());
+
setContentView(mViewHolder.getRootView());
}
+ /**
+ * May return last known GPS position or null. Used to center the map.
+ * @return last known GPS position or null
+ */
+ private Location getLastKnownPosition() {
+ // Check if user granted location permission
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ // User didn't grant permission. Ask it.
+ requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_CODE);
+ return null;
+ }
+
+ LocationManager locationManager = (LocationManager)
+ getSystemService(Context.LOCATION_SERVICE);
+ // Try to use last available location
+ return locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
+ }
+
private class ViewHolder implements View.OnClickListener {
private final ActivityMapPickerBinding binding;
private final MapView map;
+ private boolean coordsEditMode = false;
public ViewHolder(LayoutInflater inflater) {
this.binding = ActivityMapPickerBinding.inflate(inflater);
@@ -59,7 +92,7 @@ public class MapPickerActivity extends AppCompatActivity {
if (!focused)
return;
- (ViewHolder.this).binding.latlonConfirmBtn.setVisibility(View.VISIBLE);
+ (ViewHolder.this).coordsEditMode(true);
}
};
this.binding.latEt.setOnFocusChangeListener(latlonFocusListener);
@@ -69,16 +102,17 @@ public class MapPickerActivity extends AppCompatActivity {
this.map = this.binding.map;
this.map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
this.map.setMultiTouchControls(true);
- IMapController mapController = binding.map.getController();
- mapController.setZoom(7.0f);
this.map.addMapListener(new MapListener() {
@Override
public boolean onScroll(ScrollEvent event) {
+ // Disable edit mode
+ if ((ViewHolder.this).coordsEditMode)
+ (ViewHolder.this).coordsEditMode(false);
// Convert XY coords to LatLng
Projection p = (ViewHolder.this).map.getProjection();
IGeoPoint igp = p.fromPixels(event.getX(), event.getY());
- (ViewHolder.this).binding.latEt.setText(String.format("%.06f", igp.getLatitude()));
- (ViewHolder.this).binding.lonEt.setText(String.format("%.06f", igp.getLongitude()));
+ (ViewHolder.this).binding.latEt.setText(String.format(Locale.ENGLISH, "%.06f", igp.getLatitude()));
+ (ViewHolder.this).binding.lonEt.setText(String.format(Locale.ENGLISH, "%.06f", igp.getLongitude()));
return false;
}
@@ -87,12 +121,19 @@ public class MapPickerActivity extends AppCompatActivity {
return false;
}
});
+ IMapController mapController = binding.map.getController();
+ mapController.setZoom(7.0f);
// Setup onClick
this.binding.latlonConfirmBtn.setOnClickListener(this);
}
+ public void centerMapOn(Double lat, Double lon ) {
+ IMapController mapController = binding.map.getController();
+ mapController.setCenter(new GeoPoint(lat, lon));
+ }
+
public View getRootView() {
return this.binding.root;
}
@@ -100,10 +141,43 @@ public class MapPickerActivity extends AppCompatActivity {
@Override
public void onClick(View view) {
if (view == this.binding.latlonConfirmBtn) {
- // TODO: Move map
- view.setVisibility(View.GONE);
+ this.coordsEditMode(false);
+ Double lat;
+ Double lon;
+ try {
+ lat = Double.parseDouble(this.binding.latEt.getText().toString());
+ lon = Double.parseDouble(this.binding.lonEt.getText().toString());
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Unable to parse coordinates: " + e.getLocalizedMessage());
+ Toast.makeText(MapPickerActivity.this, R.string.coordinates_parse_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ // Validate coordinates
+ if (lon <= -180 || lon >= 180 || lat <= -90 || lat >= 90) {
+ Toast.makeText(MapPickerActivity.this, R.string.coordinates_invalid_error, Toast.LENGTH_SHORT).show();
+ return;
+ }
+ // Move map to coordinates
+ this.centerMapOn(lat, lon);
}
}
+
+ /**
+ * Enters/exits coordinates edit mode.
+ * On exit, removes focus from the coordinates ET and hides the button
+ */
+ private void coordsEditMode(boolean active) {
+ this.coordsEditMode = active;
+ View btn = this.binding.latlonConfirmBtn;
+ if (active) {
+ btn.setVisibility(View.VISIBLE);
+ } else {
+ this.binding.latEt.clearFocus();
+ this.binding.lonEt.clearFocus();
+ btn.setVisibility(View.GONE);
+ }
+ }
+
}
}
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index daf21db..3d8cb8f 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -63,6 +63,10 @@
Geosegnalibro salvato
Geosegnalibro incompleto: nome e categoria sono obbligatori
+
+ Le coordinate dovrebbero essere nel formato xx.xxxxxx
+ Coordinate non valide
+
Versione
Stai usando la versione <strong>%1$s</strong>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3aa1db1..66e3c0e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -62,6 +62,10 @@
Geofavorite saved
Incomplete geofavorite: Name and category are mandatory
+
+ Coordinates should be in format xx.xxxxxx
+ Invalid coordinates
+
Version
You are currently using <strong>%1$s</strong>