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}