ShowLocationActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.content.ActivityNotFoundException;
  4import android.content.ClipData;
  5import android.content.ClipboardManager;
  6import android.content.ComponentName;
  7import android.content.Intent;
  8import android.location.Location;
  9import android.location.LocationListener;
 10import android.net.Uri;
 11import android.os.Bundle;
 12import android.view.Menu;
 13import android.view.MenuItem;
 14import android.view.View;
 15import android.widget.Toast;
 16
 17import androidx.annotation.NonNull;
 18import androidx.databinding.DataBindingUtil;
 19
 20import org.osmdroid.util.GeoPoint;
 21
 22import java.util.HashMap;
 23import java.util.regex.Matcher;
 24import java.util.regex.Pattern;
 25
 26import eu.siacs.conversations.Config;
 27import eu.siacs.conversations.R;
 28import eu.siacs.conversations.databinding.ActivityShowLocationBinding;
 29import eu.siacs.conversations.ui.util.LocationHelper;
 30import eu.siacs.conversations.ui.util.UriHelper;
 31import eu.siacs.conversations.ui.widget.Marker;
 32import eu.siacs.conversations.ui.widget.MyLocation;
 33import eu.siacs.conversations.utils.LocationProvider;
 34
 35
 36public class ShowLocationActivity extends LocationActivity implements LocationListener {
 37
 38	private GeoPoint loc = LocationProvider.FALLBACK;
 39	private ActivityShowLocationBinding binding;
 40
 41
 42	private Uri createGeoUri() {
 43		return Uri.parse("geo:" + this.loc.getLatitude() + "," + this.loc.getLongitude());
 44	}
 45
 46	@Override
 47	protected void onCreate(final Bundle savedInstanceState) {
 48		super.onCreate(savedInstanceState);
 49
 50		this.binding = DataBindingUtil.setContentView(this,R.layout.activity_show_location);
 51		setSupportActionBar(binding.toolbar);
 52
 53		configureActionBar(getSupportActionBar());
 54		setupMapView(this.binding.map, this.loc);
 55
 56		this.binding.fab.setOnClickListener(view -> startNavigation());
 57
 58		final Intent intent = getIntent();
 59		if (intent != null) {
 60			final String action = intent.getAction();
 61			if (action == null) {
 62				return;
 63			}
 64			switch (action) {
 65				case "eu.siacs.conversations.location.show":
 66					if (intent.hasExtra("longitude") && intent.hasExtra("latitude")) {
 67						final double longitude = intent.getDoubleExtra("longitude", 0);
 68						final double latitude = intent.getDoubleExtra("latitude", 0);
 69						this.loc = new GeoPoint(latitude, longitude);
 70					}
 71					break;
 72				case Intent.ACTION_VIEW:
 73					final Uri geoUri = intent.getData();
 74
 75					// Attempt to set zoom level if the geo URI specifies it
 76					if (geoUri != null) {
 77						final HashMap<String, String> query = UriHelper.parseQueryString(geoUri.getQuery());
 78
 79						// Check for zoom level.
 80						final String z = query.get("z");
 81						if (z != null) {
 82							try {
 83								mapController.setZoom(Double.valueOf(z));
 84							} catch (final Exception ignored) {
 85							}
 86						}
 87
 88						// Check for the actual geo query.
 89						boolean posInQuery = false;
 90						final String q = query.get("q");
 91						if (q != null) {
 92							final Pattern latlng = Pattern.compile("/^([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?)(\\(.*\\))?/");
 93							final Matcher m = latlng.matcher(q);
 94							if (m.matches()) {
 95								try {
 96									this.loc = new GeoPoint(Double.valueOf(m.group(1)), Double.valueOf(m.group(3)));
 97									posInQuery = true;
 98								} catch (final Exception ignored) {
 99								}
100							}
101						}
102
103						final String schemeSpecificPart = geoUri.getSchemeSpecificPart();
104						if (schemeSpecificPart != null && !schemeSpecificPart.isEmpty()) {
105							try {
106								final GeoPoint latlong = LocationHelper.parseLatLong(schemeSpecificPart);
107								if (latlong != null && !posInQuery) {
108									this.loc = latlong;
109								}
110							} catch (final NumberFormatException ignored) {
111							}
112						}
113					}
114
115					break;
116			}
117			updateLocationMarkers();
118		}
119	}
120
121	@Override
122	protected void gotoLoc(final boolean setZoomLevel) {
123		if (this.loc != null && mapController != null) {
124			if (setZoomLevel) {
125				mapController.setZoom(Config.Map.FINAL_ZOOM_LEVEL);
126			}
127			mapController.animateTo(new GeoPoint(this.loc));
128		}
129	}
130
131	@Override
132	public void onRequestPermissionsResult(final int requestCode,
133										   @NonNull final String[] permissions,
134										   @NonNull final int[] grantResults) {
135		super.onRequestPermissionsResult(requestCode, permissions, grantResults);
136		updateUi();
137	}
138
139	@Override
140	protected void setMyLoc(final Location location) {
141		this.myLoc = location;
142	}
143
144	@Override
145	public boolean onCreateOptionsMenu(final Menu menu) {
146		// Inflate the menu; this adds items to the action bar if it is present.
147		getMenuInflater().inflate(R.menu.menu_show_location, menu);
148		updateUi();
149		return true;
150	}
151
152	@Override
153	protected void updateLocationMarkers() {
154		super.updateLocationMarkers();
155		if (this.myLoc != null) {
156			this.binding.map.getOverlays().add(new MyLocation(this, null, this.myLoc));
157		}
158		this.binding.map.getOverlays().add(new Marker(this.marker_icon, this.loc));
159	}
160
161	@Override
162	protected void onPause() {
163		super.onPause();
164	}
165
166	@Override
167	public boolean onOptionsItemSelected(final MenuItem item) {
168		switch (item.getItemId()) {
169			case R.id.action_copy_location:
170				final ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
171				if (clipboard != null) {
172					final ClipData clip = ClipData.newPlainText("location", createGeoUri().toString());
173					clipboard.setPrimaryClip(clip);
174					Toast.makeText(this,R.string.url_copied_to_clipboard,Toast.LENGTH_SHORT).show();
175				}
176				return true;
177			case R.id.action_share_location:
178				final Intent shareIntent = new Intent();
179				shareIntent.setAction(Intent.ACTION_SEND);
180				shareIntent.putExtra(Intent.EXTRA_TEXT, createGeoUri().toString());
181				shareIntent.setType("text/plain");
182				try {
183					startActivity(Intent.createChooser(shareIntent, getText(R.string.share_with)));
184				} catch (final ActivityNotFoundException e) {
185					//This should happen only on faulty androids because normally chooser is always available
186					Toast.makeText(this, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show();
187				}
188				return true;
189		}
190		return super.onOptionsItemSelected(item);
191	}
192
193	private void startNavigation() {
194		startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(
195				"google.navigation:q=" +
196						this.loc.getLatitude() + "," + this.loc.getLongitude()
197		)));
198	}
199
200	@Override
201	protected void updateUi() {
202		final Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:q=0,0"));
203		final ComponentName component = i.resolveActivity(getPackageManager());
204		this.binding.fab.setVisibility(component == null ? View.GONE : View.VISIBLE);
205	}
206
207	@Override
208	public void onLocationChanged(final Location location) {
209		if (LocationHelper.isBetterLocation(location, this.myLoc)) {
210			this.myLoc = location;
211			updateLocationMarkers();
212		}
213	}
214
215	@Override
216	public void onStatusChanged(final String provider, final int status, final Bundle extras) {
217
218	}
219
220	@Override
221	public void onProviderEnabled(final String provider) {
222
223	}
224
225	@Override
226	public void onProviderDisabled(final String provider) {
227
228	}
229}