Since Waze and Google Maps have different URI formats, I need to create two separate intents in order to make sure that apps will navigate user to the correct location.
The main problem: I don't want to make user select navigation app every time. I want it to behave like this: if user has default navigation app set - use it without asking.
How to have two URIs for separate apps but still have the same interface just like when starting intent with ACTION_VIEW parameter?
This is my code that I am working with. Currently navigation works fine, but user is being asked every time to select navigation app:
if (!StringUtils.isEmpty(address)) {
String q = address + "&mode=d&navigate=yes&geo=" + address + "&ll=" + address;
String urlWaze = "https://waze.com/ul?q=" + q;
Intent wazeIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlWaze));
String urlGoogle = "google.navigation:q=" + q;
Intent googleMapsIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlGoogle));
googleMapsIntent.setPackage("com.google.android.apps.maps");
String title = getActivity().getResources().getString(R.string.choose_navigation_app);
Intent chooserIntent = Intent.createChooser(wazeIntent, title);
Intent[] arr = new Intent[1];
arr[0] = googleMapsIntent;
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arr);
getContext().startActivity(chooserIntent);
} else {
Toast.makeText(getContext(), getString(R.string.waypoint_not_have_geolocation), Toast.LENGTH_SHORT).show();
}
As it turns out Waze and Google Maps have very different URIs and in ordet to resolve situation that I descibed in my question, the only solution was to create separate user-settings in my application.
Related
In my app I have a button, which opens a Google map with sent coordinates.
final ImageView view = findViewById(R.id.navigate);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse("http://maps.google.com/maps?daddr="+gps1+","+gps2));
startActivity(intent);
}
});
This is working fine, but I want to offer to the user all navigation apps that he has in his device after button click.
So not to automatically open Google Maps, but let the user choose which app to use.
I found this solution, but this is only for Google maps and Waze. As I can't know which and how many navigation apps the user has on his device, I can't hardcode all existing navigation apps.
String url = "waze://?ll=" + latitude + ", " + longitude + "&navigate=yes";
Intent intentWaze.setPackage("com.waze");
Intent intentWaze = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
String uriGoogle = "google.navigation:q=" + latitude + "," + longitude;
Intent intentGoogleNav.setPackage("com.google.android.apps.maps");
Intent intentGoogleNav = new Intent(Intent.ACTION_VIEW, Uri.parse(uriGoogle));
String title = context.getString(R.string.title);
Intent chooserIntent = Intent.createChooser(intentGoogleNav, title);
Intent[] arr = new Intent[1];
arr[0] = intentWaze;
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arr);
context.startActivity(chooserIntent);
So is there any solution, which can offer all navigation apps that the user has?
For example for sharing function it works like this:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT,
infox);
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, getString(R.string.share)));
This will show many apps with sharing possibility. How to do the same for apps with map?
EDIT: I added this to google and waze code, so now I have listed in chooser: Google map, Waze and an unknown android icon, when I click it, it shows all navigation apps on my device! However only if I click that unnamed icon and it only opens those maps without navigation.
String urlx = "geo:" + gps1 + ", " + gps2;
Intent intentOther = new Intent(Intent.ACTION_VIEW, Uri.parse(urlx));
I need to show all those app immediately after button click.
This is a year later and I was actually trying to use the solution above and I encountered some issues. Such as two Waze apps in the selector
I have just rewritten the solution in kotlin and what actually worked for me
val url = "waze://?ll=" + latitude + ", " + longitude + "&navigate=yes"
var intentWaze = Intent(Intent.ACTION_VIEW, Uri.parse(url)).setPackage("com.waze")
val uriGoogle = "google.navigation:q=" + latitude + "," + longitude
var intentGoogleNav = Intent(Intent.ACTION_VIEW, Uri.parse(uriGoogle)).setPackage("com.google.android.apps.maps")
val title: String = context.getString(R.string.app_name)
val chooserIntent = Intent.createChooser(intentGoogleNav, title)
val arr = arrayOfNulls<Intent>(1)
arr[0] = intentWaze
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arr)
context.startActivity(chooserIntent)
So as I found out, there is no universal way to force navigation routes on all navigation apps in intent chooser, so I solved it like I mentioned above, just I added a parameter to geo like this:
geo:0,0?q=latitude,longitude
and add to manifest:
<data android:scheme="geo"/>
and this shows all navigation apps on my device in the chooser, and mostly shows the point on the map with the coordinates, but some apps like Waze also calculates the route immediately, so I think this is a good solution.
I need to send an intent to Waze app in Android to navigate to a UK postcode like "N3 2AL"
I did it before with google map using this piece of code and works fine:
String postcode = "N3 2AL";
postcode = postcode.trim().replaceAll(" ", "+");
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:q=" + postcode));
startActivity(i);
But I can not handle it using Waze:
postcode = postcode.trim().replaceAll(" ", "%20");
Intent i = new Intent(Intent.ACTION_VIEW,
Uri.parse("waze://?q=" + postcode + "&navigate=yes"));
startActivity(i);
I tried using complete link too:
https://waze.com/ul?q=N3%202AL
I assumed waze can not handle UK postcodes, but when I search directly in waze app, it can find the postcode and shows it correctly. The problem is with api.
EDIT: Currently I have to reverse the postcode using postcodes.io and use Waze like this:
waze://ll=lat,long&navigate=yes
It's working but with 1 more server call.
I would like to open the Waze app from a web browser but the links I have in my db are in this format:
http://waze.to/li/hsv9hc540y
https://waze.to/li/hsv8v8wv81
When I click on these links from my mobile web browser they open the app but the navigation doesn't begin, it's only opens the app and that's it.
After reading the updated waze api I haven't found a way to navigate using the encrypted string hsv9hc540y only by latitude and longitude which I don't have.
How can I convert those waze.to links to the new deep links api using the encrypted string I have so it will open the app and init navigation?
Your deep links are not correct. To make them work, they need to look like this:
https://waze.com/ul/hsv9hc540y
https://waze.com/ul/hsv8v8wv81
For more info, check this link:
https://developers.google.com/waze/deeplinks/
try {
// Launch Waze
String mapRequest = "https://waze.com/ul?q=" + latLng.latitude + "," + latLng.longitude + "&navigate=yes&zoom=17";
Uri gmmIntentUri = Uri.parse(mapRequest);
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.waze");
startActivity(mapIntent);
} catch (ActivityNotFoundException e)
{
// If Waze is not installed, open it in Google Play
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.waze"));
startActivity(intent);
}
There are a few similar posts but I couldn't find an exact one. basically, I want to open both Google maps and Waze with the same intent. At first I tried this:
final String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(intent);
Waze navigated directly to the right location and Google maps opened the right place. then I realized that Google maps doesn't put a pin on the location so it's hard for the user to know where it is exactly. So I looked around and realized that Google maps requires the "?q=..(label)" for that... I changed the uri construction to:
final String uri = String.format(Locale.ENGLISH, "geo:%f,%f?q=%f,%f (%s)", latitude, longitude, latitude, longitude, name);
But then Waze did 2 things: navigated to the right place AND run a search on the label. This required the user to click the back button to close the search results screen and remain with the navigation to the right place.
I looked everywhere for an answer but failed to find a solution that will achieve both.
At first I thought that it's not possible and Waze has a bug... but then I noticed that Facebook messenger is doing exactly what I want. when clicking on a message with a location it will open both apps: Google maps will have a pin (with a label) and Waze will navigate straight to that location without running a search.
Few questions about the above:
1. (Of course) How can I achieve that?
2. How can I know how the Facebook messenger's intent being built? (Can I catch it in anyway)
3. What's the reason behind having the label only with the "?q=.."?
Thanks
Never mind. I was able to intercept the Facebook messenger with the below app and figured that the URI should be as follows:
String.format(Locale.ENGLISH, "geo:0,0?q=") + android.net.Uri.encode(String.format("%s#%f,%f", label, latitude, longitude), "UTF-8");
The app:
https://play.google.com/store/apps/details?id=uk.co.ashtonbrsc.android.intentintercept&feature=search_result#?t=W251bGwsMSwyLDEsInVrLmNvLmFzaHRvbmJyc2MuYW5kcm9pZC5pbnRlbnRpbnRlcmNlcHQiXQ..
Thanks
Following Nimrod's tip I've installed the app and intercepted the intent from whatsapp's location feature. Here's the full Intent tested on maps and waze:
String uri = "http://maps.google.com/maps?q=loc:"+latitude+","+longitude+" ("+label+")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
intent.setFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
intent.setData(Uri.parse(uri));
startActivity(intent);
My final solution for opening both Waze & GoogleMap applications to get direction ( works like a charm ) :
String uri = "";
Intent intent;
try {
uri = String.format(Locale.ENGLISH,"geo:" + location.getLat() + "," +location.getLng() + "?q=" + location.getLat()+","+location.getLng()+" ("+location.getName()+")");
intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (ActivityNotFoundException ex) {
try {
Intent unrestrictedIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(unrestrictedIntent);
} catch (ActivityNotFoundException innerEx) {
getSnackbar(getResources().getString(R.string.map_install_application), Snackbar.LENGTH_LONG).show();
}
}
I had the same problem - wanted the navigation app (whatever it is) to show a pin (preferably with a custom label) and be ready to navigate the user there. However, having a label in the query resulted in some apps running a search or (worse) assuming the closest address match to the label and showing that as the destination (ignoring the coordinates). So, to achieve a reliable behaviour I had to forget having a named label and ended up with the following:
final String geoIntentData = "geo:" + latitude + "," + longitude + "?q=" + latitude + "," + longitude;
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(geoIntentData));
So far it works in all apps I tested (Google Maps, Waze, Sygic, Moovit and even Komoot and Windy Maps). Please let me know if you try this solution and it doesn't work in another app!
I want to start a new hangout conversation with given people, but I can't find any code for it. Is there any easy solution to do this?
I tryed to make skype call, and it worked easyly with an intent.
Here is the skype code:
Intent sky = new Intent("android.intent.action.VIEW");
sky.setData(Uri.parse("skype:" + nickname));
startActivity(sky);
I want something similar to this.
(Or with skype how can I make a conference call? )
There is currently no way to create a Google+ hangout on an android device using an intent or any other API.
This would be a pretty cool feature, though. If you request it, they might add it.
I think I found the solution, it's quite simple, here is the code:
Intent sky = new Intent("android.intent.action.VIEW", Uri.parse("https://talkgadget.google.com/hangouts/extras/talk.google.com/myhangout"));
startActivity(sky);
You just need to give the url of the hangout, but unfortunately google suspended the named hangots, so this url every time changes. :(
public static void sendHangout(Context ctx, String message, String urlShare, String imgPath){
Intent hangouts = new Intent(Intent.ACTION_SEND);
if(!Utilities.isNullorEmpty(imgPath)){
String file = (String)imgPath.subSequence(0, imgPath.lastIndexOf("/") + 1) + message.replace(" ", "").replace(":", "").replace(".", "")
.replace("/", "") + ".jpeg";
Utilities.copyFile(imgPath, file);
hangouts.setType("image/*");
hangouts.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///" + file));
}
hangouts.setPackage("com.google.android.talk");
hangouts.setType("text/plain");
hangouts.putExtra(Intent.EXTRA_TEXT, message + ": \n" + urlShare);
ctx.startActivity(Intent.createChooser(hangouts, "Hangouts is not installed."));
}
I hope help you.
Intent i = context.getPackageManager().getLaunchIntentForPackage("com.google.android.talk");
context.startActivity(i);