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}