use resolveActivityInfo to display nagivate to button

Daniel Gultsch created

resolveActivity on the other hand only finds apps that are category_default

fixes #4375

Change summary

src/main/AndroidManifest.xml                                      |   3 
src/main/java/eu/siacs/conversations/ui/ShowLocationActivity.java | 403 
2 files changed, 213 insertions(+), 193 deletions(-)

Detailed changes

src/main/AndroidManifest.xml 🔗

@@ -64,6 +64,9 @@
             <action android:name="android.intent.action.VIEW" />
             <data android:mimeType="resource/folder" />
         </intent>
+        <intent>
+            <action android:name="android.intent.action.VIEW" />
+        </intent>
     </queries>
 
 

src/main/java/eu/siacs/conversations/ui/ShowLocationActivity.java 🔗

@@ -3,8 +3,8 @@ package eu.siacs.conversations.ui;
 import android.content.ActivityNotFoundException;
 import android.content.ClipData;
 import android.content.ClipboardManager;
-import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.location.Location;
 import android.location.LocationListener;
 import android.net.Uri;
@@ -17,6 +17,7 @@ import android.widget.Toast;
 import androidx.annotation.NonNull;
 import androidx.databinding.DataBindingUtil;
 
+import org.jetbrains.annotations.NotNull;
 import org.osmdroid.util.GeoPoint;
 
 import java.util.HashMap;
@@ -32,198 +33,214 @@ import eu.siacs.conversations.ui.widget.Marker;
 import eu.siacs.conversations.ui.widget.MyLocation;
 import eu.siacs.conversations.utils.LocationProvider;
 
