ShowLocationActivity.java

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