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