-
 public class ShowLocationActivity extends LocationActivity implements LocationListener {
 
-	private GeoPoint loc = LocationProvider.FALLBACK;
-	private ActivityShowLocationBinding binding;
-
-
-	private Uri createGeoUri() {
-		return Uri.parse("geo:" + this.loc.getLatitude() + "," + this.loc.getLongitude());
-	}
-
-	@Override
-	protected void onCreate(final Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-
-		this.binding = DataBindingUtil.setContentView(this,R.layout.activity_show_location);
-		setSupportActionBar(binding.toolbar);
-
-		configureActionBar(getSupportActionBar());
-		setupMapView(this.binding.map, this.loc);
-
-		this.binding.fab.setOnClickListener(view -> startNavigation());
-
-		final Intent intent = getIntent();
-		if (intent != null) {
-			final String action = intent.getAction();
-			if (action == null) {
-				return;
-			}
-			switch (action) {
-				case "eu.siacs.conversations.location.show":
-					if (intent.hasExtra("longitude") && intent.hasExtra("latitude")) {
-						final double longitude = intent.getDoubleExtra("longitude", 0);
-						final double latitude = intent.getDoubleExtra("latitude", 0);
-						this.loc = new GeoPoint(latitude, longitude);
-					}
-					break;
-				case Intent.ACTION_VIEW:
-					final Uri geoUri = intent.getData();
-
-					// Attempt to set zoom level if the geo URI specifies it
-					if (geoUri != null) {
-						final HashMap<String, String> query = UriHelper.parseQueryString(geoUri.getQuery());
-
-						// Check for zoom level.
-						final String z = query.get("z");
-						if (z != null) {
-							try {
-								mapController.setZoom(Double.valueOf(z));
-							} catch (final Exception ignored) {
-							}
-						}
-
-						// Check for the actual geo query.
-						boolean posInQuery = false;
-						final String q = query.get("q");
-						if (q != null) {
-							final Pattern latlng = Pattern.compile("/^([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?)(\\(.*\\))?/");
-							final Matcher m = latlng.matcher(q);
-							if (m.matches()) {
-								try {
-									this.loc = new GeoPoint(Double.valueOf(m.group(1)), Double.valueOf(m.group(3)));
-									posInQuery = true;
-								} catch (final Exception ignored) {
-								}
-							}
-						}
-
-						final String schemeSpecificPart = geoUri.getSchemeSpecificPart();
-						if (schemeSpecificPart != null && !schemeSpecificPart.isEmpty()) {
-							try {
-								final GeoPoint latlong = LocationHelper.parseLatLong(schemeSpecificPart);
-								if (latlong != null && !posInQuery) {
-									this.loc = latlong;
-								}
-							} catch (final NumberFormatException ignored) {
-							}
-						}
-					}
-
-					break;
-			}
-			updateLocationMarkers();
-		}
-	}
-
-	@Override
-	protected void gotoLoc(final boolean setZoomLevel) {
-		if (this.loc != null && mapController != null) {
-			if (setZoomLevel) {
-				mapController.setZoom(Config.Map.FINAL_ZOOM_LEVEL);
-			}
-			mapController.animateTo(new GeoPoint(this.loc));
-		}
-	}
-
-	@Override
-	public void onRequestPermissionsResult(final int requestCode,
-										   @NonNull final String[] permissions,
-										   @NonNull final int[] grantResults) {
-		super.onRequestPermissionsResult(requestCode, permissions, grantResults);
-		updateUi();
-	}
-
-	@Override
-	protected void setMyLoc(final Location location) {
-		this.myLoc = location;
-	}
-
-	@Override
-	public boolean onCreateOptionsMenu(final Menu menu) {
-		// Inflate the menu; this adds items to the action bar if it is present.
-		getMenuInflater().inflate(R.menu.menu_show_location, menu);
-		updateUi();
-		return true;
-	}
-
-	@Override
-	protected void updateLocationMarkers() {
-		super.updateLocationMarkers();
-		if (this.myLoc != null) {
-			this.binding.map.getOverlays().add(new MyLocation(this, null, this.myLoc));
-		}
-		this.binding.map.getOverlays().add(new Marker(this.marker_icon, this.loc));
-	}
-
-	@Override
-	protected void onPause() {
-		super.onPause();
-	}
-
-	@Override
-	public boolean onOptionsItemSelected(final MenuItem item) {
-		switch (item.getItemId()) {
-			case R.id.action_copy_location:
-				final ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
-				if (clipboard != null) {
-					final ClipData clip = ClipData.newPlainText("location", createGeoUri().toString());
-					clipboard.setPrimaryClip(clip);
-					Toast.makeText(this,R.string.url_copied_to_clipboard,Toast.LENGTH_SHORT).show();
-				}
-				return true;
-			case R.id.action_share_location:
-				final Intent shareIntent = new Intent();
-				shareIntent.setAction(Intent.ACTION_SEND);
-				shareIntent.putExtra(Intent.EXTRA_TEXT, createGeoUri().toString());
-				shareIntent.setType("text/plain");
-				try {
-					startActivity(Intent.createChooser(shareIntent, getText(R.string.share_with)));
-				} catch (final ActivityNotFoundException e) {
-					//This should happen only on faulty androids because normally chooser is always available
-					Toast.makeText(this, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show();
-				}
-				return true;
-		}
-		return super.onOptionsItemSelected(item);
-	}
-
-	private void startNavigation() {
-		startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(
-				"google.navigation:q=" +
-						this.loc.getLatitude() + "," + this.loc.getLongitude()
-		)));
-	}
-
-	@Override
-	protected void updateUi() {
-		final Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:q=0,0"));
-		final ComponentName component = i.resolveActivity(getPackageManager());
-		this.binding.fab.setVisibility(component == null ? View.GONE : View.VISIBLE);
-	}
-
-	@Override
-	public void onLocationChanged(final Location location) {
-		if (LocationHelper.isBetterLocation(location, this.myLoc)) {
-			this.myLoc = location;
-			updateLocationMarkers();
-		}
-	}
-
-	@Override
-	public void onStatusChanged(final String provider, final int status, final Bundle extras) {
-
-	}
-
-	@Override
-	public void onProviderEnabled(final String provider) {
-
-	}
-
-	@Override
-	public void onProviderDisabled(final String provider) {
-
-	}
+    private GeoPoint loc = LocationProvider.FALLBACK;
+    private ActivityShowLocationBinding binding;
+
+    private Uri createGeoUri() {
+        return Uri.parse("geo:" + this.loc.getLatitude() + "," + this.loc.getLongitude());
+    }
+
+    @Override
+    protected void onCreate(final Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        this.binding = DataBindingUtil.setContentView(this, R.layout.activity_show_location);
+        setSupportActionBar(binding.toolbar);
+
+        configureActionBar(getSupportActionBar());
+        setupMapView(this.binding.map, this.loc);
+
+        this.binding.fab.setOnClickListener(view -> startNavigation());
+
+        final Intent intent = getIntent();
+        if (intent != null) {
+            final String action = intent.getAction();
+            if (action == null) {
+                return;
+            }
+            switch (action) {
+                case "eu.siacs.conversations.location.show":
+                    if (intent.hasExtra("longitude") && intent.hasExtra("latitude")) {
+                        final double longitude = intent.getDoubleExtra("longitude", 0);
+                        final double latitude = intent.getDoubleExtra("latitude", 0);
+                        this.loc = new GeoPoint(latitude, longitude);
+                    }
+                    break;
+                case Intent.ACTION_VIEW:
+                    final Uri geoUri = intent.getData();
+
+                    // Attempt to set zoom level if the geo URI specifies it
+                    if (geoUri != null) {
+                        final HashMap<String, String> query =
+                                UriHelper.parseQueryString(geoUri.getQuery());
+
+                        // Check for zoom level.
+                        final String z = query.get("z");
+                        if (z != null) {
+                            try {
+                                mapController.setZoom(Double.valueOf(z));
+                            } catch (final Exception ignored) {
+                            }
+                        }
+
+                        // Check for the actual geo query.
+                        boolean posInQuery = false;
+                        final String q = query.get("q");
+                        if (q != null) {
+                            final Pattern latlng =
+                                    Pattern.compile(
+                                            "/^([-+]?[0-9]+(\\.[0-9]+)?),([-+]?[0-9]+(\\.[0-9]+)?)(\\(.*\\))?/");
+                            final Matcher m = latlng.matcher(q);
+                            if (m.matches()) {
+                                try {
+                                    this.loc =
+                                            new GeoPoint(
+                                                    Double.valueOf(m.group(1)),
+                                                    Double.valueOf(m.group(3)));
+                                    posInQuery = true;
+                                } catch (final Exception ignored) {
+                                }
+                            }
+                        }
+
+                        final String schemeSpecificPart = geoUri.getSchemeSpecificPart();
+                        if (schemeSpecificPart != null && !schemeSpecificPart.isEmpty()) {
+                            try {
+                                final GeoPoint latlong =
+                                        LocationHelper.parseLatLong(schemeSpecificPart);
+                                if (latlong != null && !posInQuery) {
+                                    this.loc = latlong;
+                                }
+                            } catch (final NumberFormatException ignored) {
+                            }
+                        }
+                    }
+
+                    break;
+            }
+            updateLocationMarkers();
+        }
+    }
+
+    @Override
+    protected void gotoLoc(final boolean setZoomLevel) {
+        if (this.loc != null && mapController != null) {
+            if (setZoomLevel) {
+                mapController.setZoom(Config.Map.FINAL_ZOOM_LEVEL);
+            }
+            mapController.animateTo(new GeoPoint(this.loc));
+        }
+    }
+
+    @Override
+    public void onRequestPermissionsResult(
+            final int requestCode,
+            @NonNull final String[] permissions,
+            @NonNull final int[] grantResults) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+        updateUi();
+    }
+
+    @Override
+    protected void setMyLoc(final Location location) {
+        this.myLoc = location;
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(@NotNull final Menu menu) {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.menu_show_location, menu);
+        updateUi();
+        return true;
+    }
+
+    @Override
+    protected void updateLocationMarkers() {
+        super.updateLocationMarkers();
+        if (this.myLoc != null) {
+            this.binding.map.getOverlays().add(new MyLocation(this, null, this.myLoc));
+        }
+        this.binding.map.getOverlays().add(new Marker(this.marker_icon, this.loc));
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.action_copy_location:
+                final ClipboardManager clipboard =
+                        (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+                if (clipboard != null) {
+                    final ClipData clip =
+                            ClipData.newPlainText("location", createGeoUri().toString());
+                    clipboard.setPrimaryClip(clip);
+                    Toast.makeText(this, R.string.url_copied_to_clipboard, Toast.LENGTH_SHORT)
+                            .show();
+                }
+                return true;
+            case R.id.action_share_location:
+                final Intent shareIntent = new Intent();
+                shareIntent.setAction(Intent.ACTION_SEND);
+                shareIntent.putExtra(Intent.EXTRA_TEXT, createGeoUri().toString());
+                shareIntent.setType("text/plain");
+                try {
+                    startActivity(Intent.createChooser(shareIntent, getText(R.string.share_with)));
+                } catch (final ActivityNotFoundException e) {
+                    // This should happen only on faulty androids because normally chooser is always
+                    // available
+                    Toast.makeText(
+                                    this,
+                                    R.string.no_application_found_to_open_file,
+                                    Toast.LENGTH_SHORT)
+                            .show();
+                }
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void startNavigation() {
+        final Intent intent = getStartNavigationIntent();
+        startActivity(intent);
+    }
+
+    private Intent getStartNavigationIntent() {
+        return new Intent(
+                Intent.ACTION_VIEW,
+                Uri.parse(
+                        "google.navigation:q="
+                                + this.loc.getLatitude()
+                                + ","
+                                + this.loc.getLongitude()));
+    }
+
+    @Override
+    protected void updateUi() {
+        final Intent intent = getStartNavigationIntent();
+        final ActivityInfo activityInfo = intent.resolveActivityInfo(getPackageManager(), 0);
+        this.binding.fab.setVisibility(activityInfo == null ? View.GONE : View.VISIBLE);
+    }
+
+    @Override
+    public void onLocationChanged(@NotNull final Location location) {
+        if (LocationHelper.isBetterLocation(location, this.myLoc)) {
+            this.myLoc = location;
+            updateLocationMarkers();
+        }
+    }
+
+    @Override
+    public void onStatusChanged(final String provider, final int status, final Bundle extras) {}
+
+    @Override
+    public void onProviderEnabled(@NotNull final String provider) {}
+
+    @Override
+    public void onProviderDisabled(@NotNull final String provider) {}
 }